Jump to content
ELFORUM - Forumul electronistilor
mmihai94

PIC + Keypad + Afisaj 7 segmente

Recommended Posts

Va salut.

Ma chinui de cateva ore sa imi dau seama cum trebuie sa fac afisarea unui cod citit de la keypad si afisat pe 4 afisaje cu 7 segmente. Pana acum am reusit sa citesc cate o valoare de la keypad, dar nu reusesc sa fac multiplexarea astfel incat atunci cand citesc o noua valoarea sa imi mute pe cea veche pe digitul urmator. Acum imi rescrie digitul 0. Nu stiu cum sa mut valoarea pe digitul urmator. Sau ar mai fi varianta sa citesc o valoare si sa o puna pe digitul 3, urmatoarea pe 2.... Oricum, in codul meu sunt mai multe probleme, una este ca afisarea este in bucla do-while si din cauza asta va face doar o afisare dupa care va astepta sa citeasca o noua valoare de la keypad. Cum fac sa afisez codul citit pe afisaje? Cred ca afisarea trebuie facuta cu o functie, dar nu stiu cum.... Dati-mi niste sfaturi, idei, ca eu deja am incercat toate ideile pe care le-am avut, dar nici una nu a mers. Nu stiu daca am dat toate detaliile, daca mai aveti nevoie de ceva intrebati-ma.

 

 

post-208062-0-94948500-1461609936_thumb.png

post-208062-0-16701800-1461609944_thumb.png

mikroC files.rar

Proteus.rar

Link to post
Share on other sites

Salut!

 

Varibila "nr" este una singura. In secventa:

    PORTA = 0b0001;    PORTD = mask(nr);    delay_ms(10);    PORTA = 0b0010;    PORTD = mask(nr);    delay_ms(10);    PORTA = 0b0100;    PORTD = mask(nr);    delay_ms(10);    PORTA = 0b1000;    PORTD = mask(nr);    delay_ms(10);

tu scrii acelasi numar care se gaseste in variabila nr, pe fiecare digit.

 

Nu te folosesti de:

int digit[5];

in care ar trebui stocate valorile de afisat pe digiti.

 

In plus, rutina de afisare (cea de mai sus dar corectata) ar trebui sa ramana intr-o bucla intrerupta cand se apasa o tasta ...

Ceva in genul:

do  display();      kp = Keypad_Key_Click();while (!kp);

iar in afara acestei bucle, cand o tasta este apasata actualizezi valorile vectorului digit.

if (kp != 0) {      digit[digit_curent++] = digit[digit_curent];      digit[digit_curent] = mask(nr);            if (digit_curent == 4) {        digit_curent = 0;        for (i = 0; i < 4; i++) {            digit[i] = 0;        }      }      else digit_curent++;    }

iar rutina de afisare ar fi ceva de genul:

display() {        PORTA = 0b0001;    PORTD = digit[0];    delay_ms(10);        PORTA = 0b0010;    PORTD = digit[1];    delay_ms(10);        PORTA = 0b0100;    PORTD = digit[2];    delay_ms(10);        PORTA = 0b1000;    PORTD = digit[3];    delay_ms(10);}

LE: cred ca este evident ca afisarea ar trebui facuta cu ajutorul unui timer dar ...

Edited by mars01
Link to post
Share on other sites

Am pus nr peste tot sa vad daca afiseaza aceeasi valoare pe toti digitii, dar nu imi afiseaza.

 

Pai tocmai asta nu stiu cum sa fac. Eu pusesem afisarea intr-o bucla while, dar odata intrat in bucla nu mai iesea, deci nu e bine.

    PORTA = 0b0001;    PORTD = digit[0];    delay_ms(10);    PORTA = 0b0010;    PORTD = digit[1];    delay_ms(10);    PORTA = 0b0100;    PORTD = digit[2];    delay_ms(10);    PORTA = 0b1000;    PORTD = digit[3];    delay_ms(10); 

Asta cred ca e afisarea corecta.

Edited by mmihai94
Link to post
Share on other sites

In situatii de acest gen, este bine sa simplifici lucrurile cat mai mult.

Daca afisarea nu iti iese, atunci fa-ti o functie de afisare si doar acea functie de afisare.

Odata ce iti merge (cu numere fixe, asignate de tine ca parametri ai functiei) atunci mergi mai departe si incerci sa afisezi numere citite de la tastatura si pe care sa le shiftezi la stanga (pe display) odata cu introducerea unui cifre noi.

Ceva de genul (scris cu picioarele peste exemplul tau):

unsigned short digit_curent = 0, kp, cnt, oldstate = 0;int i, nr, digit[4], del = 0;unsigned short mask(unsigned short num){   switch (num){      case 0: return 0x3F;      case 1: return 0x06;      case 2: return 0x5B;      case 3: return 0x4F;      case 4: return 0x66;      case 5: return 0x6D;      case 6: return 0x7D;      case 7: return 0x07;      case 8: return 0x7F;      case 9: return 0x6F;      }}void display(int* digit){    PORTA = 0b0001;    PORTD = digit[0];    delay_ms(10);    PORTA = 0b0010;    PORTD = digit[1];    delay_ms(10);    PORTA = 0b0100;    PORTD = digit[2];    delay_ms(10);    PORTA = 0b1000;    PORTD = digit[3];    delay_ms(10);}void main() {  PORTA = 0;  TRISA = 0;  PORTD = 0;  TRISD = 0;  ANSEL  = 0;  ANSELH = 0;    for (i = 0; i < 4; i++) {    digit[i] = mask(1);  }  while (del < 300){     display(digit);     delay_ms(10);     del++;  }  do {        digit[0] = mask(3);    digit[1] = mask(6);    digit[2] = mask(3);    digit[3] = mask(2);    display(digit);  } while (1);    }
Link to post
Share on other sites

Secventa de mai sus a mers, dar mai departe tot nu reusesc. Ceva tot nu e bine, cu toate ca mi se pare ok.

 

Imi afiseaza doar pe digitul 2 si pe digitul 0.

void main() {  PORTA = 0;  TRISA = 0;  PORTD = 0;  TRISD = 0;  ANSEL  = 0;  ANSELH = 0;    Keypad_Init();    do {    kp = 0;    do{       display(digit);       kp = Keypad_Key_Click();    }while (!kp);    switch (kp) {      case  1: nr = 1; break; // 1      case  2: nr = 2; break; // 2      case  3: nr = 3; break; // 3      case  5: nr = 4; break; // 4      case  6: nr = 5; break; // 5      case  7: nr = 6; break; // 6      case  9: nr = 7; break; // 7      case 10: nr = 8; break; // 8      case 11: nr = 9; break; // 9      case 14: nr = 0; break; // 0    }    if (kp != 0) {       digit[digit_curent++] = digit[digit_curent];       digit[digit_curent] = mask(nr);       if (digit_curent == 4) {          digit_curent = 0;          for (i = 0; i < 4; i++) {             digit[i] = 0;          }       }       else digit_curent++;    }  } while (1);}
Edited by mmihai94
Link to post
Share on other sites

Daca declar digit_curent = 0, atunci digit[digit_curent++] inseamna digit[1]. Eu asta am dedus ca face.

 

Edit:  :rade:  Chiar la digit[digit_curent++] era problema, am inlocuit cu digit[digit_curent+1] si se pare ca merge.

Edited by mmihai94
Link to post
Share on other sites

Posteaza codul actualizat.LE Nu-i nevoie de codul nou, e suficient sa citesti cum trebuie foaia de catalog. Se pare (cap. 3.2.3.4) ca RA3 e doar intrare (a general purpose input).

Edited by Liviu M
Link to post
Share on other sites

Așa scrie , e drept , dar din schemă, din regiștri, etc.  nu rezultă asta . Cred că e o eroare de ”copy-paste” de la alte tipuri unde RA3 este partajat cu MCLR ceea ce nu e cazul aici .

De altfel , vezi și aici :

http://learn.mikroe.com/ebooks/picmicrocontrollersprogramminginassembly/chapter/pic16f887-microcontroller-device-overview/

 

 

PS Dacă am înțeles eu bine schema digitul ăla nu s-ar aprinde de loc dacă RA3 nu ar fi ieșire . 

Link to post
Share on other sites

Salut

 

Cam asa vad eu lucrurile la afisarea pe display a digitilor apasati.

Codul este scris im mikrobasic (nu am mikroC) dar, se poate traduce destul de usor nefiind vorba de functii complexe.

 

despre cod:

- afisarea se face intr-o intrerupere de la timer1

- cu butonul steluta (*) se sterge numaarul afisat

proiect mmihai94 elforum.rar

Edited by Rabulea Sergiu
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.Terms of Use si Guidelines