Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Problema con codice per tastiera a matrice

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

0
voti

[1] Problema con codice per tastiera a matrice

Messaggioda Foto Utenteguidonetto » 21 mar 2015, 10:57

Salve, uso un pic18f4550 con Mplabx, non riesco a far funzionare un tastierino a matrice, in pratica dovrei visualizzare il tasto premuto su un display 16x2, potete darmi una mana a dirmi dove ho sbagliato a compilare il codice?
Al momento sul display vedo solo 4 righette orrizontali.
Grazie.

Codice: Seleziona tutto
//Nota: granparte del codice lo preso da settorezero.

#include <xc.h>
#include "PIC18F4550_config.h"
#define LCD_DEFAULT
#include "LCD_44780.h"
#include "LCD_44780.c"
#include "delay.h"
#include "delay.c"

#define MAX_X 16 // numero di colonne del display
#define MAX_Y 2 // numero di righe del display

unsigned char lcdXpos=0; // posizione colonna attuale
unsigned char lcdYpos=0; // posizione riga attuale
// Variabile usata per creare un conteggio fittizio di pausa
unsigned int i;

bit keyok; // flag di pulsante premuto

//*************************************
// Prototipo di funzione
//*************************************
void board_initialization (void) {
// Imposto PORTA tutti ingressi
LATA = 0x00;
TRISA = 0xFF;
// Imposto PORTB tutti ingressi
LATB = 0x00;
//Le porte sono settate per avere le colonne come uscita e le righe come ingresso.
TRISB=0b10101010;
// Imposto PORTC tutti ingressi, RC1 come output
LATC = 0x00;
TRISC = 0b11111101;
// Imposto PORTD tutte uscite, RD0 come ingresso
LATD = 0x00;
TRISD = 0b00000001;
// Imposto PORTE tutti ingressi
LATE = 0x00;
TRISE = 0xFF;

}//void board_initialization (void)

// Programma principale
//*************************************
int main (void){

// Abilita i resistori di pull-up sulla PORTB
INTCON2bits.RBPU = 0x00;

board_initialization ();

/*Definisco un array da scansionare con un ciclo for, che mi permetterà di mettere
* a massa le colonne una alla volta e riportare a livello logico alto le altre, andando
* dal valore colMask[0] al valore colMask[3], porterò a massa le colonne una alla volta.*/
unsigned char colMask[]=
   {
   0b11111110, // Colonna 1 => RB0 a massa
   0b11111011, // Colonna 2 => RB2 a massa
   0b11101111, // Colonna 3 => RB4 a massa
   0b10111111 // Colonna 4 => RB6 a massa
   };
unsigned char colScan=0; // va da 0 a 3 per scansionare l'array colMask

/*Definisco un array da scansionare con un ciclo for, che mi permetterà la scansione
* delle righe e controllare quale riga è andata a massa, più una variabile per contenere
*  l'indice della riga scansionata.*/
unsigned char rowMask[]=
   {
   0b00000010, // Riga 1
   0b00001000, // Riga 2
   0b00100000, // Riga 3
   0b10000000 // Riga 4
   };
unsigned char rowScan=0;

//Arrary che contiene i simboli disegnati sul tastierino.
unsigned char keys[]={'1','4','7','*','2','5','8','0','3','6','9','#','A','B','C','D'};

unsigned char keypressed=0; // peso numerico del pulsante premuto

// Inizializzo il display LCD con quarzo a 20MHz
LCD_initialize (20);
LCD_backlight (TURN_ON_LED_LCD);

/*Effetuo la scansione delle colonne contando da 0 a 3 e ponendo i relativi pin a livello logico basso uno
* alla volta e ripristinando a 1 gli altri facendo uso dell' array colMask.*/
for (colScan=0; colScan<4; colScan++){ // porto a massa una colonna alla volta

   PORTB &= colMask[colScan]; // porto a zero la colonna attuale
}

/*Per ogni colonna posta a 0 effetuo un ciclo di scansione delle 4 righe.*/
for (rowScan=0; rowScan<4; rowScan++){
}

/*Controllo che la riga attuale si trovi a massa effettuando un AND con l'elemento delll'array rowScan
* che permette di verificare soltanto il bit interessato su tutta la pota.*/
if (!(PORTB & rowMask[rowScan])) {

    // Pausa che filtra gli spike. Per i pulsanti è sempre meglio metterla.
for (i=0;i<32000; i++) {
}

if (!(PORTB & rowMask[rowScan])) {

keypressed=rowScan+(4*colScan); // numero di pulsante premuto
keyok=1; // è stato premuto un pulsante

LCD_write_char (keys[keypressed]); //Scrive un carattere sul display.
//LCD_write_message(keys[keypressed]); //Vedo il carattere premuto.

}//secondo if
}//primo if

//Rimango in un ciclo continuo fino a che il pulsante non viene rilasciato
PORTB=0b10101010;
while(PORTB != 0b10101010) {
     continue;
}//while
}//main
Avatar utente
Foto Utenteguidonetto
13 1 5
Frequentatore
Frequentatore
 
Messaggi: 124
Iscritto il: 8 mag 2011, 21:08

0
voti

[2] Re: Problema con codice per tastiera a matrice

Messaggioda Foto Utenteguidonetto » 21 mar 2015, 15:59

Ciao, ho trovato che è questa funzione a fare le lineette:
LCD_write_char (keys[keypressed]); //Scrive un carattere sul display.

Purtroppo se scrivo:
LCD_write_message(keys[keypressed]); //Vedo il carattere premuto.
vedo solo i piksel del display.
Avatar utente
Foto Utenteguidonetto
13 1 5
Frequentatore
Frequentatore
 
Messaggi: 124
Iscritto il: 8 mag 2011, 21:08

0
voti

[3] Re: Problema con codice per tastiera a matrice

Messaggioda Foto UtenteWALTERmwp » 23 mar 2015, 13:15

Ciao Foto Utenteguidonetto,
guidonetto ha scritto:potete darmi una mana
... ma ti diamo anche una manata ... dai, scherzo.

Non ho letto il codice però potresti provare a chiarire subito una cosa: non riesci a rilevare il tasto premuto, non riesci a visualizzare l'identificativo del tasto premuto (e quindi non riesci a gestire il display), oppure entrambi ?

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
30,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 8986
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[4] Re: Problema con codice per tastiera a matrice

Messaggioda Foto Utenteguidonetto » 25 mar 2015, 0:46

Ciao, non riesco a vedere il tasto premato, ho semplificato al massimo il codice, cerco di visualizzare un solo carattere del tastierino, mi dite per cortesia dove sbaglio?
Grazie

Codice: Seleziona tutto
#include <xc.h>
#include "PIC18F4550_config.h"
#define LCD_DEFAULT
#include "LCD_44780.h"
#include "LCD_44780.c"
#include "delay.h"
#include "delay.c"

#define colonna1 PORTBbits.RB0
#define colonna2 PORTBbits.RB1
#define colonna3 PORTBbits.RB2
#define colonna4 PORTBbits.RB3
#define riga1    PORTBbits.RB4
#define riga2    PORTBbits.RB5
#define riga3    PORTBbits.RB6
#define riga4    PORTBbits.RB7


//*************************************
// Prototipo di funzione
//*************************************
void board_initialization (void) {
// Imposto PORTA tutti ingressi
LATA = 0x00;
TRISA = 0xFF;
// Imposto PORTB tutti ingressi
LATB = 0x00;
TRISB= 0b11110000;//0xF0; //RB0..RB3 Colonne -> Out
// Imposto PORTC tutti ingressi, RC1 come output
LATC = 0x00;
TRISC = 0b11111101;
// Imposto PORTD tutte uscite, RD0 come ingresso
LATD = 0x00;
TRISD = 0b00000001;
// Imposto PORTE tutti ingressi
LATE = 0x00;
TRISE = 0xFF;
}//void board_initialization (void)

// Programma principale
//*************************************
int main (void){

// Abilita i resistori di pull-up sulla PORTB
INTCON2bits.RBPU = 0x00;

board_initialization ();

// Inizializzo il display LCD con quarzo a 20MHz
LCD_initialize (20);
LCD_backlight (TURN_ON_LED_LCD);
//Questa funzione scrive il messaggio da visualizzare sulla prima riga.
LCD_write_message ("Hello World 1");


while (1) {
int i = 0;
    for (i = 1; i <= 0x0F; i = i << 1) {

         LATB = i;
         switch (PORTB && 0xF0) {
             case 16:
                colonna4 = 0;
                riga4 = 0;   
                LCD_goto_line(2); //Questa funzione permette di posizionare il cursore sulla seconda riga.
                LCD_write_char (68); //Scrive un carattere sul display.
             break;
           
         }//switch
    }//for
  }//while
}//main
Avatar utente
Foto Utenteguidonetto
13 1 5
Frequentatore
Frequentatore
 
Messaggi: 124
Iscritto il: 8 mag 2011, 21:08

0
voti

[5] Re: Problema con codice per tastiera a matrice

Messaggioda Foto UtenteWALTERmwp » 25 mar 2015, 3:43

Premetto di non aver fatto alcun controllo sulla configurazione ne sull'utilizzo delle funzioni relative allo LCD (tra l'altro non c'è il link per la consultazione) quindi non escludo ci possa essere qualcosa da "sistemare" ma nel caso, appunto, del codice del Post [4] (quello del Post [1] non l'ho guardato) mi pare che vi sia un errore qui
Codice: Seleziona tutto
switch (PORTB && 0xF0) {
             case 16:

per cui dovresti rettificare con
Codice: Seleziona tutto
switch (PORTB & 0xF0) {
             case 16:
se proprio vuoi "intercettare" l'ingresso RB4 come attivo.
Se non ho interpretato male questo è un errore che ti pregiudica il test minimale; mentre nel Post [1] non so quale errore ci sia.
Per questo provo a darti una risposta dopo averlo letto (a meno che tu non provveda a modificarlo e proporre una nuova soluzione in un Post successivo).

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
30,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 8986
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[6] Re: Problema con codice per tastiera a matrice

Messaggioda Foto Utenteguidonetto » 25 mar 2015, 13:51

Ciao, mi piacerebbe che mi sistemassi il codice minimale per far vedere un pulsante del tastierino a matrice, cosi comprendo come funziona.
Ho messo da RB4 a RB7 le resistenze di pullup interne al PIC , abilitate come righe, e da RB0 a RB3, ho collegato quattro resistenze da 10K all' alimentazione dei 5V per le colonne.
Metto dinuovo il codice.
Grazie

Codice: Seleziona tutto
#include <xc.h>
#include "PIC18F4550_config.h"
#define LCD_DEFAULT
#include "LCD_44780.h"
#include "LCD_44780.c"
#include "delay.h"
#include "delay.c"

#define colonna1 PORTBbits.RB0
#define colonna2 PORTBbits.RB1
#define colonna3 PORTBbits.RB2
#define colonna4 PORTBbits.RB3
#define riga1    PORTBbits.RB4
#define riga2    PORTBbits.RB5
#define riga3    PORTBbits.RB6
#define riga4    PORTBbits.RB7


//*************************************
// Prototipo di funzione
//*************************************
void board_initialization (void) {
// Imposto PORTA tutti ingressi
LATA = 0x00;
TRISA = 0xFF;
// Imposto PORTB tutti ingressi
LATB = 0x00;
TRISB= 0b11110000;//0xF0; //RB0..RB3 Colonne -> Out
// Imposto PORTC tutti ingressi, RC1 come output
LATC = 0x00;
TRISC = 0b11111101;
// Imposto PORTD tutte uscite, RD0 come ingresso
LATD = 0x00;
TRISD = 0b00000001;
// Imposto PORTE tutti ingressi
LATE = 0x00;
TRISE = 0xFF;
}//void board_initialization (void)

// Programma principale
//*************************************
int main (void){

// Abilita i resistori di pull-up sulla PORTB
INTCON2bits.RBPU = 0x00;

board_initialization ();

// Inizializzo il display LCD con quarzo a 20MHz
LCD_initialize (20);
LCD_backlight (TURN_ON_LED_LCD);
//Questa funzione scrive il messaggio da visualizzare sulla prima riga.
LCD_write_message ("Hello World 1");


while (1) {
int i = 0;
    for (i = 1; i <= 0x0F; i = i << 1) {

         LATB = i;
         switch (PORTB & 0xF0) {
             case 16:
                colonna4 = 0;
                riga4 = 0;   
                LCD_goto_line(2); //Questa funzione permette di posizionare il cursore sulla seconda riga.
                LCD_write_char (68); //Scrive un carattere sul display.
             break;
            // case 32:
                    //Tasto i-esima colonna e riga 2
            // break;
             //...

         }//switch
    }//for
  }//while
}//main
Avatar utente
Foto Utenteguidonetto
13 1 5
Frequentatore
Frequentatore
 
Messaggi: 124
Iscritto il: 8 mag 2011, 21:08

0
voti

[7] Re: Problema con codice per tastiera a matrice

Messaggioda Foto UtenteWALTERmwp » 25 mar 2015, 16:30

Allora, intanto, in via preventiva, ti suggerisco la lettura del mio Post [37] in questo thread.
Ma prestami attenzione ...
guidonetto ha scritto:cosi comprendo come funziona.
... come funziona cosa ?
Lo domando ma senza nemmeno un velo di ironia; sii più esplicito così chiariamo quali e quante sono le tue lacune, altrimenti si riempiono Post(s) di indicazioni che l'utente magari, magari, non è in condizione di interpretare.

Saluti

p.s.
guidonetto ha scritto:Ciao, mi piacerebbe che mi sistemassi il codice minimale (...)
... mi trattengo e non faccio dell'ironia su questo; rispondi a quanto sopra e, eventualmente, lo si sistema insieme.
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
30,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 8986
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[8] Re: Problema con codice per tastiera a matrice

Messaggioda Foto Utenteguidonetto » 25 mar 2015, 22:50

Salve e grazie, sono agli inizi con la programmazione dei PIC, quindi la mia lacuna è grande, ora mi trovo ad armeggiare con una tastiera a matrice e mi sono arenato è ben diverso che far comparire una scritta su un display oppure far accendere un led, purtroppo non ho una scuola alle spalle ma traggo informazioni dalla rete, ti chiedo se possibile un codice funzionante, commentato, cosi prima avere la soddisfazione di vedere il tasto premuto e poi leggendo i commenti nel codice capire i passaggi.
Grazie
Avatar utente
Foto Utenteguidonetto
13 1 5
Frequentatore
Frequentatore
 
Messaggi: 124
Iscritto il: 8 mag 2011, 21:08

0
voti

[9] Re: Problema con codice per tastiera a matrice

Messaggioda Foto UtenteWALTERmwp » 25 mar 2015, 23:32

Allora, proviamo a trovare una soluzione.
Le descrizioni, se fatte bene, possono essere sufficienti ma a volte occorre uno schema.
Lo dovresti realizzare con gli strumenti previsti qui, su EY: per questo ti devi scaricare FidoCad o FidoCadJ.
Però lo devi riprodurre esattamente così come è ora.
Altra cosa, per questa discussione facciamo riferimento ad un codice al quale andiamo ad apportare le modifiche del caso, previa condivisione; quindi, se sei d'accordo, consideriamo quello del Post [6] (altrimenti un aggiornamento se lo ritieni indispensabile, ma poi quello deve essere).
Non ho capito se saresti in condizione di gestire correttamente il display ma, a questo punto, forse, della visualizzazione possiamo anche non curarci; è meglio concentrarsi sulla lettura dei pulsantini.
Non vorrei che tu mettessi in "corto" pin(s) di ingresso con pin(s) d'uscita quindi, nel frattempo ( ... attendiamo lo schema) ti suggerisco di documentarti in rete sull'utilizzo di una tastiera del genere ma, volendo, potresti già partire con la lettura di questo articolo di Foto UtenteTardoFreak, così ti fai una idea, un po più definita.
E' propedeutico, credo ti serva.
Se devi gestire un "oggetto" tramite un microcontrollore è necessario "conoscere" l'oggetto, altrimenti non sai cosa occorre fare per interagire correttamente col medesimo.
Qui, su EY, funziona così: a prescindere dal fatto che il problema possa apparire facile o difficile se si chiede una mano, nei limiti della disponibilità condizionata dal tempo, dalla competenza e dalla voglia, un aiuto lo si riceve; è fondamentale però un approccio propositivo.
Hai inserito del codice, e va bene, proviamo ad andare avanti, ma non è corretto esprimersi così
guidonetto ha scritto:Ciao, mi piacerebbe che mi sistemassi il codice (...)
Auspico d'aver chiarito ogni eventuale piccolo equivoco.

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
30,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 8986
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[10] Re: Problema con codice per tastiera a matrice

Messaggioda Foto UtenteWALTERmwp » 26 mar 2015, 2:48

Ti ho predisposto la seguente porzione di codice focalizzando l'attenzione sul loop di controllo matrice.
L'ora è tarda e potrei facilmente aver commesso qualche errore quindi tu controlla bene bene.
Spero di avere interpretato correttamente quanto avevi intenzione di fare.
Le linee di codice, poi, le metti in relazione con lo schema che ti ho riportato; ho fatto riferimento alla PORTB come da te gestita nei propositi (se non ho travisato).
Leggilo e poi fammi sapere.

Codice: Seleziona tutto
while (1)
{
    int i = 0;

    for (i = 1; i < 0x09; i = i << 1)   //W- i <= 0x0F NO!
    {
         LATB = i; //W-attivi una uscita

         switch (PORTB & 0xF0)
         {
             //W-esegui test su ingressi

             case 0x10: //W-test (riga0) di ingresso corrispondente a RB4
                 switch (i)
                 {
                     case 0x01: //W-pulsante corrispondente se (colonna0) uscita RB0
                         //W- tasto "F"
                         //W- qui inserisci codice visualizzazione
                         break;
                     case 0x02: //W-pulsante corrispondente se (colonna1) uscita RB1
                         //W- tasto "E"
                         //W- qui inserisci codice visualizzazione
                         break;
                     case 0x04: //W-pulsante corrispondente se (colonna2) uscita RB2
                         //W- tasto "D"
                         //W- qui inserisci codice visualizzazione
                         break;
                     case 0x08: //W-pulsante corrispondente se (colonna3) uscita RB3
                         //W- tasto "C"
                         //W- qui inserisci codice visualizzazione
                         break;
                     default:
                         break;
                 }
             break;

             case 0x20: //W-test (riga1) di ingresso corrispondente a RB5
                 switch (i)
                 {
                     case 0x01: //W-pulsante corrispondente se (colonna0) uscita RB0
                         //W- tasto "B"
                         //W- qui inserisci codice visualizzazione
                         break;
                     case 0x02: //W-pulsante corrispondente se (colonna1) uscita RB1
                         //W- tasto "A"
                         //W- qui inserisci codice visualizzazione
                         break;
                     case 0x04: //W-pulsante corrispondente se (colonna2) uscita RB2
                         //W- tasto "9"
                         //W- qui inserisci codice visualizzazione
                         break;
                     case 0x08: //W-pulsante corrispondente se (colonna3) uscita RB3
                         //W- tasto "8"
                         //W- qui inserisci codice visualizzazione
                         break;
                     default:
                         break;
                 }
             break;

             case 0x40: //W-test (riga1) di ingresso corrispondente a RB6
                 switch (i)
                 {
                     case 0x01: //W-pulsante corrispondente se (colonna0) uscita RB0
                         //W- tasto "7"
                         //W- qui inserisci codice visualizzazione
                         break;
                     case 0x02: //W-pulsante corrispondente se (colonna1) uscita RB1
                         //W- tasto "6"
                         //W- qui inserisci codice visualizzazione
                         break;
                     case 0x04: //W-pulsante corrispondente se (colonna2) uscita RB2
                         //W- tasto "5"
                         //W- qui inserisci codice visualizzazione
                         break;
                     case 0x08: //W-pulsante corrispondente se (colonna3) uscita RB3
                         //W- tasto "4"
                         //W- qui inserisci codice visualizzazione
                         break;
                     default:
                         break;
                 }
             break;

             case 0x80: //W-test (riga1) di ingresso corrispondente a RB7
                 switch (i)
                 {
                     case 0x01: //W-pulsante corrispondente se (colonna0) uscita RB0
                         //W- tasto "3"
                         //W- qui inserisci codice visualizzazione
                         break;
                     case 0x02: //W-pulsante corrispondente se (colonna1) uscita RB1
                         //W- tasto "2"
                         //W- qui inserisci codice visualizzazione
                         break;
                     case 0x04: //W-pulsante corrispondente se (colonna2) uscita RB2
                         //W- tasto "1"
                         //W- qui inserisci codice visualizzazione
                         break;
                     case 0x08: //W-pulsante corrispondente se (colonna3) uscita RB3
                         //W- tasto "0"
                         //W- qui inserisci codice visualizzazione
                         break;
                     default:
                         break;
                 }
             break;

             default:
             break;

         } //switch

    } //for

} //while

Tastiera matrice
Sulle uscite ti ho posizionato i diodi per dare evidenza della funzione e rendere immediatamente leggibile la matrice (almeno spero) mentre ho omesso le resistenze di pull-up (comunque ci andranno) ma questo al momento non è rilevante.

Fai pure le tue osservazioni e se c'è qualcosa che non ti è chiaro chiedi.

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
30,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 8986
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

Prossimo

Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 6 ospiti