- Kāpēc taimeris, kad mums ir kavēšanās ()?
- PIC mikrokontrolleru taimeri:
- Programmēšana un darba skaidrojums:
- Shēmas diagramma un Proteus simulācija:
Šī būs piektā apmācība mūsu PIC apmācību sērijā, kas palīdzēs jums iemācīties un izmantot taimerus PIC16F877A. Iepriekšējās apmācībās mēs bijām sākuši ar Ievads PIC un MPLABX IDE, pēc tam mēs uzrakstījām savu pirmo PIC programmu, lai mirgot LED, izmantojot PIC, un pēc tam izveidojām LED mirgojošu secību, izmantojot PIC mikrokontrollera aizkaves funkciju. Tagad izmantosim to pašu LED mirgojošo secību, kuru mēs izmantojām iepriekšējā apmācības aparatūrā, un ar to mēs iemācīsimies izmantot taimerus mūsu PIC MCU. Mēs tikko pievienojām vēl vienu pogu LED dēlī šai apmācībai. Lai uzzinātu vairāk, apmeklējiet apmācību.
Taimeri ir viens no svarīgiem iegultā programmētāja darba zirgiem. Katrā mūsu izstrādātajā lietojumprogrammā kaut kādā veidā būs iekļauta laika lietojuma programma, piemēram, kaut ko ieslēgt vai izslēgt pēc noteikta laika intervāla. Labi, bet kāpēc mums ir nepieciešami taimeri, kad mums jau ir kavēšanās makro (__delay_ms ()), kas dara to pašu !!
Kāpēc taimeris, kad mums ir kavēšanās ()?
Kavēšanās makro tiek saukta par “aizkavēšanās” aizkavi. Tā kā funkcijas Delay izpildes laikā MCU sēž dump, vienkārši izveidojot kavēšanos. Šī procesa laikā MCU nevar klausīties ADC vērtības vai lasīt neko no reģistriem. Tāpēc nav ieteicams izmantot aizkaves funkcijas, izņemot tādas lietojumprogrammas kā LED mirgo, kur laika aizkavei nav jābūt precīzai vai garai.
Kavēšanās makro ir arī īss atnākšanas laiks,
- Kavēšanās vērtībai jābūt konstantei aizkaves makro; programmas izpildes laikā to nevar mainīt. Tādējādi tas paliek programmētāja definēts.
- Kavēšanās nebūs precīza, salīdzinot ar Taimeru izmantošanu.
- Lielākas aizkavēšanās vērtības nevar izveidot, izmantojot makro, piemēram, aizkaves makro nevar izveidot pusstundas aizkavi. Maksimālā izmantojamā kavēšanās ir balstīta uz izmantoto kristāla oscilatoru.
PIC mikrokontrolleru taimeri:
Fiziski taimeris ir reģistrs, kura vērtība nepārtraukti palielinās līdz 255, un tad tas sākas no jauna: 0, 1, 2, 3, 4… 255…. 0, 1, 2, 3……tml.
PIC16F877A PIC MCU ir trīs taimeris moduļi. Tie ir nosaukumi Timer0, Timer1 un Timer2. Taimeris 0 un Taimeris 2 ir 8 bitu taimeri, bet 1. taimeris ir 16 bitu taimeris. Šajā apmācībā mēs izmantosim taimeri 0 mūsu lietojumprogrammai. Kad mēs sapratīsim taimeri 0, būs viegli strādāt arī ar 1. un 2. taimeri.
Timer0 moduļa taimerim / skaitītājam ir šādas funkcijas:
- 8 bitu taimeris / skaitītājs
- Lasāms un rakstāms
- 8 bitu programmatūras programmējams skaleris
- Iekšējā vai ārējā pulksteņa izvēle
- Pārtrauciet pārplūdi no FFh līdz 00h
- Malas izvēle ārējam pulkstenim
Lai sāktu lietot taimeri, mums vajadzētu saprast dažus izdomātus terminus, piemēram, 8 bitu / 16 bitu taimeri, Prescaler, Taimera pārtraukumus un Focs. Tagad apskatīsim, ko katrs īsti nozīmē. Kā jau minēts iepriekš, mūsu PIC MCU ir gan 8, gan 16 bitu taimeri, galvenā atšķirība starp tiem ir tā, ka 16 bitu taimera izšķirtspēja ir daudz labāka nekā 8 bitu taimera izšķirtspējai.
Prescaler ir nosaukums mikrokontrollerim, kas sadala oscilatora pulksteni, pirms tas sasniedz loģiku, kas palielina taimera statusu. Preskaler id diapazons ir no 1 līdz 256, un Prescaler vērtību var iestatīt, izmantojot OPTION reģistru (to pašu, ko mēs izmantojām pievilkšanas rezistoriem). Piemēram, ja vērtība prescaler ir 64, tad par katru 64 th pulsa Taimeris tiks palielina par 1.
Palielinoties taimerim un sasniedzot maksimālo vērtību 255, tas izraisīs pārtraukumu un atkal inicializēs 0. Šo pārtraukumu sauc par taimera pārtraukumu. Šis pārtraukums informē MCU, ka ir pagājis šis konkrētais laiks.
Fosc apzīmē biežums oscilatoru, tas ir biežums Crystal izmantota. Taimera reģistram nepieciešamais laiks ir atkarīgs no Prescaler vērtības un Fosc vērtības.
Programmēšana un darba skaidrojums:
Šajā apmācībā mēs iestatīsim divas pogas kā divas ieejas un 8 LED kā 8 izejas. Pirmo pogu izmantos, lai iestatītu laika aizkavi (500 ms par katru spiedienu), bet otro pogu izmantos, lai sāktu taimera secības mirgošanu. Piemēram, ja pirmā poga tiek nospiesta trīs reizes (500 * 3 = 1500 ms), aizkave tiks iestatīta 1,5 sekundes un, nospiežot divas pogas, katra gaismas diode ieslēgsies un izslēgsies ar iepriekš noteiktu laika aizkavi. Šīs apmācības beigās skatiet demonstrācijas video.
Tagad, paturot prātā šos pamatus, apskatīsim mūsu programmu, kas dota sadaļas Kods beigās.
Tas ir labi, ja jūs nesaņēmāt programmu, bet, ja jūs to izdarījāt !! Iedodiet sev sīkfailu un izgāžiet programmu, lai izbaudītu savu rezultātu. Citiem es sadalīšu programmu nozīmīgās daļās un paskaidrošu jums, kas notiek katrā blokā.
Kā vienmēr dažas pirmās koda rindas ir konfigurācijas iestatījumi un galvenes faili, es to neskaidrošu, jo to jau esmu izdarījis savās iepriekšējās apmācībās.
Pēc tam izlaidīsim visas līnijas un lecam tieši tukšajā galvenajā funkcijā, kuras iekšpusē mums ir PORT konfigurācija Timer0.
void main () {/ ***** Taima taimera porta konfigurācija ****** / OPTION_REG = 0b00000101; // Taimeris0 ar ārējo frekvenci un 64 kā preskalāru // Iespējo arī PULL UPs TMR0 = 100; // Ielādējiet laika vērtību 0,0019968s; delayValue var būt no 0 līdz 255 tikai TMR0IE = 1; // Iespējot taimera pārtraukuma bitu PIE1 reģistrā GIE = 1; // Iespējot globālo pārtraukumu PEIE = 1; // Iespējot perifēro traucējumu / *********** ______ *********** /
Lai to saprastu, mums jāaplūko OPTIC reģistrs mūsu PIC datu lapā.
Kā tika apspriests iepriekšējā apmācībā, bits 7 tiek izmantots, lai PORTB iespējotu vāju pretestību. Apskatiet iepriekšējo attēlu. Bits 3 tiek veidots kā 0, lai norādītu MCU, ka šāds iestatītais preskaler jāizmanto taimerim, nevis WatchDogTimer (WDT). Taimera režīms tiek izvēlēts, notīrot 5. bitu T0CS
(OPTION_REG <5>)
Tagad bits2-0 tiek izmantots, lai iestatītu taimera presskalera vērtību. Kā parādīts iepriekš tabulā, lai iestatītu preskalera vērtību 64, bitiem jābūt iestatītiem kā 101.
Pēc tam apskatīsim ar Timer0 saistītos reģistrus
Taimeris sāks pieaugt pēc iestatīšanas un pārpildes pēc 256 vērtības sasniegšanas, lai šajā laikā iespējotu taimera pārtraukumu, reģistram TMR0IE jābūt iestatītam augstam. Tā kā taimeris 0 pats par sevi ir perifērais, mums ir jāiespējo perifērā pārtraukšana, padarot PEIE = 1. Visbeidzot, mums ir jāiespējo globālais pārtraukums, lai MCU tiktu paziņots par pārtraukumu jebkuras darbības laikā, tas tiek darīts, padarot GIE = 1.
Kavēšanās = ((256-REG_val) * (Prescal * 4)) / Fosc
Iepriekš minēto formulu izmanto, lai aprēķinātu aizkavēšanās vērtību.
Kur
REG_val = 100;
Prescal = 64
Fosc = 20000000
Tas, aprēķinot, dod
Kavēšanās = 0,0019968s
Nākamais līniju kopums ir I / O pieslēgvietu iestatīšana.
/ ***** I / O porta konfigurācija ****** / TRISB0 = 1; // Norādiet MCU, ka PORTB tapa 0 tiek izmantota kā ievade pogai 1. TRISB1 = 1; // Norādiet MCU, ka PORTB 1. kontakts tiek izmantots kā ievade pogai 1. TRISD = 0x00; // Norādiet MCU, ka visas PORT D tapas tiek izvadītas PORTD = 0x00; // Inicializējiet visas tapas uz 0 / *********** ______ *********** /
Tas ir tāds pats kā iepriekšējā apmācībā, jo mēs izmantojam to pašu aparatūru. Izņemot to, ka kā ievadi esam pievienojuši vēl vienu pogu. To veic ar līniju TRISB1 = 1.
Tālāk, iekšpusē bezgalīgi, kamēr cilpa mums ir divi koda bloki. Vienu izmanto, lai saņemtu taimera ievadi no lietotāja, un otru, lai izpildītu aizkavēšanās secību virs gaismas diodēm. Es tos esmu izskaidrojis, izmantojot komentārus pret katru rindu.
kamēr (1) {skaits = 0; // Neveiciet taimera darbību galvenajā ciklā // ******* Saņemiet numura aizkavi no lietotāja **** ////// if (RB0 == 0 && flag == 0) // Kad dota ievade {get_scnds + = 1; // get_scnds = get_scnds + http: // Inkrementa mainīgā lielums = 1; } if (RB0 == 1) // Lai nepieļautu nepārtrauktu pieaugumu, = 0; / *********** ______ *********** /
Mainīgais, ko sauc get_scnds, tiek palielināts katru reizi, kad lietotājs nospiež pogu 1. Karoga (programmatūras definēts) mainīgais tiek izmantots pieauguma procesa turēšanai, līdz lietotājs noņem pirkstu no pogas.
// ******* Izpildiet secību ar aizkavi **** ////// while (RB1 == 0) {PORTD = 0b00000001 <
Nākamais bloks sāk darboties, ja tiek nospiesta otrā poga. Tā kā lietotājs jau ir definējis nepieciešamo laika aizkavi, izmantojot pirmo pogu, un tas ir saglabāts mainīgajā get_scnds. Mēs izmantojam mainīgo, ko sauc par hscnd, šo mainīgo kontrolē ISR (Interrupt service rutin).
Pārtraukt pakalpojumu rutīnas ir Pārtraukumi, kas tiks saukts katru reizi Timer0 ir pārplūst. Ļaujiet mums redzēt, kā to kontrolē ISR nākamajā blokā, piemēram, mēs vēlamies palielināt laika aizturi par pusi sekundes (0,5 sekundes) katrā pogas nospiešanā, tad mums jāpalielina mainīgais hscnd par katru pusi sekundes. Tā kā mēs esam ieprogrammējuši taimeri pārplūdei ik pēc 0,0019968 sekundēm (~ 2ms), tad, lai skaitītu pusi sekundes, skaitīšanas mainīgajam jābūt 250, jo 250 * 2ms = 0,5 sekunde. Tātad, kad skaitlis iegūst 250 (250 * 2 ms = 0,5 sekundes), tas nozīmē, ka tā ir bijusi puse sekundes, tāpēc mēs palielinām hscnd par 1 un inicializējam skaitli līdz nullei.
void break timer_isr () {if (TMR0IF == 1) // Taimera karodziņš ir aktivizēts taimera pārpildes dēļ {TMR0 = 100; // Ielādēt taimeri Vērtība TMR0IF = 0; // Notīrīt taimera pārtraukuma karodziņu skaitu ++; } ja (skaitīt == 250) {hscnd + = 1; // hscnd tiks palielināts par katru pussekundes skaitīšanu = 0; }}
Tāpēc mēs izmantojam šo vērtību un salīdzinām to ar mūsu hscnd un mainām mūsu LED, pamatojoties uz lietotāja noteikto laiku. Tas ir arī ļoti līdzīgs pēdējai apmācībai.
Tas ir tas, ka mūsu programma ir saprotama un darbojas.
Shēmas diagramma un Proteus simulācija:
Kā parasti, vispirms ļauj pārbaudīt izvadi, izmantojot Proteus, šeit esmu saistījis Proteus shematiskos failus.
Pievienojiet pogu mūsu iepriekšējam LED dēlim, un mūsu aparatūra ir gatava darbam. Tam vajadzētu izskatīties apmēram šādi:
Pēc savienojuma izveides augšupielādējiet kodu un pārbaudiet izvadi. Ja jums ir kādas problēmas, lūdzu, izmantojiet komentāru sadaļu. Pārbaudiet arī zemāk esošo videoklipu, lai saprastu visu procesu.