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

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

Messaggioda Foto Utenteguidonetto » 26 mar 2015, 14:09

Ti ringrazio tanto per il tuo impegno, metto in pratica , poi ti faccio sapere.
Grazie.
Avatar utente
Foto Utenteguidonetto
13 1 5
Frequentatore
Frequentatore
 
Messaggi: 124
Iscritto il: 8 mag 2011, 21:08

0
voti

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

Messaggioda Foto Utenteguidonetto » 26 mar 2015, 14:49

Ciao, per provare ho solo messo le istruzioni per visualizzare 4 tasti, purtroppo non vedo nulla, posto il codice per intero:

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"

unsigned int i;


//*************************************
// Prototipo di funzione
//*************************************
void board_initialization (void) {
// Imposto PORTA tutti ingressi
LATA = 0x00;
TRISA = 0xFF;

LATB = 0b00001111;
                  // Imposto   RB4..RB7 Righe   -> 0 Uscita   
TRISB= 0b00001111;// Imposto   RB0..RB3 Colonne -> 1 Ingress0
PORTB= 0b00001111;


// 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 < 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 "*"
                             LCD_goto_line(2); //Questa funzione permette di posizionare il cursore sulla seconda riga.
                             LCD_write_char (42); //Scrive un carattere sul display.
                             break;
                         case 0x02: //W-pulsante corrispondente se (colonna1) uscita RB1
                             //W- tasto "0"
                             LCD_goto_line(2); //Questa funzione permette di posizionare il cursore sulla seconda riga.
                             LCD_write_char (48); //Scrive un carattere sul display.
                             break;
                         case 0x04: //W-pulsante corrispondente se (colonna2) uscita RB2
                             //W- tasto "#"
                             LCD_goto_line(2); //Questa funzione permette di posizionare il cursore sulla seconda riga.
                             LCD_write_char (35); //Scrive un carattere sul display.
                             break;
                         case 0x08: //W-pulsante corrispondente se (colonna3) uscita RB3
                             //W- tasto "D"
                             LCD_goto_line(2); //Questa funzione permette di posizionare il cursore sulla seconda riga.
                             LCD_write_char (68); //Scrive un carattere sul display.
                             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
}//main


credo di avere ancora dei problemi col settaggio delle porte.

LATB = 0b00001111;
// Imposto RB4..RB7 Righe -> 0 Uscita
// Imposto RB0..RB3 Colonne -> 1 Ingress0
TRISB= 0b00001111;
PORTB= 0b00001111;

puoi ancora darmi una mano?


Grazie.
Avatar utente
Foto Utenteguidonetto
13 1 5
Frequentatore
Frequentatore
 
Messaggi: 124
Iscritto il: 8 mag 2011, 21:08

0
voti

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

Messaggioda Foto UtenteWALTERmwp » 26 mar 2015, 15:28

Purtroppo non ho la possibilità di verificare quanto stai facendo in pratica, e questo in parte perché non metti a disposizione le informazioni che ti sono state richieste.
Ti ho fatto presente, nel Post [9], che dovresti (non è un imperativo, tu chiedi un aiuto e ti viene semplicemente scritto cosa occorre affinché ti si possa aiutare) riportare lo schema ma non lo hai fatto malgrado te ne abbia inserito uno che potresti prendere e espandere ( ... questo è il "bello" di FidoCadJ).
A questo punto potrebbe essere fondamentale sapere cosa hai collegato e come.
Pur essendo un micro a 8 bit(s) non hai scelto proprio uno dei più piccini e se sei agli inizi è normale incontrare difficoltà, però mi sorge il dubbio che tu abbia anche poca dimestichezza con il "C".
Hai letto e compreso il codice che ti ho preparato oppure lo hai impiegato in modo acritico ?
Altrimenti non mi spiego questo:
Codice: Seleziona tutto
// Imposto RB4..RB7 Righe -> 0 Uscita
// Imposto RB0..RB3 Colonne -> 1 Ingress0
TRISB= 0b00001111;
PORTB= 0b00001111;

Riscrivo, potrei essere io a sbagliarmi quindi, a maggior ragione, devi prestare più attenzione.
Mi fai capire sino a che punto arrivi, cosa hai consolidato ?
Per esempio, questa istruzione che precede il loop
Codice: Seleziona tutto
LCD_write_message ("Hello World 1");
porta alla visualizzazione della scritta ?

Saluti

p.s.
va beh, comunque, RB7, RB6, RB5, RB4 sono Ingressi (in), RB3, RB2, RB1, RB0 sono uscite (out), vedi schema che ti ho proposto !
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

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

Messaggioda Foto Utenteguidonetto » 26 mar 2015, 22:19

Ok fatto disegno, per cortesia come lo inserisco nel post?
Avatar utente
Foto Utenteguidonetto
13 1 5
Frequentatore
Frequentatore
 
Messaggi: 124
Iscritto il: 8 mag 2011, 21:08

0
voti

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

Messaggioda Foto UtenteWALTERmwp » 27 mar 2015, 1:33

Le indicazioni le trovi consultando la guida disponibile accedendo al menu a tendina di EY (parte superiore della pagina) "Help -> Guida all'uso del Forum" (sezione "Schemi elettrici").

In pratica, con FidoCadJ aperto e il disegno visualizzato, nel menu a tendina (di FidoCadJ) selezioni "Composizione"->"Seleziona tutto": come risultato tutto quanto è presente nel disegno viene, appunto, selezionato.

Il passo successivo consiste nel copiare, quindi: ancora nel menu a tendina (di FidoCadJ) selezioni "Composizione"->"Copia"; a livello di visualizzazione non cambia nulla.

Passi quindi a visualizzare il Post; ora, come per inserire il codice hai "richiamato" i delimitatori [Code], per predisporre l'inserimento di un disegno devi "richiamare" i delimitatori [fcd].
Fatto questo, posizioni il cursore all'interno dei due delimitatori e "incolli", quanto hai prima copiato, con la combinazione dei tasti "ctrl-v".

Nel Post ti appaiono numeri e lettere ma, se selezioni il tasto sottostante "Anteprima", hai modo di visionare come si presenta il Post con il disegno riproposto allo stesso modo in cui lo hai disegnato; se va bene procedi col tasto "Invia".

Scritto questo, potresti, per cortesia, rispondere alle domande che ti ho rivolto nel Post [13] ?
Grazie.
Se te le ho scritte è per aiutarti, o almeno provare ad aiutarti, non so se riesco a spiegarmi.

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

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

Messaggioda Foto Utenteguidonetto » 27 mar 2015, 14:03


Ciao e ti chiedo scusa per non aver postato parte dello schema, hai ragione le mie lacune nel campo del c++ e PIC sono enormi, sto legggendo un libro sul c++ e seguo il manuale di Mauro Laurenti sul PIC (ecco perche uso il pic18f4550).
Mi sto concentrando sul funzionamento dei primi 4 tasti.
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"

/*Indico inpostazione colonne e righe
colonna1 PORTBbits.RB0
colonna2 PORTBbits.RB1
colonna3 PORTBbits.RB2
colonna4 PORTBbits.RB3
riga1    PORTBbits.RB4
riga2    PORTBbits.RB5
riga3    PORTBbits.RB6
riga4    PORTBbits.RB7
*/


//*************************************
// Prototipo di funzione
//*************************************
void board_initialization (void) {
// Imposto PORTA tutti ingressi
LATA = 0x00;
TRISA = 0xFF;


LATB = 0b00001111;
// Imposto   RB4..RB7 Righe   -> 0 Uscita   
// Imposto   RB0..RB3 Colonne -> 1 Ingress0
TRISB= 0b00001111;


// 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 < 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 "*"
                             LCD_goto_line(2); //Questa funzione permette di posizionare il cursore sulla seconda riga.
                             LCD_write_char (42); //Scrive un carattere sul display.
                             break;
                         case 0x02: //W-pulsante corrispondente se (colonna1) uscita RB1
                             //W- tasto "0"
                             LCD_goto_line(2); //Questa funzione permette di posizionare il cursore sulla seconda riga.
                             LCD_write_char (48); //Scrive un carattere sul display.
                             break;
                         case 0x04: //W-pulsante corrispondente se (colonna2) uscita RB2
                             //W- tasto "#"
                             LCD_goto_line(2); //Questa funzione permette di posizionare il cursore sulla seconda riga.
                             LCD_write_char (35); //Scrive un carattere sul display.
                             break;
                         case 0x08: //W-pulsante corrispondente se (colonna3) uscita RB3
                             //W- tasto "D"
                             LCD_goto_line(2); //Questa funzione permette di posizionare il cursore sulla seconda riga.
                             LCD_write_char (68); //Scrive un carattere sul display.
                             break;
                         default:
                            // Il pulsante è aperto, non visualizzo nulla.
                            LCD_goto_line(2);
                            LCD_write_message ("            ");
                     }//case 0x10:
                  /*
                 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;
                     }
                 */
             } //switch

        } //for

    } //while
}//main

Parto da questo:
[code]LCD_write_message ("Hello World 1");  [/code]
ho inserito questa istruzione solo per essere certo che il display funzioni.

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

                 case 0x10: //W-test (riga0) di ingresso corrispondente a RB4[/code]




invece qui non so se bisogna mettere un istuzione:
//W-esegui test su ingressi
Pochino, pochino sto iniziando a comprendere il funzionamento del codice.
Grazie.
Ultima modifica di Foto UtenteWALTERmwp il 27 mar 2015, 17:34, modificato 1 volta in totale.
Motivazione: riduzione dim.disegno a favore di una maggiore leggibilità
Avatar utente
Foto Utenteguidonetto
13 1 5
Frequentatore
Frequentatore
 
Messaggi: 124
Iscritto il: 8 mag 2011, 21:08

0
voti

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

Messaggioda Foto UtenteWALTERmwp » 27 mar 2015, 17:47

Mi sono permesso di ridurre la dimensione del micro in modo da rendere più leggibile il disegno che comunque ha conservato la sua impostazione.
guidonetto ha scritto:hai ragione le mie lacune nel campo del c++ e PIC sono enormi
non è un problema, ognuno di noi ha le proprie lacune, ma l'importante è, per chi prova a dare una mano, rendersi conto del livello di preparazione dell'utente per potersi relazionare in modo adeguato mentre è altrettanto importante che chi riceve un aiuto corrisponda alle domande (che poi in tal caso io riesca ad aiutarti è un'altra questione, ci provo).
guidonetto ha scritto:invece qui non so se bisogna mettere un istuzione: //W-esegui test su ingressi
no, è solo un mio commento che ti "dice" cosa fa lo switch seguente.
guidonetto ha scritto:Pochino, pochino sto iniziando a comprendere il funzionamento del codice.
ottimo, chiedi pure, senza remore, altrimenti ti pongo io le questioni per fare emergere le tue incertezze.
Se vuoi far funzionare quel programma devi capire il significato di ogni riga.
Se sei all'inizio non hai scelto un caso semplice semplice ma vediamo di dipanare i dubbi.

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

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

Messaggioda Foto Utenteguidonetto » 27 mar 2015, 23:55

Mi piacerebbe sapere se questo codice funziona, lo testato ma la pressione dei tasti non mi visualizza nulla.

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"

/*Indico inpostazione colonne e righe
colonna1 PORTBbits.RB0
colonna2 PORTBbits.RB1
colonna3 PORTBbits.RB2
colonna4 PORTBbits.RB3
riga1    PORTBbits.RB4
riga2    PORTBbits.RB5
riga3    PORTBbits.RB6
riga4    PORTBbits.RB7
*/


//*************************************
// Prototipo di funzione
//*************************************
void board_initialization (void) {
// Imposto PORTA tutti ingressi
LATA = 0x00;
TRISA = 0xFF;

LATB = 0b00001111;
// Imposto   RB4..RB7 Righe   -> 0 Uscita
// Imposto   RB0..RB3 Colonne -> 1 Ingress0
TRISB= 0b00001111;

// 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 < 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 "*"
                             LCD_goto_line(2); //Questa funzione permette di posizionare il cursore sulla seconda riga.
                             LCD_write_char (42); //Scrive un carattere sul display.
                             break;
                         case 0x02: //W-pulsante corrispondente se (colonna1) uscita RB1
                             //W- tasto "0"
                             LCD_goto_line(2); //Questa funzione permette di posizionare il cursore sulla seconda riga.
                             LCD_write_char (48); //Scrive un carattere sul display.
                             break;
                         case 0x04: //W-pulsante corrispondente se (colonna2) uscita RB2
                             //W- tasto "#"
                             LCD_goto_line(2); //Questa funzione permette di posizionare il cursore sulla seconda riga.
                             LCD_write_char (35); //Scrive un carattere sul display.
                             break;
                         case 0x08: //W-pulsante corrispondente se (colonna3) uscita RB3
                             //W- tasto "D"
                             LCD_goto_line(2); //Questa funzione permette di posizionare il cursore sulla seconda riga.
                             LCD_write_char (68); //Scrive un carattere sul display.
                             break;
                         default:
                            // Il pulsante è aperto, non visualizzo nulla.
                            LCD_goto_line(2);
                            LCD_write_message ("            ");
                     }//case 0x10:
                  /*
                 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;
                     }
                 */
             } //switch

        } //for

    } //while
}//main   


Provo a descrivere un pezzetto del codice.
int i = 0;
hai dichiarato i come intero e assegnato il valore 0.

for (i = 1; i < 0x09; i = i << 1) //W- i <= 0x0F NO!
{
fai un conteggio da 1 a 9, (i = i << 1) mi sembra che voglia dire andare indietro di 1, quindi fai un conteggio al contrario?

LATB = i; //W-attivi una uscita
qui metti a 1 (attivi come hai scritto) tutti i pin del LATB, quindi quelli che si trovano a 0 diventano 1 (colonne da RB0 a RB3) e le righe (da RB4 a RB7) rimangono a 1, tramite il conteggio sopra una alla volta.

Mi fermo, ora qui.
Grazie ancora per il tempo che mi stai dedicando.
Guido.
Avatar utente
Foto Utenteguidonetto
13 1 5
Frequentatore
Frequentatore
 
Messaggi: 124
Iscritto il: 8 mag 2011, 21:08

0
voti

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

Messaggioda Foto UtenteWALTERmwp » 28 mar 2015, 1:48

guidonetto ha scritto:fai un conteggio da 1 a 9, (i = i << 1) mi sembra che voglia dire andare indietro di 1, quindi fai un conteggio al contrario?
la variabile "i" era dichiarata come "int" nel codice che hai proposto inizialmente e tale l'ho lasciata (vedi nota a fine Post).
La "i" viene inizializzata a 1 (00000001) e, nel ciclo for, ad ogni esecuzione, il bit a 1 viene spostato a sinistra di una posizione, quindi:

- 00000001 (vale 0x01)
- 00000010 (vale 0x02)
- 00000100 (vale 0x04)
- 00001000 (vale 0x08) quarta posizione

Giunto alla quarta posizione, se si esegue un altro shift a sinistra, si ottiene questo

- 00010000 (vale 0x10) cioè 16

ma, non essendo inferiore a 9 (0x09) il ciclo termina per ripartire dalla condizione iniziale, cioè 1 (00000001).

I primi quattro bit(s), quelli sottolineati, sono da associare, nel momento in cui si esegue l'operazione
"LATB = i;"
da destra verso sinistra, rispettivamente a: RB0, RB1, RB2 e RB3.
L'operazione LATB, come assegnazione, era già presente nel primo codice che hai pubblicato quindi l'ho lasciata ma è da verificare consultando il datasheet.
Dunque, questo fa si che una delle quattro uscite (ma solo una alla volta) vada a 1.

Se, per esempio, viene messa a 1 l'uscita RB0, e tu premi uno dei quattro tasti connessi alla medesima linea (colonna C0, cioè di RB0) che sono (*), (7), (4 e (1), ti ritrovi il segnale a 1 su una delle quattro linee (righe) che sono collegate agli ingressi RB4, RB5, RB6 e RB7.

Così, facendo riferimento al codice, con l'assegnazione
i=1 (cioè i='00000001') e quindi LATB=i
metti a 1 l'uscita RB0.

Ora, se tu, per esempio, premi il pulsante asterisco (*) metti in connessione la linea C0 con la linea R0 che è collegata all'ingresso RB4.
Come questa situazione viene "intercettata" ?

Il codice
Codice: Seleziona tutto
switch (PORTB & 0xF0)
esegue un AND a bit(s) tra "PORTB" e la costante "0xF0"; questo risultato, che non è assegnato a nessun'altra variabile, rimane in un registro del micro e utilizzato per stabilire a quale "case", cioè a quale caso, tra quelli previsti, esso corrisponde.
In tale caso risulta corrispondente a
Codice: Seleziona tutto
case 0x10: //W-test (riga0) di ingresso corrispondente a RB4


"Entrati" in questa porzione di codice, si esegue lo "switch" successivo che ha lo scopo di verificare quale uscita abbiamo attivato e, per quanto sopra, risulta essere la prima ovvero RB0; il che implica che il flusso del programma vada ad eseguire la relativa porzione di codice
Codice: Seleziona tutto
switch (i)
{
case 0x01: //W-pulsante corrispondente se (colonna0) uscita RB0
//W- tasto "*"
LCD_goto_line(2); //Questa funzione permette di posizionare il cursore sulla seconda riga.
LCD_write_char (42); //Scrive un carattere sul display.
break;

In questo modo tu hai "capito" che è stato premuto quel pulsante.

Se non venisse premuto alcun pulsante il codice "switch (PORTB & 0xF0)" avreebbe 0x00 (cioè zero) come risultato e questo non ti farebbe entrare in nessun'altra porzione di codice; equivale appunto alla condizione di "nessun tasto premuto"

Il loop "while" e "for" te l'ho scritto seguendo quella che mi è sembrata essere l'impostazione iniziale; le cose si possono fare anche in altro modo.
Questo, a prescindere che possa essere più o meno "contorto", è comunque un percorso possibile.

Do evidenza ad una riserva e cioè al fatto che l'assegnazione tramite "LATB" possa precludere il rilevamento degli stati logici dei quattro pin(s) di ingresso: è da verificare consultando la documentazione.

nota:
In generale, è bene tenere presente, però, le tipologie di variabili e eseguire, per quanto possibile, operazioni tra variabili dello stesso tipo; quando questo non si fa per scelta è chiaro che bisogna esserne consapevoli.
Significa, però, che se hai una variabile che dimensionalmente corrisponde a 16 bit(s), cioè un "int" (intero) e la assegni ad una variabile "char" (carattere) o "byte" che sono a 8 bit(s), puoi perdere delle informazioni.
Ora, in questo caso, è da verificare se il compilatore riserva un'area di memoria corrispondente a 16 bit(s) o a 8 bit(s) per la variabile "i" e come "risolve l'assegnazione su LATB.

Saluti e, Buona notte
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

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

Messaggioda Foto Utenteguidonetto » 28 mar 2015, 10:05

Ciao, bravo un lavoro eccellente. Ho preso spunto e commentato il codice:

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"

/*Indico inpostazione colonne e righe
colonna1 PORTBbits.RB0
colonna2 PORTBbits.RB1
colonna3 PORTBbits.RB2
colonna4 PORTBbits.RB3
riga1    PORTBbits.RB4
riga2    PORTBbits.RB5
riga3    PORTBbits.RB6
riga4    PORTBbits.RB7
*/


//*************************************
// Prototipo di funzione
//*************************************
void board_initialization (void) {
// Imposto PORTA tutti ingressi
LATA = 0x00;
TRISA = 0xFF;

LATB = 0b00001111;
// Imposto   RB4..RB7 Righe   -> 0 Uscita
// Imposto   RB0..RB3 Colonne -> 1 Ingress0
TRISB= 0b00001111;

// 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)
    {
        unsigned char i = 0; //Ho assegnato unsigned char perche non devo leggere numeri maggiori di 255.
/*La "i" viene inizializzata a 1 (00000001), nel ciclo for, ad ogni esecuzione,
  il bit a 1 viene spostato a sinistra di una posizione, quindi:
- 00000001 (vale 0x01)
- 00000010 (vale 0x02)
- 00000100 (vale 0x04)
- 00001000 (vale 0x08) quarta posizione
   */
        for (i = 1; i < 0x09; i = i << 1)   //W- i <= 0x0F NO!
        {
             LATB = i; //Questo fa si che una delle quattro uscite (ma solo una alla volta) vada a 1.

             switch (PORTB & 0xF0)//Esegue un AND a bit(s) tra "PORTB" e la costante "0xF0, anche 0b11110000.
             {

                                  //L'operazione AND dà come valore 1 se tutti gli operandi hanno valore 1
                 
                 /*  esegue un AND a bit(s) tra "PORTB" e la costante "0xF0"; questo risultato,
                  *  che non è assegnato a nessun'altra variabile, rimane in un registro del
                  *  micro e utilizzato per stabilire a quale "case", cioè a quale caso, tra
                  *  quelli previsti, esso corrisponde.
                  *  In tale caso risulta corrispondente a */

                 case 0x10: //W-test (riga0) di ingresso corrispondente a RB4
                     switch (i)
                     {
                         case 0x01: //W-pulsante corrispondente se (colonna0) uscita RB0
                             //W- tasto "*"
                             LCD_goto_line(2); //Questa funzione permette di posizionare il cursore sulla seconda riga.
                             LCD_write_char (42); //Scrive un carattere sul display.
                             break;
                         case 0x02: //W-pulsante corrispondente se (colonna1) uscita RB1
                             //W- tasto "0"
                             LCD_goto_line(2); //Questa funzione permette di posizionare il cursore sulla seconda riga.
                             LCD_write_char (48); //Scrive un carattere sul display.
                             break;
                         case 0x04: //W-pulsante corrispondente se (colonna2) uscita RB2
                             //W- tasto "#"
                             LCD_goto_line(2); //Questa funzione permette di posizionare il cursore sulla seconda riga.
                             LCD_write_char (35); //Scrive un carattere sul display.
                             break;
                         case 0x08: //W-pulsante corrispondente se (colonna3) uscita RB3
                             //W- tasto "D"
                             LCD_goto_line(2); //Questa funzione permette di posizionare il cursore sulla seconda riga.
                             LCD_write_char (68); //Scrive un carattere sul display.
                             break;
                         default:
                            // Il pulsante è aperto, non visualizzo nulla.
                            LCD_goto_line(2);
                            LCD_write_message ("            ");
                     }//case 0x10:
                  /*
                 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;
                     }
                 */
             } //switch

        } //for

    } //while
}//main 


qui al posto del LATB = i; per non avere dubbi sullo stao delle porte si può dare un'altra assegnazione al LAT, tipo al TRIS o PORT?
Codice: Seleziona tutto
Do evidenza ad una riserva e cioè al fatto che l'assegnazione tramite "LATB" possa precludere il rilevamento degli stati logici dei quattro pin(s) di ingresso: è da verificare consultando la documentazione.
   

ho assegnato:
unsigned char i = 0; //Ho assegnato unsigned char perche non devo leggere numeri maggiori di 255.
al posto di:
inti=0;
perché non ho interi da 16bit, cosi risparmio spazio in memoria.
Grazie
Avatar utente
Foto Utenteguidonetto
13 1 5
Frequentatore
Frequentatore
 
Messaggi: 124
Iscritto il: 8 mag 2011, 21:08

PrecedenteProssimo

Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 8 ospiti