This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
en:avr:timers [2010/02/08 12:56] – mikk.leini | en:avr:timers [2020/07/20 09:00] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== Counters/ | ====== Counters/ | ||
- | Loendurid (inglise keeles // | + | Counters, which in some sense can be called timers, are one of the most important sub-functions of a microcontroller. These enable to precisely time processes, generate signals and count events. A counter converts the number of input cycles to a binary value using an array of triggers. The maximum number of counted cycles depends on the length of this array, and this is marked by the length of the binary code. AVR has 8- and 16-bit counters. If a timer has reached its maximum value (255 in 8-bit and 65535 in 16-bit counters), the next cycle will generate an overflow |
- | ===== Tüüpiline loendur | + | ===== Counter' |
- | Loendurit, mille taktsignaal tuleb töötaktist ja mis ei ole väliselt millegagi liidestatud, võib nimetada tüüpiliseks loenduriks. Sel loenduril | + | In the default mode, a counter does nothing more than continually count sequential numbers. Its value can, of course, be read and changed from the program at any time. The only additional function in the default mode is to cause an interrupt |
- | ==== Näide ==== | + | <box 100% round # |
- | Vaja on 8 MHz taktsagedusel töötav | + | Task: Make an 8 MHz ATmega128 |
<code c> | <code c> | ||
#include < | #include < | ||
- | // Loenduri 0 ületäitumine | ||
ISR(TIMER0_OVF_vect) | ISR(TIMER0_OVF_vect) | ||
{ | { | ||
- | // Loendurile sellise väärtuse omistamine, | + | // Give the counter such a value |
- | // et järgmine ületäitumine saabuks | + | // that the next overflow occurs in 10 ms. |
- | // Valem: 256 - 8 MHz / 1024 / 100 Hz = 177,785 = ~178 | + | // Formula: 256 - 8 MHz / 1024 / 100 Hz = 177,785 = ~178 |
TCNT0 = 178; | TCNT0 = 178; | ||
- | |||
- | // Tee midagi, aga alles pärast loendurile uue väärtuse omistamist | ||
} | } | ||
int main() | int main() | ||
{ | { | ||
- | // Kui esimest ületäitumise katkestust soovitakse ka 10 ms | + | // To make the first overflow interrupt fire in 10 ms as well, |
- | // pärast, tuleb loendur enne käivitamist algväärtustada. | + | // the counter needs to be initialized here. |
TCNT0 = 178; | TCNT0 = 178; | ||
- | // Sagedusjaguri teguriks | + | // Prescaler value 1024 |
- | TCCR0 = 0x05; | + | TCCR0 = 0x07; |
- | // Loenduri täitumise katkestuse lubamine | + | // Allow overflow interrupts |
TIMSK |= (1 << TOIE0); | TIMSK |= (1 << TOIE0); | ||
- | // Globaalne katkestuste lubamine | + | // Allow interrupts globally |
sei(); | sei(); | ||
- | // Lõputu programmitsükkel | + | // Endless loop |
while (1) continue; | while (1) continue; | ||
} | } | ||
</ | </ | ||
- | Näites toodud loendurile omistatava väärtusega siiski täpselt | + | The counter in this example will not generate the interrupt in exactly |
- | Kõik muud loendurid täiendavad tüüpilist loendurit. Seega kõigil loenduritel on tüüpilise loenduri tunnusjoon - ületäitumise katkestus. | + | </ |
- | ==== Välise taktika loendur | + | ==== External Clock Counter |
- | Loenduri taktsignaalina saab kasutada ka mikrokontrollerivälist signaali (inglise keeles //external clock source//). Selleks on AVR mikrokontrolleril | + | It is also possible to use an external clock source |
- | ==== Sündmuste mõõtmine | + | ==== Timing Events |
- | Kuna loendurid võimaldavad mõõta aega, on keerukamatel | + | Since the counters allow timing operations, more complex |
- | === Näide === | + | <box 100% round # |
- | Vaja on 8 MHz taktsagedusel töötava ATmega128-ga mõõta välise | + | Task: Measure the frequency of an external |
<code c> | <code c> | ||
Line 66: | Line 63: | ||
unsigned long frequency; | unsigned long frequency; | ||
- | // Sündmuse toimumise katkestus | + | // Interrupt for the event |
ISR(TIMER1_CAPT_vect) | ISR(TIMER1_CAPT_vect) | ||
{ | { | ||
- | // Loenduri nullimine esimese asjana | + | // Counter to 0 |
TCNT1 = 0; | TCNT1 = 0; | ||
- | // Tulemus on ainult siis arvestatav, kui | + | // The result is valid only if the counter |
- | // loendur pole vahepeal üle täitunud | + | // has not overflowed yet |
if (!(TIFR & (1 << TOV1))) | if (!(TIFR & (1 << TOV1))) | ||
{ | { | ||
- | // Sageduse arvutamine perioodi pöördväärtusest. | + | // Calculating the frequency from the period |
frequency = (unsigned long)8000000 / | frequency = (unsigned long)8000000 / | ||
(unsigned long)ICR1; | (unsigned long)ICR1; | ||
Line 82: | Line 79: | ||
else | else | ||
{ | { | ||
- | // Sagedus on vähem kui 122 Hz | + | // Frequency is less than 122 Hz |
frequency = 0; | frequency = 0; | ||
- | // Loenduri ületäitumise lipukese nullimine | + | // Set the counter' |
TIFR &= ~(1 << TOV1); | TIFR &= ~(1 << TOV1); | ||
} | } | ||
Line 92: | Line 89: | ||
int main() | int main() | ||
{ | { | ||
- | // Tõusva frondi registreerimine, sagedusjaguri tegur 1 | + | // Register a rising front, prescaler value 1 |
TCCR1B = (1 << ICES1) | (1 << CS10); | TCCR1B = (1 << ICES1) | (1 << CS10); | ||
- | // Sündmuse toimumise katkestuse lubamine | + | // Allow event interrupts |
TIMSK = (1 << TICIE1); | TIMSK = (1 << TICIE1); | ||
- | // Globaalne katkestuste lubamine | + | // Allow interrupts globally |
sei(); | sei(); | ||
- | // Lõputu programmitsükkel | + | // Endless loop |
while (1) continue; | while (1) continue; | ||
} | } | ||
</ | </ | ||
- | Programmis tekib välise signaali tõusva frondi ajal sündmuse katkestus. Katkestuse jooksul kontrollitakse, ega loenduri ületäitumine pole toimunud | + | The program fires an interrupt each time a rising front occurs in the external signal. During the interrupt, the counter is checked for overflows |
- | Sündmuste püüdmist ning nende aja registreerimist saab teha ka tarkvaraliselt. Saab kasutada väliseid või muid katkestusi ja nende tekkimise ajal lugeda loenduri väärtuse. Kuid riistvaraline sündmuste püüdmine on mõeldud eeskätt siiski programmist sõltumatuks töötamiseks ja suhteliselt lühiajaliste (või tihedate) sündmuste mõõtmiseks. | + | </ |
- | ===== Signaali genereerimine ===== | + | Catching events and registering the time it took for them to occur can also be resolved at the software level. It is possible to use external or other interrupts and read the value of the counter during these events. The hardware-level event catching is meant to run independently from the main program and time relatively short (or frequent) events. |
- | Peale signaali pikkuse mõõtmise saab keerukamate loenduritega ka signaali tekitada. Selleks on loenduril väärtuse võrdlemise üksus (inglise keeles //output compare unit//) ja võrdlustulemuse väljastusüksus (inglise keeles //compare match output unit//). Võrdlusüksusesse kuuluvad registrid sama bitilaiusega kui loendur ise ja mille väärtusi võrreldakse loenduri väärtusega selle töö ajal. Hetkel, mil loenduri väärtus saab võrdseks võrdlusüksuse registri väärtusega, | + | ===== Signal Generating ===== |
- | Väljastusüksuses on võimalik seadistada väljundviikude käitumist võrdusmomendil. Valida on viigu kõrgeks muutmise, madalaks muutmise ja ümbermuutumise vahel. Nende täpsem toime aga sõltub sellest, millist signaali genereerimise režiimi kasutada. Kui kasutusel on PWM signaali tekitamise režiim (järgmine peatükk), siis viik muutub loenduri täitumisel kas madalaks või kõrgeks, vastupidiselt sellele, mida viik teeb võrdusmomendil. | + | More complex counters can generate a signal, in addition to timing the length of one. For this purpose the counter has an output compare unit and a compare match output unit. The output compare unit has registers with the same bit-width as the counter and the values of these registers are compared to the value of the counter while it is running. An interrupt can be generated and special pins' values can be changed each time the counter' |
- | Mõnedel signaali genereerimise režiimidel on määratav ka loenduri suurim väärtus - loenduri füüsiline suurus jääb küll samaks, kuid mängus on võrdlusregister, mille väärtust ületades loendur nullitakse. Seda võimalust kasutades saab eespool toodud ülesandeid täpse ajalise katkestuse tekitamise kohta lahendada, kuid mõeldud on see pigem signaali perioodi muutmiseks. Vähe sellest - mõnes režiimis toimib loendur juurde ja maha lugedes. | + | In some signal generating modes, the counter' |
- | Loendurid ja eriti just nende signaali genereerimise režiimid on ühed keerulisemad perifeeriamoodulid | + | The counters and the signal generating modes using them are one of the most complex peripheral modules in an AVR. Writing about all of them here is beyond the scope of this text, and typically there is no need to know all aspects in order to use them. The following describes one of the most common |
- | ==== Pulsilaius-modulatsioon | + | ==== Pulse Width Modulation |
- | Pulsilaius-modulatsioon (inglise keeles // | + | Pulse width modulation |
- | === Näide === | + | <box 100% round # |
- | Vaja on 8 MHz taktsagedusel töötava | + | Task: Using an 8MHz ATmega128, generate two speed regulating servo motor signals. Use pin PB5 (OC1A) |
<code c> | <code c> | ||
Line 133: | Line 130: | ||
int main() | int main() | ||
{ | { | ||
- | // Viigud väljundiks | + | // Set pins as outputs |
DDRB |= (1 << PIN5) | (1 << PIN6); | DDRB |= (1 << PIN5) | (1 << PIN6); | ||
- | // Väljundid | + | // Set outputs |
- | // "Fast PWM" | + | // "Fast PWM" |
TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11); | TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11); | ||
TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11); | TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11); | ||
- | // Suurim loenduri väärtus. Valem: | + | // Maximum value of the counter. Formula: |
// TOP = 8 MHz / 8 / 50 Hz | // TOP = 8 MHz / 8 / 50 Hz | ||
ICR1 = 20000; | ICR1 = 20000; | ||
- | // Esimese mootori poolperiood | + | // Half-period of the first motor is 1 ms, and second |
OCR1A = 1000; | OCR1A = 1000; | ||
OCR1B = 2000; | OCR1B = 2000; | ||
- | // Lõputu programmitsükkel | + | // Endless loop |
while (1) continue; | while (1) continue; | ||
} | } | ||
</ | </ | ||
+ | |||
+ | </ |