Tak na szybko - jak te wszystkie rejestry poustawiac? Zegar 4MHz. Wykombinowalem tak: Prescaler 256, wiec zliczenia nastepuja co 0,000064s, czyli do zliczenia
1s potrzebuje zliczyc 15625 impulsow. Wiec timer1 16bit zlicza w gore od 0 ... OCRA ustawiony na 15625 Clear Timer on Compare Match (CTC) Mode WGM13:0 = 4 i wywoluje procedurke moja (ktora np zlicza sekundy, jak sekundy >60 to minuty++ itd) czy wywolanie procedurki bedzie w postaci ?: SIGNAL(TIMER1_COMPA_vect) { costam; } I jak do tego poustawiac TCCR1A,TCCR1B i co jeszcze zeby wlaczyc przerwanie (tylko) od tego przeladowania?
Didn't find your answer? Ask the community — no account required.
M
murmi
U¿ytkownik "BartekK" snipped-for-privacy@drut.org napisa³ w wiadomo¶ci news:e64mdt$mj3$ snipped-for-privacy@nemesis.news.tpi.pl...
to taki "szkielet" - byc moze o czyms zapomnialem - na pewno wszystko jest w datashit; a tak btw. o ile procek robi jeszcze cos innego poza mierzeniem czasu, to zegarek ten raczej nie bedzie dokladny z kilku wzgledow:
- dokladnosc kwarcow itede
- wykonanie kazdej instrukcji "iles czasu" trwa
- zachecam do wykorzystania kwarca zegarkowego 32768 khz do pomiaru czasu
- na stabilnosc wewn. oscylatora (jesli go wykorzystujesz) w ogole nie licz
murmi
M
mIrO
U¿ytkownik "murmi" napisa³ w wiadomo¶ci
Ale studenckie projekty na tym przechodza ;)
B
BartekK
murmi napisał(a):
Dzieki Oczywiscie na dokladnosc nie licze, po prostu chce przerobic stare programy z basica na c, i przy okazji powyrzucac "wait 15" zamieniajac na dekrementacje licznika w przerwaniu, cos mniejwiecej zamiast: if cos then wlacz costam wait 15 wylacz costam zamienie na: volatine uint8_t timer_jakis if (cos) timer_jakis=15; if (timer_jakis>0) {wlacz costam;} else {wylacz costam;} endif a w przerwaniu co 1s od timer1 bedzie if (timer_jakis>0) timer_jakis--;
Dzieki temu program sie zrobi troche bardziej "wielozadaniowy" ;)
M
murmi
U¿ytkownik "mIrO" <miro@spamowi_mowie_nie.pl> napisa³ w wiadomo¶ci news:e653bs$jhs$ snipped-for-privacy@atlantis.news.tpi.pl...
tiaaaaaaaa - z autopsji wiem ile zazwyczaj s± warte projekty studenckie... ;)
murmi
M
MariuszC
ale gdy licznik doliczy do tej wartosci wpisanej do rejestrow OCR1Ax pojdzie dalej od wartosci 15625 do 65535, przejdzie przez 0 i wywola przerwanie znow gdy osiagnie 15625. Dlatego ustaw dodatkowo licznik w tryb pracy "Clear Timer on Compare Match (Auto Reload)", a wartosc poczatkowa ustaw na 0. Tak mi sie wydaje, wiec doczytaj szczegoly w pdf-ie procesora
Mariusz
B
BartekK
MariuszC napisał(a):
czyli jak? (jaka zawartosc i ktorych rejestow jeszcze trzeba zmienic?) bo juz mi oczy od patrzenia w pdf wypadaja
M
MariuszC
Wlasciwie zdublowalem info podane wczesniej przez BartkaK. On w przykladowym kodzie powyzej zrobil to o czym ja mowilem, a ze nie uzywalem do tej pory timerow w AVRze wiec podalem ogolnie jak ma dzialac timer aby osiagnac to o co Ci chodzi. CTC to wlasnie tryb "Clear Timer on Compare Match (Auto Reload)".
Uzywasz trybu CTC gdzie wartosc TOP jest brana z rejestru OCR1A, wtedy bit WGM12 musi byc ustawiony a reszta (WGM10, WGM11, WGM13) wyzerowana. Zatem kod podany przez BartkaK jest OK, jedynie wyczytalem w opisie rejestru Timer/Counter Interrupt Flag Register - TIFR że bit TOV1 jest ustawiany w trybie normalnym i CTC(!) timera, więc wektor przerwania to ma byc SIG_OVERFLOW1, a nie SIG_OUTPUT_COMPARE1A (jak to podal BartekK):
_BV( x ) to makro wykonujace operacje ( 1 << x ) gdy uzywasz srodowiska WinAVR.
Jakby cos Ci nie dzialalo to daj znac, moze znajde chwile aby poprobowac na jakiejs mojej plytce prototypowej. Oczywiscie skoro uzywasz kwarca zewnetrzego, ustawiles odpowiednie fuse bity aby nie byl wykorzystany oscylator wewnetrzny ~1MHz.
Pozdrawiam Mariusz
M
MariuszC
Wlasciwie zdublowalem info podane wczesniej przez Murmiego. On w przykladowym kodzie powyzej zrobil to o czym ja mowilem, a ze nie uzywalem do tej pory timerow w AVRze wiec podalem ogolnie jak ma dzialac timer aby osiagnac to o co Ci chodzi. CTC to wlasnie tryb "Clear Timer on Compare Match (Auto Reload)".
Uzywasz trybu CTC gdzie wartosc TOP jest brana z rejestru OCR1A, wtedy bit WGM12 musi byc ustawiony a reszta (WGM10, WGM11, WGM13) wyzerowana. Zatem kod podany przez Murmiego jest OK, jedynie wyczytalem w opisie rejestru Timer/Counter Interrupt Flag Register - TIFR że bit TOV1 jest ustawiany w trybie normalnym i CTC(!) timera, więc wektor przerwania to ma byc SIG_OVERFLOW1, a nie SIG_OUTPUT_COMPARE1A (jak to podal Murmie):
_BV( x ) to makro wykonujace operacje ( 1 << x ) gdy uzywasz srodowiska WinAVR.
Jakby cos Ci nie dzialalo to daj znac, moze znajde chwile aby poprobowac na jakiejs mojej plytce prototypowej. Oczywiscie skoro uzywasz kwarca zewnetrzego, ustawiles odpowiednie fuse bity aby nie byl wykorzystany oscylator wewnetrzny ~1MHz.
Pozdrawiam Mariusz
M
MariuszC
Odpowiadam sam sobie, ale juz z ciekawosci chcialem przecwiczyc ten timer w trybie CTC (kto wie moze w przyszlosci mi sie to przyda) i napisalem kod na swoja uklad testowy. Okazuje sie ze kod ktory przytoczylem powyzej jest zly, bo nie sa generowane przerwania. Wkurzylem sie i poczytalem dokladnie wszystko o Timerach, w opisie trybu CTC Timera0 jest "An interrupt can be generated each time the counter value reaches the TOP value by using the OCF0 Flag." (a nie ma podobnej informacji w opisie trybu CTC Timera1 dotyczacego bitu OCIE1A), zaś w opisie rejestru TIFR Timera1: "In Normal and CTC modes, the TOV1 Flag is set when the timer overflows.". Ta druga informacja mnie zmyliła. Zatem kolega Murmie podal faktycznie uzywany wektor przerwania w swoim kodzie przykladowym. Ponizej podaje sprawdzony, dzialajacy kod:
#include <avr/io.h>
#include <avr/interrupt.h>
int main( void ) { DDRA = 0xFF; // PORTA bedzie przelaczany miedzy 0x00 a 0xFF
return 0; // tylko aby uniknac warning kompilatora }
SIGNAL( SIG_OUTPUT_COMPARE1A ) { // funkcja wolana co 1 sekunde! PORTA = ~PORTA; // Neguj zawartosc bitow PORTA }
Teraz na porcieA co sekunde jego bity beda negowane.
Uwaga: na symulatorze AVRStudio widac, ze rejestry Timera nie sa automatycznie zerowane w momencie dojscia do wartosci takiej jak zapisana w OCR1 (16bit), tylko troszke pozniej -> tak samo jest na sprzecie, w funkcji obslugi przerwania jak odczytywalem wartosc TCNT1L i wpisywalem ja do portuA mial wartosc 0x00, ale max wartosc odczytywana w tej nieskonczonej petli jaka TCNT1L uzyskal byla rowna OCR1AL (przy czym OCR1AH byl ustawiony na 0x00).
Mariusz
T
TomekM
Jest to zresztą zgodne z dokumentacją. Dlatego też dla 1 sekundy musi być: OCR1AH = 0x3D; OCR1AL = 0x08;
Tomek
M
MariuszC
Faktycznie, jest to w punkcie "Output Compare Units": "If TCNT equals OCRnx the comparator signals a match. A match will set the Output Compare Flag (OCFnx) at the next timer clock cycle."
Człowiek nie doczyta dwóch zdań a potem spędzi tydzien dociekając z jakiej przyczyny dostaje event nie co 1sekundę, ale co 999,936 milisekund!!!
Mariusz
M
MariuszC
Faktycznie, jest to w punkcie "Output Compare Units": "If TCNT equals OCRnx the comparator signals a match. A match will set the Output Compare Flag (OCFnx) at the next timer clock cycle."
Człowiek nie doczyta dwóch zdań a potem spędzi tydzien dociekając z jakiej przyczyny dostaje event nie co 1sekundę, ale co 1000,064 milisekund!!!
Mariusz
M
murmi
Byc mo¿e masz racje - niemniej przerwania tego uzylem juz kilkadziesiat razy w przeciagu 2 lat w roznych programach - jak do tej pory telefonow o tresci "cos nie dziala" nie otrzymalem :)
pozdrawiam murmi
M
MariuszC
Witam przeczytaj proszę mój następny post (pod tym na który dałeś odpowiedź, tam jest wyjaśnione że coś jest nie tak z dokumentacją procesora
Mariusz
M
murmi
hmmmm... dlaczego wczesniej go przeoczylem??? nie wiem... :)
pozdrawiam murmi
Join the Discussion
Have something to add? Share your thoughts — no account required.
Didn't find your answer?
Ask the community — no account required
Report Content
You are reporting this content to the moderators. They will look at it
ASAP.