elemente practice in dezvoltarea sistemelor cu arduino uno-proiect 5

Upload: masinaaaaaaa

Post on 01-Jun-2018

217 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/9/2019 Elemente Practice in Dezvoltarea Sistemelor Cu Arduino UNO-Proiect 5

    1/15

    Elemente practice de bază în dezvoltarea sistemelor cu microprocesoare integrate

    45

    ProiectProiectProiectProiect 5555 –––– ButoaneButoaneButoaneButoane şşşşiiii sistemulsistemulsistemulsistemul dededede întreruperi întreruperi întreruperi întreruperi

    Conținutul lucrării pe scurt:•  Prezentarea modulului de interconectarea a unui buton la

    placa Arduino Uno•  Modalități de configurare a întreruperilor externe și a

     întreruperilor asociate mecanismelor de tip timer•  Exemplu de cronometru cu activare directă a sistemului de

     întreruperi

    Echipamente necesare lucrării:•  Placă de dezvoltare Arduino Uno sau compatibilă•  Cablu de conectare USB•  2 breadboard 30 pini sau 1 breadboard 60+ pini + fire de

    interconectare•  3 butoane, 3 rezistoare 10kohm, 3 condesatoare 100nF•  2 shift-register TPIC6B595•  2 rezistoare 220ohm•  Afișaj pe 7 segmente 2 caractere anod comun

    Secțiuni lucrare:•  Modalități de conectare a unui buton•  Modalități de manipulare software a intrărilor digitale•  Exemplu de manipulare software a intrărilor digitale•  Exemplu de numărător pe două caractere•  Exemplu de cronometru cu activare directă a

    sistemului de întreruperi

  • 8/9/2019 Elemente Practice in Dezvoltarea Sistemelor Cu Arduino UNO-Proiect 5

    2/15

    Elemente practice de b

    ModalitModalitModalitModalităţi deăţi deăţi deăţi de interconectareinterconectareinterconectareinterconectare

    Butoanele și comutatoarele (de intrări pentru un sistem e

    logic sau ”1” logic un pin de io comandă sau o condiție de

    Imaginea de mai jos prezintăintrare a plăcii Arduino (Butope ”0” logic – la apăsarea un”0” logic.

    Microcontrolerele Atmel AVRpull-up internă care poate fitrebui să fie configurat ca intrsă fie înscris 1). Din acest mla placa Arduino se poatrezistențe de pull-up externeurmătoare).

    Atenție!!! Conectarea directăplăcii Arduino fără activareapull-up internă poate distrudatorită curentului tranzitoriu

     închiderea contactului. Nu seastfel de schemă deoarece o

     în timpul dezvoltării poathardware.

    ză în dezvoltarea sistemelor cu microprocesoare in

    46

    a unui butona unui butona unui butona unui buton 

    utoane fără revenire) reprezintă cele maibedded. Astfel de dispozitive sunt capabil

    ntrare de uz general semnalizând în acestintrare.

    schema clasică de conectare a trei butoa1 – PIN2, Buton 2 – PIN3, Buton 3 – PI

    ui buton starea pin-ului de intrare va trece

    dispun de o rezistență derogramată software (pinulare și în registrul de ieșiretiv conectarea unui buton

    face direct fără unei(imaginea de pe pagina

    a unui buton la un pin alsoftware a rezistenței dege fizic pinul de intrarefoarte mare care apare larecomandă utilizarea uneisimplă omisiune software

    conduce la distrugeri

    egrate

    imple exemplesă tragă în ”0”

    mod sistemului

    e la trei pini de4) cu comandădin ”1” logic în

  • 8/9/2019 Elemente Practice in Dezvoltarea Sistemelor Cu Arduino UNO-Proiect 5

    3/15

    Elemente practice de b

    O altă problemă care apare îtip buton sau comutator esteimperfecțiunilor mecanice

     închiderea sau la deschiderede oscila ie a semnaluluieronată a comenzii (citire msituație se utilizează un conpentru a netezi semnalul dcelălalt.

    ză în dezvoltarea sistemelor cu microprocesoare in

    47

    cazul utilizării unei element defenomenul de bounce. Datorităale contactelor electrice laelementelor apare un fenomen

    are poate conduce la citireaultiplă). Pentru a evita aceastădensator (schema de mai jos)

    trecere dintr-un nivel logic în

    egrate

  • 8/9/2019 Elemente Practice in Dezvoltarea Sistemelor Cu Arduino UNO-Proiect 5

    4/15

    Elemente practice de bază în dezvoltarea sistemelor cu microprocesoare integrate

    48

    ModaliModaliModaliModalităţi de manipulare software a intrărilortăţi de manipulare software a intrărilortăţi de manipulare software a intrărilortăţi de manipulare software a intrărilor

    Mediul Arduino IDE pune la dispoziția programatorului funcția digitalRead(pin) care returnează starea pinului dorit. Pinul citit se poate configura în prealabil ca fiind de

    intrare pinMode(pin, INPUT)  dar având în vedere faptul că după reset toții piniimicrocontrolerului sunt configurați implicit ca intrări acest lucru nu este obligatoriu decât

     în cazul în care pinul respectiv a fost configurat anterior ca ieșire.

    Plecând de la schema din secțiunea anterioară (cu sau fără debouncing hardware – darcu rezistență externă de pull-up) se poate testa programul următorul program pentru oexemplificare a funcției digitalRead .

    const int buton1 = 2;

    const int buton2 = 3;

    const int buton3 = 4;

    int a1 = 0;

    int a2 = 0;

    int a3 = 0;

    void setup() {

    pinMode(buton1, INPUT);

    pinMode(buton2, INPUT);

    pinMode(buton3, INPUT);

    Serial.begin(9600);

    }

    void loop(){

    if (digitalRead(buton1) == LOW) {

    a1++;

    Serial.print("Butonul 1 s-a apasat butonul de ");

    Serial.print(a1,DEC);

    Serial.print(" ori.");

    Serial.println();

    //debouncing software

    delay(200);}

    if (digitalRead(buton2) == LOW) {

    a2++;Serial.print("Butonul 2 s-a apasat butonul de ");

    Serial.print(a2,DEC);

    Serial.print(" ori.");

    Serial.println();

    //debouncing software

    delay(200);}

  • 8/9/2019 Elemente Practice in Dezvoltarea Sistemelor Cu Arduino UNO-Proiect 5

    5/15

    Elemente practice de bază în dezvoltarea sistemelor cu microprocesoare integrate

    49

    if (digitalRead(buton3) == LOW) {

    a3++;

    Serial.print("Butonul 3 s-a apasat butonul de ");

    Serial.print(a3,DEC);

    Serial.print(" ori.");

    Serial.println();//debouncing software

    delay(200);

    }

    }

    Se observă că citirea celor trei butoane presupune o buclă infinită care verifică continuustarea pinilor la care sunt conectate cele trei butoane și afișează pe serială numărul deapăsări al fiecărui buton în parte. Se mai observă că programul introduce și undebouncing software (o mică întârziere după declanșarea fiecărei apăsări de buton)

    pentru a nu prinde evenimentul în mod eronat de mai multe ori. Se poate experimenta șiobserva efectul înlăturării debouncing-ului software

    O altă modalitate de a prinde un eveniment de tip închidere circuit / apăsare buton sepoate face și prin utilizarea întreruperilor externe. Mediul Arduino IDE pune la dispozițiaprogramatorului funcția attachInterrupt(întrerupere, isr_asociat, mod) care permite manipularea celor două întreruperi externe INT0 și INT1 alemicrocontrolerului. Din păcate acestea sunt singurele întreruperi care sunt accesibileprin intermediul limbajului de bază al mediului Arduino IDE. Butoanele trebuie să fieconectate la pinii 2 (INT0) și 3 (INT1) ai plăcii Arduino. Parametrii funcției sunt:

     întrerupere - 0 pentru INT0 și 1 pentru INT1, isr_asociat – numele unei proceduri caresă trateze apariția întreruperii și mod – specifică evenimentul extern la care să sedeclanșeze întreruperea LOW (pinul devine ”0” logic), FALLING (pinul trece din ”1” în”0”), RISING (pinul trece din ”0” în ”1”) sau CHANGE (orice tip de tranziție – la butonacest mod va conduce la declanșare dublă la fiecare apăsare). Funcția perechedetachInterrupt(întrerupere)  permite dezactivarea întreruperii activate cuajutorul funcției precedente. Pentru testarea celor două funcții se poate rula programulurmător utilizând aceiași schemă electrică – efectul programului este identic cu celprecedent.

    include

    const int buton3 = 4;

    volatile int a1 = 0;

    volatile int a2 = 0;

    int a3 = 0;

  • 8/9/2019 Elemente Practice in Dezvoltarea Sistemelor Cu Arduino UNO-Proiect 5

    6/15

    Elemente practice de bază în dezvoltarea sistemelor cu microprocesoare integrate

    50

    void setup() {

    attachInterrupt(0,ISR_b1,FALLING);

    attachInterrupt(1,ISR_b2,FALLING);

    Serial.begin(9600);

    }

    void loop(){

    if ((PIND & (1

  • 8/9/2019 Elemente Practice in Dezvoltarea Sistemelor Cu Arduino UNO-Proiect 5

    7/15

    Elemente practice de bază în dezvoltarea sistemelor cu microprocesoare integrate

    51

    •  Citirea butonului 3 nu se mai face cu ajutorul funcției digitalRead  descrisăanterior ci, direct, prin intermediul registrului intern PIND care stochează stareapinilor de intrare a portului D – pinul 4 al plăcii este conectat la pinul PD4 almicrocontrolerului (a se revedea lucrarea 3). Verificarea stării pinului 4 al plăciiconstă în verificarea stării bitului 4 din registrul PIND. Utilizarea alias-ului PINDnecesită includerea fișierului de definiții avr/io.h  . Acest mecanism se află înspatele implementării funcției digitalRead specifică mediului Arduino IDE. 

    Exemplu de activare directă a întreruperilor externeExemplu de activare directă a întreruperilor externeExemplu de activare directă a întreruperilor externeExemplu de activare directă a întreruperilor externe

    Placa de dezvoltare Arduino permite activarea tuturor pinilor I/O ca surse de întreruperiexterne. Este adevărat că spre deosebire de pinii 2 și 3 (INT0 și INT1) restul pinilor I/0

    (PCINTx) nu pot configura întreruperi externe declanșate de prinderea unui evenimentextern de tip front crescător, front descrescător sau zero logic (RISING, FALLING,LOW) ci doar de modificarea nivelului logic (CHANGE). Pentru a configura întreruperileexterne asociate cu alți pini decât 2 sau 3 este nevoie să configurăm în mod directregistrele interne ale microcontrolerului. Programul următor reface comportamentulprogramelor anterioare fără a apela la funcția attachInterrupt. Se vor utiliza trei

     întreruperi externe INT0 – pin 2 – buton 1, INT1 – pin 3 – buton 2, PCINT2 – pin4 =PCINT20 – buton 3.

    #include

    #include #include

    volatile int a1 = 0;

    volatile int a2 = 0;

    volatile int a3 = 0;

    void setup() {

    sei();

    EIMSK |= (1

  • 8/9/2019 Elemente Practice in Dezvoltarea Sistemelor Cu Arduino UNO-Proiect 5

    8/15

    Elemente practice de bază în dezvoltarea sistemelor cu microprocesoare integrate

    52

    Serial.print(a1,DEC);

    Serial.print(" ori.");

    Serial.println();

    Serial.print("Butonul 2 s-a apasat de ");

    Serial.print(a2,DEC);

    Serial.print(" ori.");Serial.println();

    Serial.print("Butonul 3 s-a apasat de ");

    Serial.print(a3,DEC);

    Serial.print(" ori.");

    Serial.println();

    delay(1000);

    }

    ISR(INT0_vect) {

    a1++;

    _delay_ms(400);}

    ISR(INT1_vect) {

    a2++;

    _delay_ms(400);

    }

    ISR(PCINT2_vect) {

    a3++;

    _delay_ms(1000);

    }

    Programul include fișierele de definiții avr/interrupt.h  [16] și avr/io.h pentru aputea utiliza denumirile registrelor și biților care sunt utilizați în configurarea sistemuluide întreruperi precum și a denumirii standard a subrutinelor de tratare a întreruperilor –ISR(INT_vect).

    Pentru activarea sistemului de întreruperi (la nivel global) se utilizează instrucțiuneasei(); care echivalează cu setarea bitului I în registrului intern SREG.

    Pentru activarea întreruperilor INT0 și INT1 se setează biții INT0 și INT1 din registrulintern EIMSK, de exemplu: EIMSK |= (1

  • 8/9/2019 Elemente Practice in Dezvoltarea Sistemelor Cu Arduino UNO-Proiect 5

    9/15

    Elemente practice de bază în dezvoltarea sistemelor cu microprocesoare integrate

    53

    de buton 3 va fi prinsă de două ori, lucru care poate fi evitat prin mărirea temporizării dedebounce software.

    Funcțiile ISR pentru cele trei întreruperi trebuie declarate de forma ISR(INT_vect) unde INT_vect va fi INT0_vect, INT1_vect, PCINT2_vect. [17]

     În cazul ISR-urilor reale (nu generate de mediul Arduino) sistemul de întreruperi estedezactivat pe durata execuției ISR-ului (pentru ca un ISR să nu întrerupă un alt ISR).Pentru a preveni blocarea programului (în ISR) nu trebuie folosite în cadrul unui ISRfuncțiile puse la dispoziție de mediul Arduino. De exemplu, utilizarea funcției delay încadrul unui ISR (pentru debouncing-ul software) va conduce la blocarea programuluideoarece această funcție utilizează întreruperea asociată timer-ului 0 – apelată într-uncontext de dezactivare a sistemului de întreruperi va introduce un delay infinit –

     întreruperea asociată timer-ului 0 nu se va declanșa niciodată. Această funcție poate fi înlocuită cu macro-ul _delay_ms(nr_ms) prezent în biblioteca util/delay.h .

    Exemplu de numărător pe două caractereExemplu de numărător pe două caractereExemplu de numărător pe două caractereExemplu de numărător pe două caractere

    Având în vedere cunoștințele noi prezentate vom încerca să implementăm unnumărător simplu cu ajutorul unui afișaj de două caractere pe 7 segmente. După resetafișajul va arăta 00, la fiecare apăsare a butonului 1 numărul se va incrementa(incrementarea din 99 va duce în 00), la fiecare apăsare a butonului 2 numărul de peafișaj se va decrementa (decrementarea din 00 va duce în 99), butonul 3 va resetanumărul la 00 (nu vom fi deranjați de declanșarea dublă a evenimentului având învedere că este o operație de reset).

    Schema electrică a numărătorului este prezentată în imaginea următoare. Se observăcă datorită utilizării a două registre de deplasare nu mai apare efectul de aprindereslabă a unor segmente în cazul afișării de cifre diferite pe cele două caractere – nu semai efectuează comanda prin intermediul aceluiași registru a celor două caractere.Comanda de aprindere a segmentelor este stabilă – fiecare caracter are propriulregistru.

  • 8/9/2019 Elemente Practice in Dezvoltarea Sistemelor Cu Arduino UNO-Proiect 5

    10/15

    Elemente practice de b ză în dezvoltarea sistemelor cu microprocesoare in

    54

    egrate

  • 8/9/2019 Elemente Practice in Dezvoltarea Sistemelor Cu Arduino UNO-Proiect 5

    11/15

    Elemente practice de bază în dezvoltarea sistemelor cu microprocesoare integrate

    55

    Pentru testarea montajului se utilizează următorul cod sursă:

    #include

    #include

    #include

    const int latchPin1 = 7;

    const int clockPin1 = 8;

    const int dataPin1 = 9;

    const int latchPin2 = 10;

    const int clockPin2 = 11;

    const int dataPin2 = 12;

    volatile int digit1 = 0;

    volatile int digit2 = 0;

    const int numbers[] = {63, 6, 91, 79, 102, 109, 125, 7, 127, 111};

    void setup() {

    //activare int0 si int1

    EIMSK |= (1

  • 8/9/2019 Elemente Practice in Dezvoltarea Sistemelor Cu Arduino UNO-Proiect 5

    12/15

    Elemente practice de bază în dezvoltarea sistemelor cu microprocesoare integrate

    56

    ISR(INT0_vect) {

    if (digit1==9) {

    if (digit2==9) {

    digit1=0;

    digit2=0;

    }else {

    digit1=0;

    digit2++;

    }

    }

    else digit1++;

    _delay_ms(400);

    }

    ISR(INT1_vect) {

    if (digit1==0) {if (digit2==0) {

    digit1=9;

    digit2=9;

    }

    else {

    digit1=9;

    digit2--;

    }

    }

    else digit1--;

    _delay_ms(400);}

    ISR(PCINT2_vect) {

    digit1 = 0;

    digit2 = 0;

    _delay_ms(400);

    }

    Exemplu de cronometru cu activare directă a sistemului de întreruperiExemplu de cronometru cu activare directă a sistemului de întreruperiExemplu de cronometru cu activare directă a sistemului de întreruperiExemplu de cronometru cu activare directă a sistemului de întreruperi

    La fel cum se pot activa întreruperile externe ale plăcii Arduino se pot utiliza șimecanismele de tip timer care au fost utilizate în cadrul lucrării anterioare prinintermediul unei biblioteci specializată – prin accesarea directă a registrelor interne deconfigurare a microcontroler-ului. Pentru a exemplifica acest lucru vom reface exemplucu cronometru din lucrarea precedentă utilizând schema de interconectare prezentatăanterior – pentru măsurarea independentă a duratei de o secundă nu vom utiliza

  • 8/9/2019 Elemente Practice in Dezvoltarea Sistemelor Cu Arduino UNO-Proiect 5

    13/15

    Elemente practice de bază în dezvoltarea sistemelor cu microprocesoare integrate

    57

    funcțiile bibliotecii TimerOne ci rutinele implicite asociate timer-ului intern 1.Funcționarea cronometrului va fi următoarea: numărătoarea se va face în zecimal (00-99), butonul 1 va porni cronometrul, butonul 2 va opri numărătoarea fără a ștergerezultatul astfel încât numărătoarea să poată fi reluată, butonul 3 va reseta numărul desecunde la 00 indiferent de modul de funcționare (oprit / pornit). Evenimentele asociatecelor trei butoane vor fi prinse similar ca și în cazul numărătorului (folosind întreruperi).Programul ce trebuie încărcat este următorul:

    #include

    #include

    #include

    const int latchPin1 = 7;

    const int clockPin1 = 8;

    const int dataPin1 = 9;

    const int latchPin2 = 10;const int clockPin2 = 11;

    const int dataPin2 = 12;

    volatile int digit1 = 0;

    volatile int digit2 = 0;

    const int numbers[] = {63, 6, 91, 79, 102, 109, 125, 7, 127, 111};

    void setup() {

    // activare intrerupere Timer1 overflow

    TIMSK1 = (1

  • 8/9/2019 Elemente Practice in Dezvoltarea Sistemelor Cu Arduino UNO-Proiect 5

    14/15

    Elemente practice de bază în dezvoltarea sistemelor cu microprocesoare integrate

    58

    void loop(){

    digitalWrite(latchPin1, LOW);

    shiftOut(dataPin1, clockPin1, MSBFIRST, numbers[digit1]);

    digitalWrite(latchPin1, HIGH);

    digitalWrite(latchPin2, LOW);shiftOut(dataPin2, clockPin2, MSBFIRST, numbers[digit2]);

    digitalWrite(latchPin2, HIGH);

    delay(1000); }

    ISR(TIMER1_OVF_vect) {

    if (digit1==9) {

    if (digit2==9) {

    digit1=0;

    digit2=0;

    }

    else {digit1=0;

    digit2++;

    }

    }

    else digit1++;

    }

    ISR(INT0_vect) {

    _delay_ms(400);

    //pornire timer FCPU/256

    TCCR1B |= (1

  • 8/9/2019 Elemente Practice in Dezvoltarea Sistemelor Cu Arduino UNO-Proiect 5

    15/15

    Elemente practice de bază în dezvoltarea sistemelor cu microprocesoare integrate

    59

    = 0. Parametrul INT_vect în funcția ISR pentru timer-ul 1 este TIMER1_OVF_vect.[18]

    Pentru ca timer-ul 1 să facă overflow la fiecare secundă trebuie calculat factorul descalare (divizare) în funcție de frecvența de ceas a microcontrolerului. La o frecvență de

    16MHz (cum este în cazul plăcii Arduino) se poate folosi un factor de scalare de 256care va produce overflow la fiecare 1.048576 secunde.

    Timp_overflow = Incrementări * (Frecv_CPU/factor_scalare)-1  = 65536 / (16000000 /256)