+ All Categories
Home > Documents > 00ac800e-b0bb-4763-8a6d-2e80be1a5764_lucrare5

00ac800e-b0bb-4763-8a6d-2e80be1a5764_lucrare5

Date post: 17-Dec-2015
Category:
Upload: prichindel-morocanos
View: 3 times
Download: 1 times
Share this document with a friend
14
Elemente practice de bază în dezvoltarea sistemelor cu microprocesoare integrate 49 Lucrare 5 – Butoane şi sistemul de întreruperi Conținutul lucrării pe scurt: Prezentarea modulului de conectarea a unui buton la placa Arduino Uno Modalități de configurare a întreruperilor externe Exemplu de numărător și cronometru cu butoane și activare directă a sistemului de întreruperi externe Echipamente necesare lucrării: Placă de dezvoltare Arduino Uno sau compatibilă Cablu de conectare USB 2 breadboard-uri 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 activare directă a întreruperilor externe Proiect numărător pe două caractere și trei butoane Proiect cronometru pe două caractere și trei butoane Referințe online
Transcript
  • Elemente practice de baz n dezvoltarea sistemelor cu microprocesoare integrate

    49

    Lucrare 5 Butoane i sistemul de ntreruperi

    Coninutul lucrrii pe scurt: Prezentarea modulului de conectarea a unui buton la placa

    Arduino Uno Modaliti de configurare a ntreruperilor externe Exemplu de numrtor i cronometru cu butoane i activare

    direct a sistemului de ntreruperi externe

    Echipamente necesare lucrrii:

    Plac de dezvoltare Arduino Uno sau compatibil Cablu de conectare USB 2 breadboard-uri 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 Afiaj pe 7 segmente 2 caractere anod comun

    Seciuni lucrare: Modaliti de conectare a unui buton Modaliti de manipulare software a intrrilor digitale Exemplu de activare direct a ntreruperilor externe Proiect numrtor pe dou caractere i trei butoane Proiect cronometru pe dou caractere i trei

    butoane Referine online

  • Elemente practice de baz n dezvoltarea sistemelor cu microprocesoare integrate

    50

    Modaliti de conectare a unui buton

    Butoanele i comutatoarele (butoane fr revenire) reprezint cele mai simple exemple de intrri pentru un sistem embedded. Astfel de dispozitive sunt capabile s trag n 0 logic sau 1 logic un pin de intrare de uz general semnaliznd n acest mod sistemului o comand sau o condiie de intrare.

    Imaginea de mai jos prezint schema clasic de conectare a trei butoane la trei pini de intrare a plcii Arduino (Buton 1 PIN2, Buton 2 PIN3, Buton 3 PIN4) cu comand pe 0 logic la apsarea unui buton starea pin-ului de intrare va trece din 1 logic n 0 logic.

    Microcontrolerele Atmel AVR dispun de o rezisten de pull-up intern care poate fi programat software (pinul trebui s fie configurat ca intrare i n registrul de ieire s fie nscris 1). Din acest motiv conectarea unui buton la placa Arduino se poate face direct fr unei rezistene de pull-up externe (imaginea de pe pagina urmtoare). Atenie!!! Conectarea direct a unui buton la un pin al plcii Arduino fr activarea software a rezistenei de pull-up intern poate distruge fizic pinul de intrare datorit curentului tranzitoriu foarte mare care apare la nchiderea contactului. Nu se recomand utilizarea unei astfel de schem deoarece o simpl omisiune software n timpul dezvoltrii poate conduce la distrugeri hardware.

  • Elemente practice de baz n dezvoltarea sistemelor cu microprocesoare integrate

    51

    O alt problem care apare n cazul utilizrii unei element de tip buton sau comutator este fenomenul de bounce. Datorit imperfeciunilor mecanice ale contactelor electrice la nchiderea sau la deschiderea elementelor apare un fenomen de oscilaie a semnalului care poate conduce la citirea eronat a comenzii (citire multipl). Pentru a evita aceast situaie se utilizeaz un condensator (schema de mai jos) pentru a netezi semnalul de trecere dintr-un nivel logic n cellalt.

  • Elemente practice de baz n dezvoltarea sistemelor cu microprocesoare integrate

    52

    Modaliti de manipulare software a intrrilor

    Mediul Arduino IDE pune la dispoziia programatorului funcia digitalRead(pin) care returneaz starea pinului dorit. Pinul citit se poate configura n prealabil ca fiind de intrare pinMode(pin, INPUT) dar avnd n vedere faptul c dup reset toii pinii microcontrolerului sunt configurai implicit ca intrri acest lucru nu este obligatoriu dect n cazul n care pinul respectiv a fost configurat anterior ca ieire.

    Plecnd de la schema din seciunea anterioar (cu sau fr debouncing hardware dar cu rezisten extern de pull-up) se poate testa programul urmtorul program pentru o exemplificare a funciei 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);}

  • Elemente practice de baz n dezvoltarea sistemelor cu microprocesoare integrate

    53

    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 continuu starea pinilor la care sunt conectate cele trei butoane i afieaz pe serial numrul de apsri al fiecrui buton n parte. Se mai observ c programul introduce i un debouncing software (o mic ntrziere dup declanarea fiecrei apsri de buton) pentru a nu prinde evenimentul n mod eronat de mai multe ori. Se poate experimenta i observa efectul nlturrii debouncing-ului software.

    O alt modalitate de a prinde un eveniment de tip nchidere circuit / apsare buton se poate face i prin utilizarea ntreruperilor externe. Mediul Arduino IDE pune la dispoziia programatorului funcia attachInterrupt(ntrerupere, isr_asociat, mod) care permite manipularea celor dou ntreruperi externe INT0 i INT1 ale microcontrolerului. Din pcate acestea sunt singurele ntreruperi care sunt accesibile prin intermediul limbajului de baz al mediului Arduino IDE. Butoanele trebuie s fie conectate la pinii 2 (INT0) i 3 (INT1) ai plcii Arduino. Parametrii funciei sunt: ntrerupere - 0 pentru INT0 i 1 pentru INT1, isr_asociat numele unei proceduri care s trateze apariia ntreruperii i mod specific evenimentul extern la care s se declaneze 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 tranziie la buton acest mod va conduce la declanare dubl la fiecare apsare). Funcia pereche detachInterrupt(ntrerupere) permite dezactivarea ntreruperii activate cu ajutorul funciei precedente. Pentru testarea celor dou funcii se poate rula programul urmtor utiliznd aceiai schem electric efectul programului este identic cu cel precedent.

    const int buton3 = 4;

    volatile int a1 = 0;

    volatile int a2 = 0;

    int a3 = 0;

    void setup() {

    attachInterrupt(0,ISR_b1,FALLING);

  • Elemente practice de baz n dezvoltarea sistemelor cu microprocesoare integrate

    54

    attachInterrupt(1,ISR_b2,FALLING);

    Serial.begin(9600);

    }

    void loop(){

    if ((PIND & (1

  • Elemente practice de baz n dezvoltarea sistemelor cu microprocesoare integrate

    55

    microcontrolerului (a se revedea lucrarea 3). Verificarea strii pinului 4 al plcii const n verificarea strii bitului 4 din registrul PIND. Acest mecanism se afl n spatele implementrii funciei digitalRead specific mediului Arduino IDE.

    Exemplu de activare direct a ntreruperilor externe

    Placa de dezvoltare Arduino permite activarea tuturor pinilor I/O ca surse de ntreruperi externe. Este adevrat c spre deosebire de pinii 2 i 3 (INT0 i INT1) restul pinilor I/0 (PCINTx) nu pot configura ntreruperi externe declanate de prinderea unui eveniment extern de tip front cresctor, front descresctor sau zero logic (RISING, FALLING, LOW) ci doar de modificarea nivelului logic (CHANGE). Pentru a configura ntreruperile externe asociate cu ali pini dect 2 sau 3 este nevoie s configurm n mod direct registrele interne ale microcontrolerului. Programul urmtor reface comportamentul programelor anterioare fr a apela la funcia attachInterrupt. Se vor utiliza trei ntreruperi externe INT0 pin 2 buton 1, INT1 pin 3 buton 2, PCINT2 pin4 = PCINT20 buton 3. Pentru mai mult informaii legate de configurarea direct a sistemului de ntreruperi se poate consulta [1].

    #include

    volatile int a1 = 0;

    volatile int a2 = 0;

    volatile int a3 = 0;

    void setup() {

    EIMSK |= (1

  • Elemente practice de baz n dezvoltarea sistemelor cu microprocesoare integrate

    56

    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(400); }

    Pentru activarea ntreruperilor INT0 i INT1 se seteaz biii INT0 i INT1 din registrul intern EIMSK, de exemplu: EIMSK |= (1

  • Elemente practice de baz n dezvoltarea sistemelor cu microprocesoare integrate

    57

    Proiect numrtor pe dou caractere i trei butoane

    Avnd n vedere cunotinele noi prezentate vom ncerca s implementm un numrtor simplu cu ajutorul unui afiaj de dou caractere pe 7 segmente. Dup reset afiajul va arta 00, la fiecare apsare a butonului 1 numrul se va incrementa (incrementarea din 99 va duce n 00), la fiecare apsare a butonului 2 numrul de pe afiaj se va decrementa (decrementarea din 00 va duce n 99), butonul 3 va reseta numrul la 00 (nu vom fi deranjai de declanarea dubl a evenimentului avnd n vedere c este o operaie de reset). Schema electric a numrtorului este prezentat n imaginea urmtoare. Se observ c datorit utilizrii a dou registre de deplasare nu mai apare efectul de aprindere slab a unor segmente n cazul afirii de cifre diferite pe cele dou caractere nu se mai efectueaz comanda prin intermediul aceluiai registru a celor dou caractere. Comanda de aprindere a segmentelor este stabil fiecare caracter are propriul registru.

    Pentru testarea montajului se utilizeaz urmtorul cod surs:

    #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

  • Elemente practice de baz n dezvoltarea sistemelor cu microprocesoare integrate

    Elemente practice de baz n dezvoltarea sistemelor cu microprocesoare integrate

    58

    Elemente practice de baz n dezvoltarea sistemelor cu microprocesoare integrate

  • Elemente practice de baz n dezvoltarea sistemelor cu microprocesoare integrate

    59

    pinMode(latchPin1, OUTPUT);

    pinMode(dataPin1, OUTPUT);

    pinMode(clockPin1, OUTPUT);

    pinMode(latchPin2, OUTPUT);

    pinMode(dataPin2, OUTPUT);

    pinMode(clockPin2, OUTPUT);

    }

    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(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);}

  • Elemente practice de baz n dezvoltarea sistemelor cu microprocesoare integrate

    60

    ISR(PCINT2_vect) {

    digit1 = 0;

    digit2 = 0;

    _delay_ms(400); }

    Proiect cronometru pe dou caractere i trei butoane

    Utiliznd schema precedent vom implementa un sistem de tip cronometru. Funcionarea cronometrului va fi urmtoarea: numrtoarea se va face n zecimal (00-99), butonul 1 va porni cronometrul, butonul 2 va opri numrtoarea fr a terge rezultatul astfel nct numrtoarea s poat fi reluat, butonul 3 va reseta numrul de secunde la 00 indiferent de modul de funcionare (oprit / pornit). Evenimentele asociate celor trei butoane vor fi prinse similar ca i n cazul numrtorului (folosind ntreruperi). Programul ce trebuie ncrcat este urmtorul:

    #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

  • Elemente practice de baz n dezvoltarea sistemelor cu microprocesoare integrate

    61

    pinMode(latchPin1, OUTPUT);

    pinMode(dataPin1, OUTPUT);

    pinMode(clockPin1, OUTPUT);

    pinMode(latchPin2, OUTPUT);

    pinMode(dataPin2, OUTPUT);

    pinMode(clockPin2, OUTPUT); }

    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++;

    TCNT1 = 0x0BDC;

    }

    ISR(INT0_vect) {

    _delay_ms(400);

    TCNT1 = 0x0BDC;

    //pornire timer FCPU/256

    TCCR1B |= (1

  • Elemente practice de baz n dezvoltarea sistemelor cu microprocesoare integrate

    62

    Referine online

    [1] : Interrupts http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html [2] We interrupt this program to bring you a tutorial on Arduino interrupts http://www.engblaze.com/we-interrupt-this-program-to-bring-you-a-tutorial-on-arduino-interrupts/