Pomoc przy timerze 1 (bascom)

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
Jasam
Użytkownik
Posty: 422
Rejestracja: 27 mar 2007, 21:09

Pomoc przy timerze 1 (bascom)

Post autor: Jasam » 07 lut 2008, 20:20

Za nic nie mogę zrozumieć jak działa odmierzanie czasu timerem na przyklad timer1. Na przykład (oczywiscie pominąłem deklarację portów):
kwarc 4 megaherce

Kod: Zaznacz cały

Config Timer1 = Timer , Prescale = 256
Enable Interrupts
Enable Timer1
On Timer1 T1

Timer1 = 15625

do 
loop

T1:
toggle portb.0
return
Je sli dobrze rozumiem to przerwanie w którym zostanie wykonana procedura t1 zostanie wykonane kiedy timer sie przepełni. Ograniczylem jego pojemnośc do 15625. Przy oscylatorze 4 megaherców i podziale przez 256 tyle własnie procesor zliczy w sekundę. dlaczego więc port zmienia stan w jakichś dziwnych odstepach czasu? z reguly dluzszych niz powinien...Pomóżcie..wytlumaczcie..
Ostatnio zmieniony 07 lut 2008, 20:39 przez Jasam, łącznie zmieniany 1 raz.

ZbeeGin

Post autor: ZbeeGin » 07 lut 2008, 20:28

Z tym ograniczeniem pojemności licznika to kolega się bardzo pomylił.

Wpisałeś w TIMER1 15625 a zatem do przepełnienia licznik zliczy: 65536-15625 = 49911 impulsów wyjściowych z preskalera. Czas pomiędzy uruchomieniem licznika przez CONFIG z parametrem PRESCALE, a wpisaniem nowej wartości do licznika możemy tutaj pominąć z racji tak dużego podziału.

Ponadto jak już licznik zliczy te 49911 impulsów to następnie zliczy... I tu niespodzianka: 65536 impulsów!! Dlaczego? Bo nie przypisałeś ponownie w przerwaniu nowej wartości do TIMER1.

Ot cała filozofia.

Jasam
Użytkownik
Posty: 422
Rejestracja: 27 mar 2007, 21:09

Post autor: Jasam » 07 lut 2008, 20:37

Zaczynam rozumieć. Czyli powinno byc tak jesli dobrze rozumiem. A gdzie wpisac tą nową wartość w przerwaniu?

Kod: Zaznacz cały

Config Timer1 = Timer , Prescale = 256
Enable Interrupts
Enable Timer1
On Timer1 T1

Timer1 = 49911

do
loop

T1:
toggle portb.0
return
Ostatnio zmieniony 07 lut 2008, 20:39 przez Jasam, łącznie zmieniany 1 raz.

ZbeeGin

Post autor: ZbeeGin » 07 lut 2008, 20:38

Jasam pisze:A gdzie wpisac tą nową wartość w przerwaniu?
Sam sobie odpowiedziałeś: "w przerwaniu".

Jasam
Użytkownik
Posty: 422
Rejestracja: 27 mar 2007, 21:09

Post autor: Jasam » 07 lut 2008, 20:40

Czyli tak? Nie mam innego pomyslu...

Kod: Zaznacz cały

Config Timer1 = Timer , Prescale = 256
Enable Interrupts
Enable Timer1
On Timer1 T1

Timer1 = 49911

do
loop

T1:
Timer1 = 49911 
toggle portb.0
return

--------
Używaj tagów CODE, bo będzie ostrzeżenieZbeeGin
Ostatnio zmieniony 07 lut 2008, 20:41 przez Jasam, łącznie zmieniany 1 raz.

ZbeeGin

Post autor: ZbeeGin » 07 lut 2008, 20:42

Dokładnie w tym miejscu.

Jasam
Użytkownik
Posty: 422
Rejestracja: 27 mar 2007, 21:09

Post autor: Jasam » 07 lut 2008, 20:54

Dziwne, że post z moim podziękowaniem do Zbeegina został usunięty (najprawdopodobniej przez niego). Jednak podziękuję jeszcze raz z całego serca. Ależ bardzo proszę <ironiczny uśmiech>.

Awatar użytkownika
RcTomek
Moderator
Posty: 243
Rejestracja: 27 wrz 2007, 21:15
Lokalizacja: Głogów / Wrocław

Post autor: RcTomek » 08 lut 2008, 15:40

Jest jeszcze inna metoda: tryb CTC. Wtedy nie musisz co każde przerwanie wpisywać do timera jakąś tam wartość skracającą cykl. Włączasz CTC, wpisujesz ową wartość do rejestru np. COMPARE1A, i wywołujesz wtedy przerwanie On Compare1a Etykieta (zrównanie zawartości licznika z zawartością rejestru Compare1a). Ten sposób zwiększa nieco dokładność odliczania.

ZbeeGin

Post autor: ZbeeGin » 08 lut 2008, 17:25

Ddevil pisze:Jest jeszcze inna metoda: tryb CTC.
Owszem można i tak. W BASCOMie niestety jego stosowanie i konfigurowanie jest bardzo mgliście opisane. Jest dodatkowa opcja w poleceniu CONFIG TIMER: CLEAR TIMER = 0 | 1 która go włącza, ale nie ma dalszych informacji jak tego używać. Np. w ATTiny26 tryb CTC współpracuje tylko z rejestrem OCR1C! Nie ma też zdefiniowanych przyjaznych zmiennych: COMPARE1C.
Dlatego też, w tym przypadku, łatwiej i czytelniej było zrobić wszstko "na piechotę".
Ddevil pisze:Włączasz CTC, wpisujesz ową wartość do rejestru np. COMPARE1A, i wywołujesz wtedy przerwanie On Compare1a Etykieta (zrównanie zawartości licznika z zawartością rejestru Compare1a).
Więcej! Nie trzeba nawet używać przerwań i pisać do nich programów obsługi gdyż odpowiednio ustawiając bity COMnx1 licznik sam będzie zmieniał stan końcówki OC1x w każdym spełnionym porównaniu.

Jasam
Użytkownik
Posty: 422
Rejestracja: 27 mar 2007, 21:09

Post autor: Jasam » 08 lut 2008, 18:36

Dla mnie brzmi to dosyć skomplikowanie.

Awatar użytkownika
RcTomek
Moderator
Posty: 243
Rejestracja: 27 wrz 2007, 21:15
Lokalizacja: Głogów / Wrocław

Post autor: RcTomek » 08 lut 2008, 19:02

ZbeeGin pisze:W BASCOMie niestety jego stosowanie i konfigurowanie jest bardzo mgliście opisane.
W takim przypadku można przeprowadzić konfigurację bezpośrednio wpisując do odpowiednich rejestrów I/O potrzebne ustawienia (przy pomocy Bascom'a lub ASM jak kto woli).

ZbeeGin

Post autor: ZbeeGin » 09 lut 2008, 8:14

Wcale nie trzeba posuwać się do manipulowania rejestrami w celu konfiguracji CTC. Wystarczy złożyć odpowiednio polecenie CONFIG:

CONFIG TIMER1 = TIMER , PRESCALE = 8 , COMPARE A = TOGGLE , CLEAR TIMER = 1

Jedyny problem to wpisywanie danych do rejestru COMPARE. Nie wyszystkie są jak pisałem "zaaliasowane" do zmiennych specjalnych. Ale próbować można:

Kod: Zaznacz cały

$regfile = "m8515.dat"
$crystal = 1000000

Config Timer1 = Timer , Prescale = 1 , Compare A = Toggle , Clear Timer = 1
Compare1a = 15625

Do
Loop
I już nam ładnie pracuje liczniczek, a stan OC1A zmienia się w takt kolejnych porównań.

ODPOWIEDZ