Skocz do zawartości

yoyo1


yoyoazs1

Pomocna odpowiedź

Nie dołączaj tylko wstaw kod. Ale najpierw go uporządkuj i wywal zbędne rzeczy by był dla nas łatwy do analizy.

Tak na szybko używasz nowego ISR(), ale starego wektora SIG_OVERFLOW0.

ISR(SIG_OVERFLOW0) 

Tak być nie powinno. Nie oznacza to że to jest przyczyną problemów.

Link do komentarza
Share on other sites


#include <avr/io.h>
#include <avr/interrupt.h> 
#include <util/delay.h> 
#include <stdio.h>
#include <math.h> 
#include <inttypes.h>
#include <avr/wdt.h>    //watchdog

#define F_CPU 8000000UL /* 8 MHz */

//czestotliwosc kwarca i czas trwania 1 cyklu
#define clk_freq 		8000000UL
#define clk_period_us 	1*200*1000000UL/clk_freq

volatile int	licznik;
volatile double	czas;
volatile double	distance;
volatile int	zwrot;
volatile char 	triggered;
volatile int	rejestr;

//--------------------------------------------------------------------------------//


//--------------------------------------------------------------------------------//
//przerwanie 
ISR(INT2_vect) 
{
zwrot++;
TCCR0 |= (0<<CS02) | (0<<CS01) | (0<<CS00) | (0<<WGM01) | (0<<WGM00);
TIMSK |= (0<<TOIE0);
rejestr = TCNT0;

czas = ((int)rejestr + 255 * ((int)licznik));
distance =(((double)czas)/(29)*clk_period_us)/2;

licznik = 0;
TCNT0 = 0;
czas = 0;
triggered = 0;
}

//--------------------------------------------------------------------------------//


//--------------------------------------------------------------------------------//
ISR(SIG_OVERFLOW0) //początek funkcji obsługi przerwania
{
licznik++;
}
//--------------------------------------------------------------------------------//


//--------------------------------------------------------------------------------//
//ustawienia portów
void init_ports(void)
{	
DDRD 	|= _BV(PD7) | _BV(PD5) | _BV(PD4);		 //ustawienie pinów jako wyjść 
PORTD 	|= _BV(PD5) | _BV(PD4);				//stan wysoki
DDRD 	|= _BV(PD0);		//input 1 wyjście
DDRC 	|= _BV(PC1);		//input 3 wyjście
DDRD 	|= _BV(PD1);		//input 2 wyjście
DDRC 	|= _BV(PC0);		//input 4 wyjście
DDRB 	&= ~_BV(PB2);	 	//ustawienie pinu jako wejścia
PORTB 	|= _BV(PB2);	  	//załączenie rezystora podciągającego
}
//--------------------------------------------------------------------------------//


//--------------------------------------------------------------------------------//
void trigger(void)
{
PORTD = _BV(PD7);		//
_delay_us(10);          //czas trwania impulsu TRIG 10us
PORTD = ~_BV(PD7);		//
triggered = 1; 
}
//--------------------------------------------------------------------------------//


//--------------------------------------------------------------------------------//
void pomiar(void)
{
trigger ();
TCCR0 |= (0<<CS02) | (0<<CS01) | (1<<CS00) | (0<<WGM01) | (0<<WGM00);
TIMSK |= (1<<TOIE0);
}
//--------------------------------------------------------------------------------//

//program główny
int main (void)
{ 
init_ports();

MCUCSR |= _BV(ISC2); 
GICR   |= _BV(INT2);	 


sei ();


while (1)
{
	PORTD |= _BV(PD1);		//input 1 stan wysoki do przodu prawa strona 
	PORTD &= ~_BV(PD0);		//input 2 stan niski do przodu prawa strona
	PORTC |= _BV(PC0);		//input 1 stan wysoki do przodu prawa strona 
	PORTC &= ~_BV(PC1);		//input 2 stan niski do przodu prawa strona

	pomiar ();

	if (triggered == 0)
	{
	if (distance <= 50)
	{ 
		PORTD &= ~_BV(PD1);		//input 2 stan niski do przodu prawa strona
		PORTC &= ~_BV(PC0);		//input 2 stan niski do przodu prawa strona
		_delay_ms(1000);
	}
	}
}
return (0);
}

A oto i kod 🙂

Link do komentarza
Share on other sites

0. Jaki to mikrokontroler?

1. Nie wyskakuje Ci taki warning:

c:/winavr-20100110/lib/gcc/../../avr/include/util/delay.h:85:3: warning: #warning "F_CPU not defined for "

../PROBY.c:11:1: warning: "F_CPU" redefined

Jeżeli definiujesz F_CPU w kodzie, to MUSISZ to zrobić przed inkludowaniem delay.h. Nie wiem w czym piszesz, ale jeżeli w AVR Studio to zegar zdefiniuj w opcjach projektu a nie w kodzie.

2. Nie definiuj dodatkowej etykiety:

#define clk_freq  8000000UL 

Wykorzystaj F_CPU - nie masz wtedy problemu ewentualnej pomyłki przy zmianach częstotliwości zegara.

3. Już pisałem ale napiszę jeszcze raz bo w załączonym kodzie nie poprawiłeś:

używasz nowego ISR(), ale starego wektora SIG_OVERFLOW0 patrz: http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html

4. mało istotny drobiazg - to jest zbędne:

return (0); 

5. inne warningi?

6. Wprowadź zmiany i sprawdź, a gdyby nadal nie działał to opisz dokładniej co stwierdzasz i jakie są problemy.

Link do komentarza
Share on other sites

Jedyny warning to:

 przerwania.c:100: warning: large integer implicitly truncated to unsigned type 

.

Program piszę w WinAVR, problem polega na tym, że gdy zadam mu jakąś odległość, i porównam ją do otrzymanej z obliczeń to gdzie bym nie ruszył ręką, atmega i tak zareaguje zmieniając stan na wyjściu. Wydaje mi się, że procedura odmierzania czasu jest poprawna oraz obliczanie odległości także, ale warunek ze sprawdzaniem odległości nie działa poprawnie. Jedyną różnicą w jakiej odległości ustawię przedmiot jest czas odpowiedzi mikrokontrolera, im bliżej tym szybsza odpowiedź, ale to wydaje się być logiczne.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Odpowiadając nie napisałeś, czy naniosłeś poprawki które opisałem powyżej?

Teraz nie wiemy, czy ten opis jest po poprawkach czy przed.

Jedyny warning to:
 przerwania.c:100: warning: large integer implicitly truncated to unsigned type 

.

czyli która linia kodu, bo po numeracji nie znajdę?

Link do komentarza
Share on other sites

PORTD = _BV(PD7);        //
_delay_us(10);          //czas trwania impulsu TRIG 10us
PORTD = ~_BV(PD7);        //
triggered = 1; 

Jeśli chcesz ustawić stan na odpowiednim pinie, to chyba powinno być:

PORTD |= _BV(PD7);        //
_delay_us(10);          //czas trwania impulsu TRIG 10us
PORTD &=~ _BV(PD7);        //
triggered = 1; 
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.