Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 19 mar 2026, o 23:42


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 11 ] 
Autor Wiadomość
PostNapisane: 16 wrz 2014, o 12:46 
Offline
Użytkownik

Dołączył(a): 03 lut 2014
Posty: 37
Pomógł: 0

Proszę o sprawdzenie obliczeń timera0 na atmega8 i kwarcu 8MHz.

F_CPU/preskaler = 8000 000/64 = 125000 tyknięć timera na sekundę
125000 = 125*1000
256-125 = 131 Więc jako wartość początkową timera ustawiam TCNT0 = 131;
W funkcji przerwania mam pętlę for z liczbą 1000.

Chcę, bo dioda zmieniała swój stan co 1s. Robi to jakieś 2,5 raza na sekundę.

Oto kod:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Dodam, że nie mam kondensatorów 22pF przy kwarcu (tych, które wg dokumentacji podłącza się do GND) ponieważ gdy choćby jeden z nich jest podłączony to atmega nie startuje.

Proszę o pomoc. Przeczytałem już wiele tego co w sieci ale nadal widać czegoś nie rozumiem z tą częstotliwością migania diody.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 16 wrz 2014, o 13:02 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27450
Lokalizacja: Szczecin
Pomógł: 1045

cwanish napisał(a):
Dodam, że nie mam kondensatorów 22pF przy kwarcu (tych, które wg dokumentacji podłącza się do GND) ponieważ gdy choćby jeden z nich jest podłączony to atmega nie startuje.

Bo na 100% nie są to kondensatory 22pF jeśli procek nie startuje - więc zmień na prawdziwe 22pF a gwarantuję ci głową że będzie działać, ale spoko i bez tego do testów też można na chwilę pominąć te kondki

cwanish napisał(a):
Chcę, bo dioda zmieniała swój stan co 1s. Robi to jakieś 2,5 raza na sekundę.

Bo teraz to się zastanów pan NAJPIERW z jakiego trybu Timera ty chcesz korzystać ;)

bo niby z twojego opisu wynika, że chcesz działać w trybie NORMAL

ale z kodu wynika tak jakbyś chciał użyć trybu CTC

czyli pomieszały ci się kompletnie dwa tryby pracy - i to musisz poprawić

------------------------ [ Dodano po: kilkunastu sekundach ]

Ba jeszcze jaki to procek ? bo jak np ATmega8 to ona w ogóle nie ma nawet trybu CTC dla Timer0 ;)

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 16 wrz 2014, o 13:07 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 07 kwi 2013
Posty: 418
Lokalizacja: Rzeszów
Pomógł: 102

Przy każdym przejściu do funkcji obsługi przerwania musisz ustawiać ponownie rejestr TCNT0, ponieważ zawiera on aktualną wartość licznika (nie jest to ustawienie stałe). Pojedyncze przypisanie sprawia, że tylko pierwszy okres timer'a będzie poprawny, a kolejne się przedłużą. Dodatkowo zmieniłbym zasięg zmiennej "licznik" na lokalny dla funkcji obsługi przerwania.

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Lepszym do tego typu zastosowań jest tryb CTC timer'a.

Edit: Mirek mnie ubiegł :)


Autor postu otrzymał pochwałę


Ostatnio edytowano 16 wrz 2014, o 15:17 przez atmel, łącznie edytowano 1 raz

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 16 wrz 2014, o 14:55 
Offline
Użytkownik

Dołączył(a): 03 lut 2014
Posty: 37
Pomógł: 0

Panie Mirku, miał Pan rację z kondensatorami :)

Ale ten timer... w dokumentacji jest o nim (timer0) wyraźnie napisane, że można wpisać wartość od jakiej ma liczyć do rejestru TCNT0. Będzie zliczał do 255. Potem powinno nastąpić przepełnienie i co za tym idzie -> przerwanie.
To chyba najprostsze użycie timera jakie jest możliwe. Do tego atmel napisał wyżej że lepiej użyć trybu CTC (w atmega8 nie ma, jak Pan Mirek pisał). Zatem która część mojego kodu odnosi się do trybu CTC? Czy chodzi o wpisanie wartości początkowej? Od początku chciałem użyć trybu normalnej pracy.

Czy mógłby mi ktoś pokazać jak w normalnym trybie timera0 osiągnąć przerwania co 1 sekundę?

Chodzi mi o wyjaśnienie dlaczego mój tok myślenia jest błędny, bo wpisując wartości zmiennym metodą prób i błędów osiągnę jakieś przybliżenie sekundy ale nadal nie będę rorzumiał.



Ostatnio edytowano 16 wrz 2014, o 15:01 przez cwanish, łącznie edytowano 1 raz

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 16 wrz 2014, o 15:00 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 07 kwi 2013
Posty: 418
Lokalizacja: Rzeszów
Pomógł: 102

Wcześniejszy brak informacji o procesorze, dlatego wspomniałem o CTC.

Zgadza się, timer liczy od 131 do wartości 255 (w trybie liczenia w górę), ale później ten rejestr nie jest ponownie przeładowywany wartością 131, a zaczyna liczenie od 0, dlatego trzeba ten rejestr zapisywać ponownie.
O "ustawieniu" trybu CTC świadczy sposób jego błędnej interpretacji. Nie jest on zawarty w kodzie, a jedynie chcesz aby pracował w tym trybie.

Przecież podałem wyżej jak powinien wyglądać kod dla trybu "Normal"...



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 16 wrz 2014, o 15:06 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27450
Lokalizacja: Szczecin
Pomógł: 1045

cwanish napisał(a):
w dokumentacji jest o nim (timer0) wyraźnie napisane, że można wpisać wartość od jakiej ma liczyć do rejestru TCNT0. Będzie zliczał do 255. Potem powinno nastąpić przepełnienie i co za tym idzie -> przerwanie.


TAK i za pierwszym razem po inicjalizacji tak się stanie ;) i pierwsze przerwanie w trybie NORMAL odbędzie się po założonym czasie ....

ale poczytaj co wyżej pisze kolega atmel i słusznie ci podpowiada

przecież gdy Timer0 zliczy do 255 to się - W Y Z E R U J E - i będzie liczył od ZERA a nie od 131 - rozumiesz ?

dlatego trzeba go ładować za każdym razem w przerwaniu i WCALE nie tą wartością co wyliczyłeś .... Dlaczego (masz to opisane WYRAŹNIE w Bluebooku przecież) ;) wprawdzie na przykładzie Timer1 zdaje się ale zasada jest ta sama

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 16 wrz 2014, o 15:11 
Offline
Użytkownik

Dołączył(a): 03 lut 2014
Posty: 37
Pomógł: 0

No tak, tylko że jedyna zmiana którą wprowadziłeś jest w funkcji ISR przerwania. Dodałeś "static" do zmiennej co pewnie jest bardziej poprawne ale tak naprawdę nic nie zmienia.

Dodałeś też TCNT0 = 131; do funkcji ISR - tu dałeś mi cenna informację że trzeba to robić za każdym razem - nie jest to ustawienie stałe. Ale mi dioda miga zbyt szybko - z Twoją funkcją ok 3-4 razy na sekundę czyli jakieś 6-8 razy zbyt szybko. Wpisanie wartości 131 na początku przerwania jeszcze przyśpiesza miganie :)

---
Zanim wysłałem post napisał Pan Mirek. Więc jedynym błędem jest wartość którą wpisuję do TCNT0 już w przerwaniu?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 16 wrz 2014, o 15:15 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27450
Lokalizacja: Szczecin
Pomógł: 1045

cwanish napisał(a):
Więc jedynym błędem jest wartość którą wpisuję do TCNT0 już w przerwaniu?


teraz już tak ;) tylko to pozostało ci do rozwiązania ;)

Podpowiedź - tą wartość wpisywałoby się TYLKO RAZ do rejestru porównania OCRx gdyby był tryb CTC, ale w trybie NORMAL trza inaczej ... Bluebook ;) tam masz to opisane z przykładem


Autor postu otrzymał pochwałę

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 16 wrz 2014, o 15:22 
Offline
Użytkownik

Dołączył(a): 03 lut 2014
Posty: 37
Pomógł: 0

Dziękuję:)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 17 wrz 2014, o 12:14 
Offline
Użytkownik

Dołączył(a): 15 cze 2013
Posty: 599
Lokalizacja: Lubin
Zbananowany użytkownik

Pomógł: 35

cwanish napisał(a):
Ale mi dioda miga zbyt szybko - z Twoją funkcją ok 3-4 razy na sekundę czyli jakieś 6-8 razy zbyt szybko.

Ustawiłeś fusebit aby procek korzystał z kwarca? Może ciągle działa na fabrycznym 1 Mhz?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 18 wrz 2014, o 09:32 
Offline
Użytkownik

Dołączył(a): 03 lut 2014
Posty: 37
Pomógł: 0

Ustawiłem. _delay_ms(1000) trwa sekundę. Gdybym nie ostawił i było 1mHz to byłoby zbyt wolno, a nie za szybko.

LOW FUSE: 0xDF
HOGH FUSE: 0x D9

------------------------ [ Dodano po: 43 minutach ]

No, to teraz wiem. Próbowałem coś takiego wcześniej ale widać coś przeoczyłem.

8 000 000 / 256 (preskaler) = 31250 tyknięć timera0
31250 tyknięć / 256 (pojemność timera 8bitowego) = 122,07 przepełnień timera0
122*256 = 31232 (tyknięć w pełnych cyklach timera - od zera do przepełnienia)
122 to wartość do pętli w przerwaniu ISR.
Do jednej sekundy pozostało 31250 - 31232 tyknięć = 18 tyknięć.
Po wykonaniu 122 przerwań od przepełnień do licznika TNTC0 wpisuję 255-18=246.
Wtedy licznik wykona już tylko pozostałe 18 tyknięć od 246 do 255 (ostatniego przepełnienia (i przerwania) wktórym to zmieniam stan diody.

Oto mój kod:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 11 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 0 gości


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO