[atmega162][c] przerwania/timery

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
ODPOWIEDZ
rzepcio
-
Posty: 16
Rejestracja: 03 lip 2009, 18:02
Lokalizacja: Katowice

[atmega162][c] przerwania/timery

Post autor: rzepcio » 14 lip 2009, 15:02

Jak zrobię bez przerwań np tak:

Kod: Zaznacz cały

	overflowT3 = 0;									// czas = 0 (zero przekręceń licznika)
	//ETIMSK |= _BV(TOIE3);							// zezwolenie na przerwania dla T3
	TIMSK |= _BV(TOIE0);							// zezwolenie na przerwania dla T0
	TCNT0 = 240;									// ustawienie wartości (max-16), aby przepełnienie było po 16 impulsach
	//sei();                   				    	// włącz obsługę przerwań
	TCCR3B |= _BV(CS30); 							// ustawienie timera zliczającego czas

Kod: Zaznacz cały

				if (TCNT3>65530)
				{
					overflowT3++;
					if (!(overflowT3%16))
					{
						if (PORTC == D_ZA_NISKO)
							PORTC = ZADNA_DIODA_NASTROJENIA;
						else if (PORTC == ZADNA_DIODA_NASTROJENIA)
							PORTC = D_ZA_NISKO;
					}
				}	
To dioda ładnie zapala się na ~sekundę i gaśnie.
Jak zrobię tak:

Kod: Zaznacz cały

	overflowT3 = 0;									// czas = 0 (zero przekręceń licznika)
	ETIMSK |= _BV(TOIE3);							// zezwolenie na przerwania dla T3
	TIMSK |= _BV(TOIE0);							// zezwolenie na przerwania dla T0
	TCNT0 = 240;									// ustawienie wartości (max-16), aby przepełnienie było po 16 impulsach
	sei();                   				    	// włącz obsługę przerwań
	TCCR3B |= _BV(CS30); 							// ustawienie timera zliczającego czas

Kod: Zaznacz cały

ISR(TIMER3_OVF_vect)
{
	overflowT3++;
	if (!(overflowT3%16))
	{
		if (PORTC == D_ZA_NISKO)
			PORTC = ZADNA_DIODA_NASTROJENIA;
		else if (PORTC == ZADNA_DIODA_NASTROJENIA)
			PORTC = D_ZA_NISKO;
	}
}
To dioda miga z 8 razy na sekundę :|
O co w tym chodzi??

_Brutus
-
Posty: 26
Rejestracja: 01 gru 2006, 16:08
Lokalizacja: Złotopole / Łódź
Kontakt:

Post autor: _Brutus » 14 lip 2009, 16:40

Ustaw sobie preskaler do taktowania timera i po problemie ;) A i pokaż jak masz fusebity ustawione.

rzepcio
-
Posty: 16
Rejestracja: 03 lip 2009, 18:02
Lokalizacja: Katowice

Post autor: rzepcio » 14 lip 2009, 17:35

Co ma preskaler do problemu? Dodałbym tylko, że to nie jest to, co układ ma robić, tylko część testowa wynikająca z błędnego działania programu.

Wcześniej nie opisałem dokładnej konfiguracji, wiec teraz to zrobię. Atmega162 taktowana jest kwarcem 12MHz. Według moich wyliczeń daje mi to mniej więcej jeden takt na 1 us, więc przekręcenie 16bitowego timera następuje po ~65ms, co daje nam ~16 przeładowań na sekundę.

Bez przerwań, przy sprawdzaniu jedynie aktualnej wartości licznika daje odpowiedni czas. Teraz jeszcze próbowałem zrobić to na CTC i otrzymałem dokładnie taki sam wynik jak przy przerwaniach overflow :(

[ Dodano: 2009-07-14, 18:45 ]
Wygląda na to, że poprawne działanie bez przerwań było spowodowane tylko tym, że nie zdążyło zauważyć wartości timera. Czy zatem źle policzyłem sobie szybkość timera?

[ Dodano: 2009-07-14, 19:00 ]
Ale ze mnie debil :) czytałem o kwarcach dla '51, a tam jest cykl maszynowy trwa 12 taktów zegara, zapewne w atmegach jest inaczej.
Załączniki
fusy.PNG

_Brutus
-
Posty: 26
Rejestracja: 01 gru 2006, 16:08
Lokalizacja: Złotopole / Łódź
Kontakt:

Post autor: _Brutus » 14 lip 2009, 19:57

No inaczej ;) W AVR'ach jeden cykl maszynowy to jeden cykl zegara.

A z preskalerem chodziło mi o to, że jak przerwanie następowało 8 razy za często, to wystarczyło włączyć preskaler timera przez 8 i już by było ok ;)

rzepcio
-
Posty: 16
Rejestracja: 03 lip 2009, 18:02
Lokalizacja: Katowice

Post autor: rzepcio » 14 lip 2009, 21:21

To było tylko tak na oko ;) Jak widać z dość dużą niedokładnością, a dokładność jest bardzo istotna ;)

ODPOWIEDZ