Ankstesnėje mūsų pamokoje sužinojome apie šviesos diodo mirksėjimą naudojant PIC mikrovaldiklį ir pastatėme tą pačią grandinę ant „Perf“ plokštės. Tada mes panaudojome „ PICkit 3“, „ICSP“ ir „MPLAB IPE“, kad išmestume programą ant savo „Perf“ plokštės. Dabar šioje pamokoje mes pažadinsime save, kad galėtume naudoti daugiau kaiščių PIC mikrovaldiklyje. Mes naudosime 7 išėjimus (šviesos diodus) ir vieną įvestį. Šiai pamokai mes naudosime seną „Perf“ lentą (parodyta žemiau) ir pridėsime bergų lazdeles, kad ištrauktumėte reikiamus kaiščius ant antrosios LED plokštės. Šios pamokos pabaigoje sugeneruosime mirksinčių šviesos diodų seką naudodami PIC mikrovaldiklį PIC16F877A ir sužinosime, kaip naudotis keliais įėjimais ir išvestimis, kai kuriais pagrindais „už“ kilpa ir funkcijų iškvietimu.
Šviesos diodų plokštė yra ne kas kita, kaip kita perf plokštė, ant kurios mes lituosime šviesos diodus su srovę ribojančiu rezistoriumi (parodyta žemiau). Mes taip pat pridėsime mygtuką, kad pradėtų mirksėti sekos šviesos diodas.
Grandinės schema:
PIC mikrovaldiklis PIC16F877A LED mirksi sekos kodas ir darbo paaiškinimas:
Pilnas kodas buvo pateiktas žemiau (patikrinkite pabaigoje), čia mes gausime jį per eilutę. Paspaudus mygtuką, šis kodas pradės šviesti šviesos diodais nuosekliai. Norėdami suprasti sekas, žiūrėkite vaizdo įrašą mokymo programos pabaigoje. Aš rekomenduočiau jums palyginti vaizdo įraše rodomą išvestį su žemiau esančiu kodu ir pabandyti suprasti programą.
Pažvelkime į kodą eilutėmis. Pirmos kelios eilutės skirtos konfigūracijos bitams nustatyti, kurie buvo paaiškinti ankstesnėje pamokoje, todėl kol kas juos praleidžiu. Geriausias būdas suprasti bet kurią programą yra pradėti nuo pagrindinės ( void main () ) funkcijos, todėl padarykime tai
TRISB0 = 1; // Nurodykite MCU, kad PORTB kaištis 0 naudojamas kaip mygtuko įvestis. TRISD = 0x00; // Nurodykite MCU, kad visi kaiščiai būtų išvedami PORTD = 0x00; // Inicializuokite visus kaiščius iki 0
Žodis TRIS yra naudojamas apibrėžti, ar kaištis naudojamas kaip įvestis / išvestis, o žodis PORT naudojamas kaiščio aukštai / žemai formavimui. Linija TRISB0 = 1 padarys 0- ąjį PORT B kaištį kaip įvestį. Tai bus mūsų mygtukas. Linijos TRISD = 0x00; PORTD = 0x00; padarys visus D prievado kaiščius kaip išvestį ir priskirs tiems kaiščiams pradinę LOW vertę.
Kadangi mes pasakėme, kad B0 yra naudojamas kaip įvestis, mes sujungsime vieną mygtuko galą su kaiščiu B0, o kitą galą - su žeme. Tada, kai paspausime mygtuką, kaištis bus laikomas ant žemės, kaip parodyta aukščiau esančioje jungties schemoje. Bet kad tai įvyktų, turime naudoti traukimo varžą, kad kaištis būtų aukštai laikomas, kai mygtukas nebus paspaustas. Ištraukiamas rezistorius yra kažkas panašaus.
Tačiau mūsų PIC MCU turi vidinį silpną rezistorių, kurį programinė įranga gali suaktyvinti tokiu būdu sutaupydama daug rūpesčių (kai reikia prijungti daugiau mygtukų).
Kas yra silpnas traukiamasis rezistorius?
Yra dviejų tipų traukimo rezistoriai, vienas iš jų yra silpnas, kitas - stiprus. Silpni traukimo rezistoriai yra didelės vertės, todėl silpnai srovei gali tekėti, o stiprūs - aukštai, todėl stipri srovė gali tekėti. Visi MCU dažniausiai naudoja silpnus traukimo rezistorius. Norėdami tai suaktyvinti savo PIC MCU, turime ieškoti OPTION_REG (parinkčių registro) duomenų lapo, kaip parodyta žemiau esančioje nuotraukoje.
Kaip parodyta, 7 bitai yra susiję su silpnu rezistoriumi. Norint jį suaktyvinti, reikia padaryti nulį. Tai atlieka OPTION_REG <7> = 0 . Tai konkrečiai nagrinėja 7 bitą, paliekant kitiems bitams numatytąsias reikšmes. Tokiu būdu mes pateksime į „while“ kilpą, kur jis patikrins, ar mygtukas yra paspaustas naudojant if (RB0 == 0). Jei sąlyga yra įvykdyta, savo funkciją vadiname parametrais 1, 3, 7 ir 15.
sblink (1); // FUNCTION CALL 1 su parametru 1 sblink (3); // FUNCTION CALL 3 su 3 parametru sblink (7); // FUNCTION CALL 7 su 7 parametru sblink (15); // FUNCTION CALL 4 su 15 parametru
Kodėl mes naudojame funkcijas?
Funkcijos naudojamos sumažinti eilučių skaičių mūsų kode. Tai būtų žinoję dauguma iš mūsų. Bet kodėl turime sumažinti eilučių skaičių, ypač kai kalbama apie MCU programavimą. Priežastis yra ribota erdvė mūsų programos atminties. Jei netinkamai optimizuosime kodą, gali trūkti atminties. Tai bus naudinga, kai rašysime ilgus kodų puslapius.
Bet kuri funkcija turės funkciją Apibrėžimas ( sblink (int get) mūsų atveju) ir funkciją Call (mūsų atveju sblink (1) ). Neprivaloma turėti funkcijos deklaraciją, kad jos išvengčiau, prieš iškviesdamas funkciją į savo pagrindinę funkciją įdėjau savo funkcijos apibrėžimą.
Funkcijos parametrai yra vertė, kuri bus perduodama iš funkcijos iškvietimo į funkcijos apibrėžimą. Mūsų atveju sveikojo skaičiaus vertės (1, 3, 7, 15) yra parametrai, kurie perduodami iš funkcijos iškvietimo, o kintamasis „get“ parametrų vertę gauna į funkcijos apibrėžimą, kad jas apdorotų. Funkcija gali turėti daugiau nei vieną parametrą.
Iškvietus funkciją, bus vykdomos žemiau pateiktos funkcijos apibrėžimo eilutės.
už (int i = 0; i <= 7 && RB0 == 0; i ++) {PORTD = gauti << i; // LED judėjimas kairės sekos __delay_ms (50); } for (int i = 7; i> = 0 && RB0 == 0; i--) {PORTD = gauti << i; // LED judėjimas kairės sekos __delay_ms (50); }
Dabar ši eilutė atrodo nelyginė: PORTD = get << i . Aš paaiškinsiu, kas čia iš tikrųjų vyksta.
"<<" yra kairės poslinkio operatorius, kuris visus bitus perkelia į kairę padėtį. Dabar, kai mes vadiname funkciją „sblink“ („int get“) su parametru „1“ kaip „ sblink“ (1), tai reikš „get“ reikšmę kaip 1, kuri dvejetainėje reikšmėje yra 0b00000001. Taigi ši eilutė bus panaši į PORTD = 0b00000001 << i .
„I“ vertė svyruos nuo 0 iki 7, nes mes naudojome „for loop“ (int i = 0; i <= 7 && RB0 == 0; i ++). „I“ reikšmė nuo 0 iki 7 pakeis rezultatą taip:
Kaip matote, mes įjungėme po vieną šviesos diodą (iš kairės į dešinę), likę išjungti. Kitas „for loop“, skirtas (int i = 7; i> = 0 && RB0 == 0; i--) , taip pat padarys tą patį, bet šį kartą šviesos diodas bus įjungtas iš dešinės į kairę iš eilės, kai pradėjome nuo 7 ir leidome žemyn iki 0. Mes panaudojome 200ms vėlavimą, kad galėtume vizualizuoti įjungiamą ir išjungiamą šviesos diodą.
Dabar, kai perduosime 3 reikšmę „ sblink“ („int get“) funkcijoje, bus vykdoma funkcija „ sblink“ (3), dėl kurios „get“ reikšmė bus 0b00000011, taigi PORTD rezultatas bus:
Taigi dabar šį kartą du šviesos diodai bus įjungti bet kuriuo metu naudojant „ sblink“ (3). Panašiai kaip „ sblink“ (7) ir „ sblink“ (15), trys ir keturi šviesos diodai bus įjungti nuosekliai. Kai tai bus baigta, visi šviesos diodai bus įjungti, naudojant liniją PORTD = 0xFF . Norėdami pamatyti išsamią demonstraciją, patikrinkite toliau pateiktą vaizdo įrašą.
Tikimės, kad supratote kodą ir taip išmokote naudoti funkcijas „už“ ir „o“, norėdami gauti norimus rezultatus. Dabar galite pakoreguoti kodą, kad mirksi skirtinga LED seka. Kompiliuokite savo kodą ir išmeskite jį į savo MCU ir mėgaukitės išvestimi. Galite pasinaudoti komentarų skiltimi, jei kur nors užstrigote. Čia taip pat pridėjau modeliavimo ir programos failus.
Tai dabar mūsų kitoje pamokoje sužinosime, kaip naudoti PIC16F877A laikmačius, užuot naudojus uždelsimo funkcijas. Čia galite peržiūrėti visas PIC mikrovaldiklių pamokas.