Skocz do zawartości
Zaloguj się, aby obserwować  
komabra

Timer CTC + przerwanie

Pomocna odpowiedź

Cześć. Zwracam się z problemem w miarę prostym i myślę, że bardzo szybko dojdziemy do wniosków.

Otóż, robię prosty program na ATMEGA16, który ma zapalać po kolei diody. Kolejna dioda ma się zapalać wraz z wystąpieniem przerwania od timera w trybie CTC. Diód jest 3.

Kod programu :

#include<avr/io.h>
#include<util/delay.h>
#include<avr/interrupt.h>


int main(void)
{
//ustawienie wejsc/wyjsc
DDRB |= (1<<PB0)|(1<<PB1)|(1<<PB2);
PORTB = 0x01;                        /// diody jako wyjscia, pierwsza od razu zapalona



////inicjalizacja timera w trybie CTC
	TCCR0 |= (1<<WGM01);   // tryb CTC
	TCCR0 |= (1<<CS00) | (1<<CS01) ; // preskaler 64
	OCR0 = 80;
	TIMSK |= (1<<OCIE0);				// zezwolenie na przerwanie CompareMatch

	sei();                              //zezwolenie na prerwania globalne


	while(1)
	{
	}
}

ISR(TIMER0_COMP_vect)
{

	PORTB *=2;       //załącza się kolejna dioda

		if(PORTB>4)   // jesli dioda 3 zapalona to po niej zapalamy pierwszą
		{
			PORTB = 0x01;
		}
}

Diody nie reagują i w sumie nie mam pojęcia gdzie jest błąd..

Udostępnij ten post


Link to post
Share on other sites

Witaj, wydaje mi sie, ze program jest ok, natomiast samo przerwanie wywoluje sie za szybko. Wedlug moich obliczen zakladajac czestotliwosc taktowanai procesora rowna 1MHz, przerwanie wywoluje sie co ~195Hz(1MHz/64/80)zatem ludzkie oko ze wzgledu na swoja zawila budowe, (konkretnie chodzi o bezwladnosc), nie bedzie w stanie dostrzec tak szybkich zmian. Choc z drugiej strony powinny swiecic sie wszystkie z tego powowdu, a nie jak piszesz zadne.

Slowa dioda, nie odmienia sie na "di"u"d", tylko diod 😉

Udostępnij ten post


Link to post
Share on other sites

Jakoś dziwnie troche wygląda ten program, na sam początek zaświeć poprostu ledy bez żadnych timerów itd na prostych delayach zeby sprawdzić czy cała płytka działa poprawnie.

Jak działa wszystko ok to sprawdź ten mój program, który ci troche przerobiłem.

#include<avr/io.h>
#include<util/delay.h>
#include<avr/interrupt.h>

volatile int przerwanie=0;
volatile int x=0;

ISR(TIMER0_COMP_vect)
{
przerwanie=1;
} 

int main(void)
{
//ustawienie wejsc/wyjsc
DDRB |= (1<<PB0)|(1<<PB1)|(1<<PB2);
PORTB = 0x01;                        /// diody jako wyjscia, pierwsza od razu zapalona

////inicjalizacja timera w trybie CTC
   TCCR0 |= (1<<WGM01);   // tryb CTC
   TCCR0 |= (1<<CS00) | (1<<CS02) ; // preskaler 1024
   OCR0 = 250; // 4hz
   TIMSK |= (1<<OCIE0);                // zezwolenie na przerwanie CompareMatch

   sei();                              //zezwolenie na prerwania globalne


       while(1)
       {
		if (przerwanie==1)
		{
			x++;
			przerwanie==0;

			if (x==3)
			{
			PORTB = 0x01;
			x=0;
			}
			else
			PORTB = PORTB<<1;
		}
       }
}

Nie jestem pewien czy dobrze ustawilem timer w 100% bo robilem na szybko,
przerwanie powinno wyłowywać się z częstotliwością 4 Hz.

W przerwaniu dałem zmiane flagi, staraj się głównie operować w nich na flagach bo nie jest wskazane w przerwaniach umieszczanie dużych części kodu czy różnych funkcji delay itp.

Sama zasada działania jest prosta, robimy przesunięcie binarne co przerwanie, jeśli x==3 to oznacza, że PORTB == 0b00000100 i należy wpisać wartość poprostu 1.

Jak masz pytania to pisz.

Udostępnij ten post


Link to post
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.

Zaloguj się, aby obserwować  

×
×
  • Utwórz nowe...