Krmiljenje LED diode (programski jezik c)

Za programe, napisane v programskem jeziku c bomo uporabljali prevajalnik (compiler) HI-Tech C Compiler (HTC, HI-TECH compiler for PIC10/12/16 MCUs V9.82). Dobimo ga skupaj s programskim okoljem MPLAB IDE ali pa si ga dodatno naložimo. Uporabljali ga bomo za programiranje 8-bitnih mikrokontrolerjev PIC serije 16f. Mi bomo uporabili PIC16f628a.

Naše okolje MPLAB IDE ima vgrajeno knjižnico prevajalnika HTC verzije 9.82.

Program v programskem jeziku c bomo napisali za enake zahteve, kot smo ga napisali za krmiljenje LED diode v assemblerju:

Program naj deluje po naslednjih zahtevah:

S tipko T1, priključeno na pin RA0, vklopimo svetlečo diodo, ki je priključena na pin RB0. Svetleča dioda sveti, dokler je s tipko T2, priključeno na pin RA2, ne izklopimo.

Slika 1: Priklop elementov na mikrokontroler

Kreiranje projekta v okolju MPLAB IDE:

Uporabili bomo čarovnika za kreiranje projekta. V menijski vrstici izberemo Project in izberemo Project Wizard ...

Slika 2: Kreiranje projekta s čarovnikom v okolju MPAB

S pritiskom na gumb Naprej se odpre okno, v katerem izberemo tip mikrokontrolerja:

Slika 3: Izbira mikrokontrolerja

Po pritisku na gumb Naprej se odpre okno, v katerem izberemo jezikovno orodje (language toolsuite). Mi izberemo prevajalnik HI-TECH Universal ToolSuite:

Slika 4: Izbira jezikovnega orodja

Po pritisku na gumb Naprej se odpre okno, v katerem določimo pot do izbrane mape projekta:

Slika 5: Pot do izbrane mape projekta

Po pritisku na gumb Naprej se odpre okno, v katerem dodajamo zahtevane datoteke. V našem primeru to ni potrebno. Po pritisku na gumb Naprej v oknu Summary dokončamo oblikovanje projekta s pritiskom na gumb Dokončaj.

Slika 6: Dokončanje oblikovanja projekta

Ko smo kreirali projekt ga hočemo videti, v menijski vrstici izberemo File in izberemo New. Odpre se nam okno, kamor bomo pisali programsko kodo, vendar ga moramo še prej shraniti in dodati v naš projekt. Zato v menijski vrstici še enkrat izberemo File in izberemo Save As. Shranimo ga pod izbranim imenom v mapo, kamor smo kreirali projekt. Ker bomo programsko kodo pisali v c-ju, moramo imenu obvezno dodati končnico .c (v našem primeru bomo izbrali Krmiljenje LED.c). Nato v okencu projekta z desnim klikom miške izberemo Source files in izberemo Add Files... Izberemo dokument, ki smo ga prej shranili, v našem primeru Krmiljenje LED.c. Ko je dokument dodan, lahko začnemo s pisanjem programske kode.

Program za krmiljenje svetleče diode s tipkama v c jeziku:

 /*

 Krmiljenje svetleče diode s tipkama

 Okolje MPLAB IDE v8.92, HI_TECH compiler for PIC10/12/16 MCUs V9.82, oscilator 4 MHz.

 Avtor: Milan Ivič, sept 2017

*/

  #include <htc.h>                     //Predprocesorska direktiva za Hi-Tech compiler

  #include <pic.h>                     //Predprocesorska direktiva ki vključuje potrebne datoteke za PIC16f628a

  #define _XTAL_FREQ 4000000           //Razglasitev konstante z direktivo #define => Kristalni oscilator 4 MHz

  __CONFIG (0x2129);                   //Konfiguracijski biti

  void main()

  {

    TRISA = 3;                         //RA0 in RA1 sta vhoda (3 dec = 00000011 bin)

    TRISB0 = 0;                        //RB0 je izhodni pin

    CMCON = 7;                         //Izklopimo komparatorje na PORTA

    RB0 = 0;                           //Inicializacija => Izklop LED diode

    do                                 //Zanka do-while

    {

      if(RA0 == 1 && RA1 == 0) //Ali je tipka T1 pritisnjena?

      {

        __delay_ms(5);                               //Zakasnitev zaradi odbijanja kontaktov

        if(RA0 == 1 && RA1 == 0) //Ali je tipka T1 še vedno pritisnjena?

        {

          RB0 = 1;                                   //Vklopi LED diodo

        }

      }

      if(RA1 == 1 && RA0 == 0)  //Ali je tipka T1 pritisnjena?

      {

        __delay_ms(5);                               //Zakasnitev zaradi odbijanja kontaktov

        if(RA1 == 1 && RA0 == 0)  //Ali je tipka T1 še vedno pritisnjena?

        {

          RB0 = 0;                                   //Izklopi LED diodo

        }

      }

    }

    while(1);

  }

Opis programa:

Programska koda se začne s komentarjem. Komentarji so del izvorne kode, ki jih prevajalnik ne upošteva. Namenjeni so programerju za vstavljanje opomb in opisov izvorne kode. C podpira dva načina vstavljanja komentarjev:

Prvi prikazuje vrstico s komentarjem, drugi pa blok s komentarjem. Vrstica s komentarjem se začne in konča v isti vrstici z dvema poševnicama (//). Blok komentarja se začne z /* in konča z */ in lahko zavmzema več vrstic.

S predprocesorsko direktivo #include <htc.h> smo vključili HI-TECH prevajalnik, s predprocesorsko direktivo #include <pic.h> pa potrebne datoteke za mikrokontroler PIC16f628a.

Z direktivo #define _XTAL_FREQ 4000000 smo razglasili konstanto za uporabo zunanjega kristalnega oscilatorja frekvence 4 MHz.

S konfiguracijskimi biti (__CONFIG (0x2129)) smo določili izklop zaščite pred kopiranjem, izklop stražnega mehanizma (watch dog timer), vklop stabilizacije oscilatorja, omogočena sta ponastavljanje (resetiranje) in uporaba pina RB4 ter uporaba zunanjega kristalnega oscilatorja. Konfiguracijske bite smo zapisali v heksadecimalnem številskem sistemu. Namesto __CONFIG (0x2129) bi lahko zapisali __CONFIG(WDTE_OFF & CP_OFF & FOSC_XT & PWRTE_ON & LVP_OFF).

Če heksadecimalno vrednost 2129(16) pretvorimo v binarno, dobimo 10000100101001(2). Poglejmo kaj predstavljajo te vrednosti v registru CONFIG:

Register CONFIG (RAM naslov: 2007h)

Tabela 1: Register CONF

Funkcija void main() je vstopna točka v program. Program se začne z zavitim oklepajem ({) za funkcijo void main() in konča s pripadajočim zavitim zaklepajem (}). Kar pišemo vmes, je naš program.

Najprej smo v funkciji void main() določili vhodne in izhodne pine mikrokontrolerja PIC16f628a:

Pina RA0 in RA1 morata biti vhodna pina, saj sta nanju priključeni tipki T1 in T2. Zato smo v register TRISA zapisali desetiško vrednost 3. Če pretvorimo desetiško vrednost 3 v dvojiško vrednost oziroma v šestnajstiško vrednost dobimo:

3(10) = 11(2) oziroma 00000011(2) oziroma 3(16).

Prvemu in drugemu bitu registra TRISA smo določili vrednost 1 in s tem določili, naj se obnašata kot vhodna pina.

Namesto TRISA = 3 bi lahko zapisali TRISA = 0b00000011 ali TRISA = 0x3. Prvi zapis je desetiški, drugi dvojiški tretji pa predstavlja šestnajstiški zapis v register TRISA. Ker je na pin RB0 priključena LED dioda, ga moramo določiti kot izhodni pin, zato mora biti vrednost prvega bita (bit 0) v registru TRISB enaka 0 (TRISB0 = 0).

Ker uporabljamo pina RA0 in RA1 kot digitalna pina (ko tipki nista sklenjeni imata ta dva pina vrednost 0, če sta tipki sklenjeni pa vrednost 1), moramo izklopiti komparatorje na PORTA. To storimo tako, da prvim trem bitom registra CMCON določimo vrednost 1.

Če med izvajanjem programa v oknu Watch opazujemo vrednost registra TRISA opazimo, da je vrednost šestega bita (bit 5) enaka 1. To je zato, ker smo s konfiguracijskimi biti omogočili delovanje ponastavitvenega (reset) vezja.

Slika 7: Prikaz vrednosti registrov v oknu Watch

Po začetnih nastavitvah se program izvaja v zanki do-while.

Zanka do-while (delaj dokler je)

Zanka do-while izvede blok, nato preveri, ali naj nadaljuje. Sintaksa je:

do blok while (izraz_pogoja);

Zanka je zelo podobna zanki while. Bistvena razlika med njima je, da se blok izvede pred preverjanjem pogoja. Torej se v vsakem primeru izvede najmanj enkrat.

Slika 8: Delovanje zanke do-while

V bloku do-while zanke preverjamo stanje obeh tipk, priključenih na pina RA0 in RA1. LED dioda se naj vklopi, če je sklenjena samo tipka, priključena na pin RA0. Če sta sklenjeni obe tipki, se LED dioda ne sme vklopiti. Z if stavkom in logičnim operatorjem IN (&&) preverjamo stanje obeh pinov:

if(RA0 == 1 && RA1 == 0)   //Ali je stanje na pinu RA0 enako 1 (tipka T1 sklenjena) in stanje na pinu RA1 enako 0 (tipka T2 ni sklenjena)?

Slika 9: Delovanje if stavka

Če je pogoj resničen, se izvede blok if stavka, če pa pogoj ni resničen, se blok if stavka ne izvede. Blok if stavka je ujet med zavita oklepaja. V if stavku imamo vgnezden drugi if stavek, v katerem po preteku 5 ms ponovno preverjamo stanje tipk. Če je na primer tipka T1 (RA0) sklenjena, tipka T2 (RA1) pa ni sklenjena, se v bloku if stavka najprej izvede zakasnitev 5 ms (__delay_ms(5);) zaradi odbijanja kontaktov na tipki (predpostavljamo da odbijanje kontaktov ne presega časa 5 ms). Po preteku časa 5 ms preverimo, ali je tipka T1 še vedno sklenjena (tipka T2 pa ni sklenjena). Če je, vklopimo LED diodo (RB0 = 1;), priključeno na pin RB0 (na pin RB0 pošljemo napetost 5 V). Enako z vgnezdenima if stavkoma storimo, če želimo s tipko T2 LED diodo izklopiti.

Logični operatorji:

V logičnih operatorjih se operanda primerjata po svoji logični vrednosti.

V jeziku C je logično resnično vse, kar nima vrednosti 0 ter logično neresnično vse, kar ima vrednost 0.

Logični podatki so takšni podatki, ki lahko imajo samo dve vrednosti, na primer da/ne, resnica/laž, dan/noč.

Za logične podatke pozna jezik C tri operatorje:

Operatorji primerjanja:

Z operatorji primerjanja primerjamo dva operanda. Vrednost operacije je logična vrednost true, če operanda zadostita pogoju primerjanja, sicer je vrednost false. Vrednost operacij z operatorji primerjanja je torej, tako kot pri logičnih operatorjih, vedno tipa bool.

Slika 10: Operatorji primerjanja