Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
et:examples:timer:delay [2009/11/25 11:16] – vana versioon taastatud mikk.leiniet:examples:timer:delay [2020/07/20 09:00] (current) – external edit 127.0.0.1
Line 1: Line 1:
-====== Viite tekitamine ======+====== Viide ======
  
-//Vajalikud teadmised: [HW] [[et:hardware:controller]], [AVR] [[et:avr:architecture|AVR arhitektuur]], [AVR] [[et:avr:timers|AVR taimerid]], [LIB] [[et:software:library:pin|Viikude teek]], [LIB] [[et:software:library:delay|Viite teek]]//+//Vajalikud teadmised:  
 +[HW] [[et:hardware:homelab:controller]],  
 +[AVR] [[et:avr:timers]], 
 +[LIB] [[et:software:homelab:library:pin]], [LIB] [[et:software:homelab:library:delay]], [LIB] [[et:software:homelab:library:timer]]//
  
 ===== Teooria ===== ===== Teooria =====
  
-Tihti on mikrokontrollerite programmis vaja tekitada viiteid - näiteks mingi tegevuse ajastamiseks või tegevuse lõpu ootamiseksKontroller on aga enamasti palju "kiirem" kui nii mõnigi tegevus ja seepärast on vaja kontrollerit kuidagi "aeglustada"Selleks on mitmeid võimalusi.+Tihti on mikrokontrollerite programmis vaja tekitada viiteid, et tegevusi ajastada või nende lõppu oodataÜks idee poolest lihtsamaid meetodeid mikrokontrolleri töös paus tekitada on selle protsessor mingi muu tegevusega üle koormata - näiteks panna see lugema suuri arveProtsessori taktsagedusest saab välja arvutada, mitmeni see arve loendama peaks, et kindlat ajalist viidet tekitada. Mingi arvu loendamine nullist protsessori taktsageduse väärtuseni hertsides tekitaks teoreetiliselt viite üks sekund. Praktikas see erinevatel põhjustel päris nii lihtne ei ole.
  
-==== Tarkvaraline viide ====+Kui mikrokontrolleri protsessor arvutab arvudega, mille kahendkuju on sama lai kui selle sisemine siin (AVR puhul 8-bitti), siis protsessoritel võtab üks aritmeetiline tehe, näiteks arvu liitmine ühega, aega 1 protsessori töötakt. Selleks, et arvutada tuhandete või miljonitega, peab arv olema 16- või 32-bitine ja nende arvutamiseks kulub 8-bitistel protsessoritel rohkem kui 1 töötakt. Niisiis, suurte arvude puhul peab tundma protsessori sisemust - täpsemalt selle käsustikku. Kuna kõrgtaseme keeles (näiteks C-keeles) programmeerides ei kirjutata programmi otse käsustiku baasil, peab tarkvaralise viite tekitamiseks tundma ka kompilaatorit, mis programmi masinkoodi teisendab. Just sellest sõltub, mitu instruktsiooni (ja sellest tulenevalt mitu takti) kulub aritmeetilisteks arvutusteks. Keerukust lisab veel asjaolu, et kompilaator võib programmi masinkoodi teisendada mitut moodi - näiteks tehes masinkoodi võimalikult mälusäästlikuks või võimalikult kiiresti täidetavaks. Neid kompilaatori tegevusi nimetatakse optimeerimiseks. Erinevate optimeerimise režiimidega tulevad ka tarkvaralise viite masinkood ja selle ajaline kestus erinevad.
  
-Üks idee poolest lihtsamaid meetodeid kontrolleri tegevuses paus tekitada on see mingi muu tegevusega üle koormata - näiteks panna see lugema suuri numbreid. Kontrolleri taktsagedusest saab välja arvutata mitmeni see numbreid loendama peaks, et kindlat ajalist viidet tekitada. Teoreetiliselt tekitaks siis mingi arvu (muutuja) loendamine nullist kontrolleri taktsageduse väärtuseni viite üks sekund. Praktikas see aga nii lihtne ei ole ning põhjuseid on mitmed:+===== Praktika ======
  
-Kui kontroller arvutab arvudega mis on sama suure ühikuga kui selle sisemine siin (AVR puhul 8-bitti) siis enamustel kontrolleritel võtab üks arvutus, näiteks liitmine ühega, aega 1 kontrolleri töötakt. Selleks, et arvutada tuhandete või miljonitega peab arvu muutuja olema 16- või 32-bitine ja nende arvutamiseks kulub 8-bitistel kontrolleril rohkem kui 1 töötakt. Niisiis, suurte arvude puhul peab tundma kontrolleri sisemust - täpsemalt selle käsustikku. +Järgnevalt on toodud näide tarkvaralise viite tekitamisest AVR mikrokontrolleriga. Kirjutatud on C-keele programmilõikmis loendab //for//-tsüklis muutujat //x// nullist sajani. Iga tsükli sees toimub ühe mittemidagitegeva tühiinstruktsiooni täitmine. Seda on seal vaja, kuna tsükli sisu tühjaks jättes optimeerib kompilaator tsükli programmist üldse välja, sest see on tema arvates kasutu.
- +
-Kuna kõrgtaseme keeles (C) programmeerides ei kirjutata programm otse käsustiku baasil peab tarkvaras viite tekitamisel tundma ka kompilaatorit, mis programmi masinkoodi teisendab. Just sellest sõltub mitu instruktsiooni (ja sellest tulenevalt takti) kulub millegi arvutamiseks. Keerukust lisab veel asjaolu, et kompilaator võib programmi masinkoodi teisendada mitut moodi - näiteks tehes masinkoodi võimalikult lühidaks või võimalikult kiiresti täidetavaks. Neid valikuid nimetatakse optimeerimiseks. Erinevate optimeerise režiimidega tuleb ka tarkvaralise viite masinkood ja selle ajaline kestvus erinev. +
- +
-=== Lihtsustatud näide === +
- +
-Järgnevalt on toodud näide tarkvaralise viite tekitamisest AVR mikrokontrolleriga. Kirjutatud on C keele programmilõik mis loendab //for// tsüklis muutujat //x// nullist sajani. Iga tsükli sees toimub ühe mitte-midagi tegeva tühi-instruktsiooni täitmine. Seda on seal vaja, kuna tsükli sisu tühjaks jättes kompilaator optimeerib tsükli programmist üldse välja kuna see on tema arvates kasutu.+
  
 <code c> <code c>
 unsigned char x; unsigned char x;
- 
 // Tsükkel seni kuni x on 100 // Tsükkel seni kuni x on 100
 for (x = 0; x < 100; x++) for (x = 0; x < 100; x++)
 { {
- // Tühi-instruktsiooniga nop+ // Tühiinstruktsiooniga nop
  asm volatile ("nop");  asm volatile ("nop");
 } }
 </code> </code>
  
-Siinkohal on aga toodud sama C-keele programmilõigu esitus masinkoodis (vasakpoolsed 2 heksadetsimaalarvuja assembler-keeles (sõna koos operandidega). Masinkood ja assembler-keel on üks-üheselt seotud, teine neist on lihtsalt inimesele loetaval kujul. Kompileerimisel on kasutatud programmi pikkuse optimeerimist (-Os).+Siinkohal on aga toodud sama C-keele programmilõik pärast kompileerimist. Vasakpoolsed 2 heksadetsimaalarvu on masinkood ja paremal on assemblerkeeles käsk koos operandi(de)ga. Masinkood ja assemblerkeel on üks-üheselt seotud, assembler on lihtsalt masinkoodi inimesele loetaval kujul esitamiseks. Kompileerimisel on kasutatud programmi pikkuse optimeerimist (kompilaatori parameeter -Os).
  
 <code asm> <code asm>
-80 e0       ldi r24, 0x00 ; r24 registrisse arvu 0 laadimine +80 e0     ldi  r24, 0x00   ; r24 registrisse arvu 0 laadimine 
-00 00       nop ; Tühioperatsioon +00 00     nop              ; Tühioperatsioon 
-8f 5f       subi r24, 0xFF ; r24 registrist 255 lahutamine, ehk siis +1 liitmine +8f 5f     subi r24, 0xFF   ; r24 registrist 255 lahutamine, ehk +1 liitmine 
-84 36       cpi r24, 0x64 ; r24 registri võrdlemine arvuga 100 +84 36     cpi  r24, 0x64   ; r24 registri võrdlemine arvuga 100 
-e1 f7       brne .-8       kui võrdlus polnud tõene siis siire 8 baiti tagasi+e1 f7     brne .-8         Kui võrdlus oli väär, siis siire 8 baiti tagasi
 </code> </code>
  
-Kompileeritud kujul on näha mis täpselt C-keele tsüklist saab ja selle järgi saab arvutada mitu instruktsiooni ühe tsükli perioodi puhul täidetakse. Antud näites kulub ühes tsükli perioodis 4 instruktsiooni täitmiseks 4 takti. Oletades, et kontrolleri töötakt on 14,7456MHz võib välja arvutada kogu tsükli tekitatud ajalise viite:+Kompileeritud kujul on nähamis tegelikult C-keele tsüklist saabja selle järgi saab arvutadamitu takti ühe tsükli perioodi täitmiseks kulub. Infot instruktsioonide toime ja tööaja kohta leiab AVR käsustiku andmelehest. Antud näites kulub ühe tsükli perioodis 4 instruktsiooni täitmiseks 4 takti, sest kõik instruktsioonid võtavad ühe töötakti. Lisaks kulub enne tsüklit 1 takt laadimisinstruktsiooni jaoks ja tsüklist väljudes 1 lisatakt. Oletades, et kontrolleri töötakt on 14,7456 MHz, võib välja arvutada kogu programmilõigu tekitatud ajalise viite:
  
-100 4 / 14745600 = 27.13us+(1 + 100 ⋅ + 1) / 14745600 = 27,26 μs
  
-====+Näites tekitatud viide on mikrosekundites ja kasutatav muutuja on 8-bitine, seega on ka masinkood üsna lihtne. Selleks, et tekitada pausi millisekundites, on vaja loendada palju suuremaid arve ja siis läheb ka masinkood pikemaks. Võib kasutada ka üksteise sees töötavaid tsükleid, kuid selle meetodi puhul pole kogu viide lineaarses sõltuvuses tsüklite arvust, sest iga tsükli tasemega tekivad pisikesed lisaviited.
  
-Näites tekitatud viide on mikrosekundites ja muutujat mida kasutatakse on 8-bitine, seega on ka masinkood üsna lihtne. Selleks, et tekitada pausi millisekundites on vaja palju suuremaid arve loendada ja siis läheb masinkood pikemaksVõib kasutada ka üksteise sees töötavaid tsükleid kuid selle meetodi puhul pole kogu viide lineaarses sõltuvuses tsüklite arvust, sest iga tsükli tasemega tekivad pisikesed lisaviited.+Käesoleva teooriaosa eesmärk ei ole siiski masinkoodi tasandil täpset tarkvaralist viidet tekitada, sest see on üsna peen töö ja pealegi on viite tekitamiseks avr-libc ja Kodulabori teegis juba funktsioonid olemasNeed kasutatakse ka järgmistes näidetes.
  
-Siiskikäesoleva harjutuse eesmärk ei ole ise täpset tarkvaralist viidet tekitadasest see on üsna keeruline ja pealegi on selleks avr-libc ja kodulabori teegis juba funktsioonid olemas. Need tulevad ka näites kasutusele.+Tarkvaralise viite puhul on aga oluline teadaet hoolimata oma põhimõttelisest lihtsusest on see äärmiselt ebaefektiivne meetod energiatarbe seisukohast. Kõigil neil taktidel, mil mikrokontroller tegeleb kasutu loendamisega, kulub energiat. Patareidega rakenduses ei ole seega soovitatav pikki tarkvaralisi viiteid tehavaid tuleks kasutada raudvaralisi taimereid, mis töötavad iseseisvalt ning äratavad protsessori uneolekust üles, kui on vaja tööd jätkata.
  
-Tarkvaralise viite puhul on aga oluline teada, et hoolimata oma põhimõttelisest lihtsusest on see äärmiselt eba-efektiivne meetod energiatarbe seisukohast. Kõigil neil taktidel mil mikrokontroller tegeleb kasutu loendamisega kulub energiat. Patareidega rakenduses ei ole seega soovitatav pikkasid tarkvaralisi viiteid teha, vaid kasutada taimereid mis töötavad iseseisvalt ning äratavad protsessor uneolekust üles kui aeg on täis.+[{{  :examples:timer:timer_counter.png?300|AVR loenduri väärtuse muutusega kaasnevad sündmused}}]
  
-==== Viide taimeriga ====+Tarkvaraline viide pole ainus meetod pausi tekitamiseks. Sama asja saab teha ka taimeriga. Taimer on riistvaraline kindla sagedusega suurenev või vähenev loendur. Loenduri taktsignaali saab enamasti tekitada mikrokontrolleri töötaktist või mingist välisest taktist. Taktsignaali sagedust saab üldjuhul ka mingi teguriga jagada väiksem taktsageduse saavutamiseks - seda tehakse taktijaguriga, mida inglise keeles nimetatakse //prescaler//. Oluline on siinkohal siiski fakt, et fikseeritud taktsagedusega loenduri väärtus on lineaarses sõltuvuses ajast. Aja saab välja arvutada, korrutades loenduri taktisignaali perioodi loenduri väärtusega.
  
-Taimer on riistvaraline kindla sagedusega suurenev või vähenev loendur. Loenduri taktsignaali saab tekitada mikrokontrolleri töötaktist või seda läbi jagadesSeega fikseeritud taktsignaaliga loenduri väärtus on lineaarses sõltuvuses ajastAja saab välja arvutada korrutades loenduri taktisignaali perioodi loenduri väärtusega.+AVR loendurit saab panna teavitama loenduri ületäitumisest (inglise keeles //overflow//või kindla väärtuse saavutamisest (inglise keeles //compare match//)Ületäitumine tekib hetkel, kui loendur on omistanud maksimaalse võimaliku väärtuse ja alustab uuesti nullist loendamistKindla väärtuse saavutamise puhul aga toimub loenduri suurendamise hetkel selle uue väärtuse võrdlemine kasutaja poolt määratud väärtusega. Sündmuse tekkimise korral seatakse AVR olekuregistrites vastavad bitid automaatselt kõrgeks.
  
-{{:examples:timer:timer_counter.png?300  |Loenduri töö}}+Selleks, et taimeriga viide tekitada, piisabki vaid loenduri seadistamisest ja olekubiti kõrgeks minemise ootamisestErinevalt tarkvaralisest viitest ei sõltu taimerite töö kompilaatorist, mis teeb nende kasutamise töökindlamaks. Samas võib AVR loendurite mitmekesisuse (või ka segasuse) tõttu  nende seadistamine üsna tülikas tunduda. Olenevalt mikrokontrolleri taktsignaalist võib ka juhtuda, et see ei jagu täpselt soovitud viite perioodiga ja viide ei ole täpne.
  
-AVR loendurid saab panna loenduri ületäitumisest (inglise keeles //overflow//) või kindla väärtuse saavutamisest (inglise keeles //compare match//) teavitama. Ületäitumine tekib hetkel kui loendur on omistanud maksimaalse võimaliku väärtuse ja alustab uuesti nullist loendamist. Väärtuse saavutamise kontroll toimub loenduri suurendamise hetkel selle uut väärtust kasutaja poolt määratud väärtusega võrreldes. Mõlema sündmuse tekkimist kujutab kõrvalolev graafik. Sündmuse tekkimise korral seatakse AVR olekuregistrites vastavad bitid automaatselt kõrgeks. +Järgnev programmikood käib tarkvaralise viite funktsiooni //sw_delay_ms// kohtamis tekitab parameetriga //count// etteantud viite millisekundites. Funktsioon kasutab omakorda avr-libc teegi poolenisti assemblerkeeles kirjutatud funktsiooni //_delay_ms//. Põhjusmiks harjutuses pole kohe //_delay_ms// kasutatudon selles, et //_delay_ms// puhul võivad pikkade viidetega probleemid tekkida. //sw_delay_ms// funktsioon võimaldab aga probleemideta kuni 65535 ms viidet.
- +
-Kui nüüd loendur õigesti ära seadistada, siis piisabki vaid olekubiti kõrgeks minemise ootamisest, et soovitud viide saada. Erinevalt tarkvaralisest viitest ei sõltu taimerite töö kompilaatorist, mis teeb nende kasutamise töökindlamaks. Samas, AVR-i loendurite mitmekesisuse (või ka segasuse) tõttu võib nende seadistamine esimestel kordadel üsna tülikas tunduda. Olenevalt mikrokontrolleri taktsignaalist võib ka juhtuda, et see ei jagu täpselt soovitud viite perioodiga ja viide ei ole täpne. +
- +
-AVR loendurite tööpõhimõttega lähemalt tutvumiseks on soovitatav lugeda vastavat peatükki AVR tutvustuses. +
- +
-===== +
- +
-Mõlemat liigi viite puhul peaks  +
- +
-===== Praktika ===== +
- +
-Järgnevas praktilises näites on kasutatud nii tarkvaralist kui riistvaralist viite tekitamise meetodit. Mõlema meetodi jaoks on kodulabori teeki loodud vastavad funktsioonid, mis tähendab, et ise neid kirjutama ei pea kuid kasulik on teada nende tööpõhimõtet. +
- +
-Järgnev programmikood käib tarkvaralise viite funktsiooni //sw_delay_ms// kohta mis tekitab parameetriga //count// etteantud viite millisekundites. Funktsioon kasutab omakorda avr-libc teegi poolenisti assembler keeles kirjutatud funktsiooni //_delay_ms//. Põhjus miks harjutuses pole kohe //_delay_ms// kasutatud on selles, et //_delay_ms// puhul on maksimaalne viide piiratud. //sw_delay_ms// funktsion võimaldab kuni 65535 ms viidet teha.+
  
 <code c> <code c>
-// 
 // Tarkvaraline viide millisekundites // Tarkvaraline viide millisekundites
-// 
 void sw_delay_ms(unsigned short count) void sw_delay_ms(unsigned short count)
 { {
Line 83: Line 63:
  while (count-- > 0)  while (count-- > 0)
  {  {
- // 1ms viide spetsiaalse funktsiooniga+ // 1 ms viide spetsiaalse funktsiooniga
  _delay_ms(1);  _delay_ms(1);
  }  }
Line 89: Line 69:
 </code> </code>
  
-Allpool olev programmikood on aga taimeril põhinev viite-funktsioonmida on natuke lihtsustatud. Loendamise põhimõte on sama mis tarkvaralise viite funktsioonilgi - tekitatakse soovitud arv 1 ms viiteidViite tekitamiseks on kasutusel ATmega128 8-bitine loendur 0. Eelnevalt on juba välja arvutatud, et 14.7456 Mhz taktsageduse puhul peab loenduri taktsignaal olema vähemalt 64 korda jagatud, et 1 ms jooksul 8-bitine loendur üle ei täituks. See, mis väärtust loendur omama peab, et ületäitumine toimuks 1 ms järel on esitatud avaldise kujul ja omistatud muutujale //timer_start//. Nimetatud taktsageduse puhul peaks siis loenduri väärtus 25.6 olema, kuid kuna murdarve kasutada ei saa, siis loenduri algväärtuseks saab 26. Siin tekib paraku ka viga viite ajas, kuid see on üsna väike (-1.7 mikrosekundit).+Toodud funktsiooni kasutamiseks on järgnev programm, mis tekitab lõputus tsüklis kaks viidet: 100 ms ja 900 ms. Lühema viite jooksul LED põleb ja pikema ajal on kustunud tulemusena LED perioodiliselt vilgatab.
  
-Tsüklis toimub loenduri algväärtustamine ja ületäitumise lipukese nullimine (sellesse 1 kirjutades). Seejärel oodatakse kuni loendur loeb algväärtusest kuni 256-ni, ehk nullimiseniNullimise hetkel läheb ületäitumise lipuke kõrgeks ja 1 ms viide ongi toimunud. Funktsiooni lõpus taimer peatatakse.+<code c> 
 +// Kodulabori tarkvaralise viite näidisprogramm 
 +// Programm vilgutab ~1 sekundi järel hetkeks LED-i 
 +#include <homelab/pin.h> 
 +#include <homelab/delay.h> 
 +  
 +// Põhiprogramm 
 +int main(void) 
 +
 + // LED-i viigu väljundiks seadmine 
 + pin_setup_output(led_debug); 
 + 
 + // Lõputu tsükkel  
 + while (1) 
 +
 + // LED-i süütamine 
 + pin_clear(led_debug); 
 +  
 + // Tarkvaraline paus 100 millisekundit 
 + sw_delay_ms(100); 
 +  
 + // LED-i kustutamine 
 + pin_set(led_debug); 
 + 
 + // Tarkvaraline paus 900 millisekundit 
 + sw_delay_ms(900); 
 +
 +
 +</code> 
 + 
 +Kuigi näib, et LED vilgatab tõesti 1 sekundi järel, on aeg tegelikult siiski natuke pikem, sest LED-i ja viite funktsioonide väljakutsumised võtavad ka mõned mikrokontrolleri taktid aega. 
 + 
 + 
 +Järgnev programmikood on taimeril põhinev ehk riistvaraline viitefunktsioon, mida on natuke lihtsustatud. Loendamise põhimõte on sama, mis tarkvaralise viite funktsioonilgi - tekitatakse soovitud arv 1 ms pikkuseid viiteid. Viite tekitamiseks on kasutusel 8-bitine loendur 0. Eelnevalt on juba välja arvutatud, et 14,7456 MHz taktsageduse puhul peab loenduri taktsignaal olema vähemalt 64-ga jagatud, et 1 ms jooksul 8-bitine loendur üle ei täituks. See, mis väärtust loendur omama peab, et ületäitumine toimuks 1 ms järel, on esitatud avaldise kujul ja omistatud muutujale //timer_start//. //F_CPU// on makro-keele konstant, mis näitab taktsagedust hertsides. Nimetatud taktsageduse puhul peaks loenduri väärtus 25,6 olema, kuid kuna murdarve kasutada ei saa, siis loenduri algväärtuseks saab 26. Siin tekib paraku ka viga viite ajas, kuid see on üsna väike (-1,7 μs). 
 + 
 +Tsüklis toimub loenduri algväärtustamine ja ületäitumise lipukese nullimine (sellesse 1 kirjutades). Seejärel oodataksekuni loendur loendab algväärtusest 256-ni, ehk ületäitumiseniÜletäitumise hetkel läheb ületäitumise lipuke kõrgeks ja 1 ms viide ongi toimunud. Funktsiooni lõpus taimer peatatakse.
  
 <code c> <code c>
-// +// Riistvaraline viide millisekundites ATmega kontrolleril
-// Riistvaraline viide millisekundites +
-//+
 void hw_delay_ms(unsigned short count) void hw_delay_ms(unsigned short count)
 {  {
Line 129: Line 142:
 </code> </code>
  
-Järgnevalt on toodud aga mõlemat liiki viite tekitamise funktsiooni praktiline harjutus, milles toimub kontrollerimooduli LED-i vilgutamine 1 sekundilise poolperioodiga. Ühel poolperioodil tekitab viidet tarkvaraline funktsioon, teisel taimer.+Esitatud viite funktsioon kasutab aga taimerite teekimille lähtekood ATmega kontrollerile näeb välja järgmine:
  
 <code c> <code c>
-// +// Taimer 0 taktijaguri valiku tüüp 
-// Kodulabori viite tekitamiste meetodite +typedef enum 
-// demonstratsioon-programm. +
-//+ TIMER0_NO_PRESCALE         = 0x01, 
 + TIMER0_PRESCALE_8          = 0x02, 
 + TIMER0_PRESCALE_32         = 0x03, 
 + TIMER0_PRESCALE_64         = 0x04, 
 + TIMER0_PRESCALE_128        = 0x05, 
 + TIMER0_PRESCALE_256        = 0x06, 
 + TIMER0_PRESCALE_1024       = 0x07 
 +
 +timer0_prescale; 
 + 
 +// Taimer 0 normaalrežiimi seadistamine 
 +inline void timer0_init_normal(timer0_prescale prescale) 
 +
 + TCCR0 = prescale & 0x07; 
 +
 +  
 +// Taimer 0 peatamine 
 +inline void timer0_stop() 
 +
 + TCCR0 = 0x00; 
 +
 + 
 +// Taimer 0 loenduri väärtuse määramine 
 +inline void timer0_set_value(unsigned char value) 
 +
 + TCNT0 = value; 
 +
 + 
 +// Taimer 0 ületäitumise lipukese nullimine 
 +inline void timer0_overflow_flag_clear(void) 
 +
 + bit_set(TIFR, TOV0); 
 +
 + 
 +// Taimer 0 ületäitumise lipukese oleku lugemine 
 +inline bool timer0_overflow_flag_is_set(void) 
 +
 + return (bit_is_set(TIFR, TOV0) ? true : false); 
 +
 +</code> 
 + 
 +Järgnevalt on toodud samasugune programm nagu tarkvaralise viite näiteskiLühemal 100 ms poolperioodil LED süüdatakse, pikemal 900 ms poolperioodil kustutatakse. Tulemusena vilgatab LED  iga sekundi järel. Paraku pole ka selles näites periood täpselt 1 sekund, sest programmi muude funktsioonide täitmine igas tsüklis võtab samuti aega. Täpseks ajastuseks tuleb kasutada 16-bitist taimerit koos katkestustega. 
 + 
 +<code c> 
 +// Kodulabori riistvaralise viite näidisprogramm 
 +// Programm vilgutab ~1 sekundi järel hetkeks LED-i (led_debug)
 #include <homelab/pin.h> #include <homelab/pin.h>
 #include <homelab/delay.h> #include <homelab/delay.h>
  
-// 
-// Test LED-i viigu määramine 
-// 
-pin debug_led = PIN(B, 7); 
- 
-// 
 // Põhiprogramm // Põhiprogramm
-// 
 int main(void) int main(void)
 { {
  // LED-i viigu väljundiks seadmine  // LED-i viigu väljundiks seadmine
- pin_setup_output(debug_led);+ pin_setup_output(led_debug);
  
  // Lõputu tsükkel   // Lõputu tsükkel
- while (true)+ while (1)
  {  {
- // LED-i põlema panek + // LED-i süütamine 
- pin_clear(debug_led);+ pin_clear(led_debug);
   
- // Tarkvaraline paus 1000 millisekundit + // Riistvaraline paus 100 millisekundit 
- sw_delay_ms(1000);+ hw_delay_ms(100);
  
  // LED-i kustutamine  // LED-i kustutamine
- pin_set(debug_led);+ pin_set(led_debug);
   
- // Riistvaraline paus 1000 millisekundit + // Riistvaraline paus 900 millisekundit 
- hw_delay_ms(1000);+ hw_delay_ms(900);
  }  }
 } }
 </code> </code>
- 
- 
et/examples/timer/delay.1259147769.txt.gz · Last modified: 2020/07/20 09:00 (external edit)
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0