- Kodėl laikmatis, kai mes vėluojame ()?
- PIC mikrovaldiklio laikmačiai:
- Programavimas ir darbo paaiškinimas:
- Grandinės schema ir „Proteus“ modeliavimas:
Tai bus penktoji „ PIC Tutorial Series“ pamoka, kuri padės jums išmokti ir naudoti „PIC16F877A“ laikmačius. Ankstesnėse mūsų pamokose mes buvome pradėję nuo „PIC“ ir „MPLABX IDE“ įvado, tada parašėme savo pirmąją „PIC“ programą, kad mirksėtų šviesos diodas, naudodamas PIC, tada sukūrėme šviesos diodų mirksėjimo seką, naudodami „PIC“ mikrovaldiklio vėlavimo funkciją. Dabar naudokime tą pačią šviesos diodų mirksėjimo seką, kurią naudojome ankstesnėje mokymo programinėje įrangoje, ir tai sužinosime, kaip naudoti laikmačius mūsų PIC MCU. Šiai pamokai ką tik pridėjome dar vieną mygtuką LED lentoje. Peržiūrėkite mokymo programą, kad sužinotumėte daugiau.
Laikmačiai yra vienas iš svarbiausių įterptojo programuotojo darbo arkliukų. Kiekviena programa, kurią mes suprojektuosime, kažkaip apims laiko nustatymo programą, pvz., Įjungiant arba išjungiant kažką po nustatyto laiko intervalo. Gerai, bet kam mums reikalingi laikmačiai, kai jau turime uždelsimo makrokomandas (__delay_ms ()), darančius tą patį !!
Kodėl laikmatis, kai mes vėluojame ()?
„Delay“ makrokomanda vadinama „dump“ vėlavimu. Nes vykdant „Delay“ funkciją MCU sėdi „dump“ tiesiog sukurdamas uždelsimą. Šio proceso metu MCU negali klausytis savo ADC reikšmių ir nieko neskaityti iš savo registrų. Todėl nerekomenduojama naudoti uždelsimo funkcijų, išskyrus tokias programas kaip LED mirksi, kai laiko uždelsimas neturi būti tikslus ar ilgas.
Vėlavimo makrokomandose taip pat netrukus pasirodys:
- Vėlavimo vertė turi būti pastovi vėlavimo makrokomandoms; jo negalima pakeisti vykdant programą. Taigi jis lieka programuotojo apibrėžtas.
- Vėlavimas nebus tikslus, palyginti su laikmačių naudojimu.
- Didesnių vėlavimų reikšmių negalima sukurti naudojant makrokomandas, pavyzdžiui, vėlavimo makrokomandos negali sukurti pusės valandos vėlavimo. Didžiausias vėlavimas, kurį galima naudoti, pagrįstas naudojamu kristalų osciliatoriumi.
PIC mikrovaldiklio laikmačiai:
Fiziškai laikmatis yra registras, kurio vertė nuolat didėja iki 255, o tada viskas prasideda iš naujo: 0, 1, 2, 3, 4… 255…. 0, 1, 2, 3……tml.
PIC16F877A IPS MCU turi tris Laikmačių moduliai. Tai pavadinimai „Timer0“, „Timer1“ ir „Timer2“. „Timer 0“ ir „Timer 2“ yra 8 bitų laikmačiai, o „Timer 1“ yra 16 bitų laikmačiai. Šioje pamokoje savo programai naudosime laikmatį 0. Kai suprasime „Timer 0“, bus lengva dirbti ir su „Timer 1“ ir „Timer 2“.
„Timer0“ modulio laikmatis / skaitiklis turi šias funkcijas:
- 8 bitų laikmatis / skaitiklis
- Skaitytinas ir rašomas
- 8 bitų programuojamas programinis preskaleris
- Pasirinkite vidinį arba išorinį laikrodį
- Nutraukite perpildymą nuo FFh iki 00h
- Išorinio laikrodžio krašto pasirinkimas
Norėdami pradėti naudoti laikmatį, turėtume suprasti keletą išgalvotų terminų, tokių kaip 8 bitų / 16 bitų laikmatis, „Prescaler“, „Timer“ pertraukimai ir „Focs“. Dabar pažiūrėkime, ką kiekvienas iš tikrųjų reiškia. Kaip minėta anksčiau, mūsų PIC MCU yra tiek 8, tiek 16 bitų laikmačiai, pagrindinis skirtumas tarp jų yra tas, kad 16 bitų laikmačio skiriamoji geba yra daug geresnė nei 8 bitų laikmačio.
„Prescaler“ yra mikrovaldiklio dalis, padalijanti osciliatoriaus laikrodį, kol ji pasieks logiką, kuri padidina laikmačio būseną. Preskalerio ID diapazonas yra nuo 1 iki 256, o preskalerio vertę galima nustatyti naudojant „OPTION“ registrą (tą patį, kurį naudojome traukiant rezistorius). Pvz., Jei išankstinio skalavimo priemonės vertė yra 64, tada už kiekvieną 64 -ąjį impulsą laikmatis bus padidintas 1.
Laikmatiui didėjant ir pasiekus maksimalią 255 vertę, jis suaktyvins pertraukimą ir vėl pradės veikti į 0. Šis pertraukimas vadinamas laikmačio pertraukimu. Šis pertraukimas praneša MCU, kad šis laikas praleido.
„ Fosc“ reiškia osciliatoriaus dažnį, tai yra naudojamo kristalo dažnis. Laikmačio registravimo laikas priklauso nuo „Prescaler“ vertės ir „Fosc“ vertės.
Programavimas ir darbo paaiškinimas:
Šioje pamokoje mes nustatysime du mygtukus kaip du įėjimus ir 8 LED kaip 8 išėjimus. Pirmasis mygtukas bus naudojamas laiko atidėjimui nustatyti (500 ms už kiekvieną paspaudimą), o antrasis mygtukas bus naudojamas mirksint laikmačio sekai. Pvz., Jei pirmasis mygtukas paspaudžiamas tris kartus (500 * 3 = 1500ms), uždelsimas bus nustatytas 1,5 sek., O paspaudus mygtuką du kiekvienas šviesos diodas įsijungs ir išsijungs iš anksto nustatytu laiko atidėjimu. Patikrinkite demonstracinį vaizdo įrašą šios pamokos pabaigoje.
Dabar, turėdami omenyje šiuos pagrindus, pažvelkime į savo programą, pateiktą skyriaus Kodas pabaigoje.
Gerai, jei negavote programos, bet jei gavote !! Duokite sau slapuką ir išleiskite programą, kad galėtumėte mėgautis savo rezultatais. Kitiems aš padalysiu programą į prasmingas dalis ir paaiškinsiu, kas vyksta kiekviename bloke.
Kaip visada pirmosios kodo eilutės yra konfigūracijos nustatymai ir antraštės failai, aš to neketinu paaiškinti, nes tai jau padariau ankstesnėse mokymo programose.
Tada praleiskime visas eilutes ir pereikime tiesiai į tuščią pagrindinę funkciją, kurios viduje turime „Timer0“ PORT konfigūraciją.
void main () {/ ***** laikmačio prievado konfigūracija ****** / OPTION_REG = 0b00000101; // „Timer0“ su išoriniu dažniu ir 64 kaip išankstinis skalė // Taip pat įgalina PULL UPs TMR0 = 100; // Įkelti laiko vertę 0,0019968s; „delayValue“ gali būti tik tarp 0–256 TMR0IE = 1; // Įjungti laikmačio pertraukimo bitą PIE1 registre GIE = 1; // Įgalinti visuotinį pertraukimą PEIE = 1; // Įgalinti periferinį pertraukimą / *********** ______ *********** /
Norėdami tai suprasti, turime pažvelgti į OPTIC registrą savo PIC duomenų lape.
Kaip aptarta ankstesnėje pamokoje, 7 bitas naudojamas norint įjungti silpną PORTB rezistorių. Pažvelkite į aukščiau pateiktą paveikslėlį. 3 bitas yra padarytas 0, kad nurodytų MCU, kad šis nustatomas išankstinis skaleris turėtų būti naudojamas laikmačiui, o ne „WatchDogTimer“ (WDT). Laikmačio režimas pasirenkamas išvalius 5 bitą T0CS
(OPTION_REG <5>)
Dabar „ bits2-0 “ naudojamas laikmačio išankstinio skalerio vertei nustatyti. Kaip parodyta aukščiau esančioje lentelėje, kad nustatytumėte išankstinio skalavimo priemonės vertę 64, bitai turi būti nustatyti kaip 101.
Tada pažvelkime į „Timer0“ susietus registrus
Laikmatis pradės didėti, kai bus nustatytas, ir perpildys pasiekęs 256 vertę, kad įjungtų laikmačio pertraukimą šiuo metu, registras TMR0IE turi būti nustatytas aukštai. Kadangi pats laikmatis 0 yra periferinis įrenginys, turime įjungti periferinį pertraukimą nustatydami PEIE = 1. Galiausiai turime įgalinti visuotinį pertraukimą, kad bet kurios operacijos metu MCU būtų pranešta apie pertraukimą, tai daroma padarius GIE = 1.
Vėlavimas = ((256-REG_val) * (Prescal * 4)) / Fosc
Pirmiau pateikta formulė naudojama vėlavimo vertei apskaičiuoti.
Kur
REG_val = 100;
Prescal = 64
Fosc = 20000000
Tai apskaičiuojant suteikia:
Vėlavimas = 0,0019968s
Kitas eilučių rinkinys - nustatyti įvesties / išvesties prievadus.
/ ***** prievado konfigūracija I / O ****** / TRISB0 = 1; // Nurodykite MCU, kad PORTB kaištis 0 naudojamas kaip 1 mygtuko įvestis. TRISB1 = 1; // Nurodykite MCU, kad 1 mygtukas PORTB naudojamas kaip mygtuko 1 įvestis. TRISD = 0x00; // Nurodykite MCU, kad visi PORT D kaiščiai būtų išvedami PORTD = 0x00; // Inicializuokite visus kaiščius į 0 / *********** ______ *********** /
Tai tas pats, kas mūsų ankstesnėje mokymo programoje, nes naudojame tą pačią aparatinę įrangą. Išskyrus tai, kad mes įvedėme dar vieną mygtuką. Tai atliekama tiese TRISB1 = 1.
Toliau, begalinis, o ciklas, viduje - du kodo blokai. Vienas naudojamas gauti laikmačio įvestį iš vartotojo, o kitas - atidėjimo per šviesos diodus sekai įvykdyti. Aš juos paaiškinau naudodamas komentarus prie kiekvienos eilutės.
o (1) {skaičius = 0; // Neleiskite laikmačio esant pagrindinei grandinei // ******* Gaukite numerio vėlavimą iš vartotojo **** ////// if (RB0 == 0 && flag == 0) // pateiktas įvestis {get_scnds + = 1; // get_scnds = get_scnds + http: // Prieaugio kintamojo vėliava = 1; } if (RB0 == 1) // Norėdami išvengti nepertraukiamo prieaugio žymėjimo = 0; / *********** ______ *********** /
Kintamasis, vadinamas get_scnds, didinamas kiekvieną kartą, kai vartotojas paspaudžia mygtuką 1. Vėliava (programinės įrangos apibrėžtas) kintamasis naudojamas palaikyti prieaugio procesą, kol vartotojas pašalins pirštą nuo mygtuko.
// ******* Vykdykite seką vėluodami **** ////// while (RB1 == 0) {PORTD = 0b00000001 <
Kitas mygtukas pradeda veikti, jei paspaudžiamas antrasis mygtukas. Kadangi vartotojas jau nustatė reikiamą laiko atidėjimą naudodamas pirmąjį mygtuką ir jis buvo išsaugotas kintamajame get_scnds. Mes naudojame kintamąjį, vadinamą hscnd, šį kintamąjį valdo ISR (Interrupt service rutin).
Nutraukti paslaugų rutina yra Nutraukti kad bus vadinamas kiekvieną kartą Timer0 lankosi perpildymo. Pažiūrėkime, kaip jį valdo ISR kitame bloke, kaip kad mes norėtume padidinti kiekvieno laiko paspaudimą puse sekundės (0,5 s) kiekvieną kartą paspaudę mygtuką, tada mes turime padidinti kintamąjį hscnd kiekvienai pusei sekundės. Kadangi mes užprogramavome laikmatį per dideliam srautui kas 0,0019968 s (~ 2ms), skaičiuojant pusę sekundės skaičiuojamasis kintamasis turėtų būti 250, nes 250 * 2ms = 0,5 sekundės. Taigi, kai skaičius gaunamas 250 (250 * 2ms = 0,5 sekundės), tai reiškia, kad praėjo pusė sekundės, todėl mes padidiname hscnd 1 ir inicijuojame skaičių iki nulio.
void pertraukimo laikmatis_isr () {if (TMR0IF == 1) // Laikmačio vėliava suveikė dėl laikmačio perpildymo {TMR0 = 100; // Įkelti laikmatį Reikšmė TMR0IF = 0; // Išvalyti laikmačio pertraukimo vėliavų skaičių ++; } if (skaičius == 250) {hscnd + = 1; // hscnd bus padidintas už kiekvieną pusę sekundės = 0; }}
Taigi mes naudojame šią vertę ir palyginame ją su mūsų hscnd ir keičiame savo šviesos diodą pagal vartotojo nustatytą laiką. Tai taip pat labai panaši į paskutinę pamoką.
Štai ką mes supratome ir dirbame savo programą.
Grandinės schema ir „Proteus“ modeliavimas:
Kaip įprasta, pirmiausia galite patikrinti išvestį naudodami „Proteus“, aš čia susiečiau „Proteus“ scheminius failus.
Pridėkite mygtuką prie mūsų ankstesnės LED plokštės ir mūsų aparatinė įranga yra paruošta naudoti. Tai turėtų atrodyti maždaug taip:
Atlikus ryšį, įkelkite kodą ir patikrinkite išvestį. Jei turite kokių nors problemų, naudokite komentarų skyrių. Taip pat patikrinkite toliau pateiktą vaizdo įrašą, kad suprastumėte visą procesą.