E' noto che per utilizzare un LCD, tutti i pin connessi al modulo alfanumerico devono essere impostati come uscite, mentre per il pilotaggio di una tastiera solo i pin connessi alle colonne devono essere impostati come uscita e quelli connessi alle righe devono essere ingressi. Questi ultimi devono essere connessi anche ad un pull-up resistivo che può essere costituito da resistori esterni da 10K o dal pull-up interno del microcontrollore (se disponibile). L’accorgimento per gestire entrambi i dispositivi è piuttosto elementare: durante la gestione della tastiera si mantiene a livello basso il pin Enable del modulo LCD in modo da disattivare il display. Lo schema è riportato in figura 1, mentre il listato 1 riporta il sorgente scritto in mikroC.
#include “lcd_keypad.h”
void init_ports(void) {
ADCON1 = 0x06; //tutte uscite digitali
PORTB = 0;
TRISB = 0; //PORTB come uscite
}
void main() {
unsigned short key ; //tasto premuto
unsigned short c=0 ; // Show something on LCD.
char op[4] ; // Scratch area.
init_ports();
LCD_access();
Lcd_Config(&PORTB,0,2,1,7,6,5,4);
// PORT,RS,EN,WR,D7,D6,D5,D4
Lcd_Cmd(Lcd_CLEAR);// Clear display
Lcd_Cmd(Lcd_CURSOR_OFF); // Turn cursor off
Lcd_Out(1, 1, “BEST-MICRO-PJCTS”);
// Print text to LCD, 2nd row, 1st column
for(;;) {
// lettura KEYPAD
key = read_KEYPAD();
//decodifica del tasto premuto e conversione in carattere
switch (key) {
case KEY_0 : key=’0’;break;
case KEY_1 : key=’1’;break;
case KEY_2 : key=’2’;break;
case KEY_3 : key=’3’;break;
case KEY_4 : key=’4’;break;
case KEY_5 : key=’5’;break;
case KEY_6 : key=’6’;break;
case KEY_7 : key=’7’;break;
case KEY_8 : key=’8’;break;
case KEY_9 : key=’9’;break;
case KEY_STAR : key=’*‘;break;
case KEY_HASH : key=’#‘;break;
}
LCD_access(); // Uso del display
if (key) LCD_Chr(2,15,key); //Visualizza il tasto premuto:
ByteToStr(c++,op);
Lcd_Out(2, 1, op);
}
}
| Listato 1 |
Il programma mette a livello basso alternativamente tutte le colonne della tastiera a matrice. Quando viene premuto un tasto, lo zero presente sulla colonna viene trasmesso sulla riga su cui è connesso il tasto. Se nessun tasto è premuto, tutte le righe saranno a livello alto. La routine di lettura della tastiera ritorna un intero secondo quanto definito nel file lcd_key.h (riportato nel listato 2).
#define LCD_ALL (LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7 | LCD_RS | LCD_R_W | LCD_E) // Keypad PINS #define KEY_ROW1 (1<<4) #define KEY_ROW2 (1<<5) #define KEY_ROW3 (1<<7) #define KEY_ROW4 (1<<6) #define KEY_COL1 (1<<0) #define KEY_COL2 (1<<1) #define KEY_COL3 (1<<3) // Keypad groups #define KEY_ROWS (KEY_ROW1 | KEY_ROW2 | KEY_ROW3 | KEY_ROW4) #define KEY_COLS (KEY_COL1 | KEY_COL2 | KEY_COL3) #define KEY_ALL (KEY_ROWS | KEY_COLS) ///////////////////////////////////////////////////////////////////// // Output key values. // // These are only valid for the correct hardware connections // RB4=Row1(top), RB5=Row2, RB6=Row3, RB7=Row4 // RB0=COL1(left),RB1=COL2, RB3=COL3 // #define KEY_1 225 #define KEY_2 226 #define KEY_3 232 #define KEY_4 209 #define KEY_5 210 #define KEY_6 216 #define KEY_7 177 #define KEY_8 178 #define KEY_9 184 #define KEY_STAR 113 #define KEY_0 114 #define KEY_HASH 120 // Prototypes void LCD_access(void);
| Listato 2 |
Premendo due tasti connessi a differenti righe e colonne, vengono cortocircuitate due colonne che si trovano a livelli differenti. Poiché il pilotaggio delle colonne viene attraverso tre resistenze in serie (R1, R2 e R3), questo fenomeno non recherà alcun danno al circuito e consente, allo stesso tempo, di gestire correttamente il display anche se qualche tasto risulta premuto. Il listato 3 mostra le routnines LCD_access per abilitare il display, KEYPAD_access per abilitare la tastiera, e READ_keypad che legge il tasto premuto e lo converte nell’opportuno carattere.
unsigned short read_KEYPAD(void);
void LCD_access(void) {
LCD_PORT = 0;
LCD_TRIS = ~LCD_ALL;
}
static void KEYPAD_access(void) {
KEY_PORT = 0x00;
KEY_TRIS = ~KEY_COLS &~(LCD_E);
}
unsigned short read_KEYPAD(void) {
unsigned short mask = KEY_COL1;
unsigned short val;
unsigned short i;
char op[9];
KEY_PORT = 0x00;
KEY_TRIS = ~KEY_COLS &~(LCD_E);
OPTION_REG &= 0x7f; // enable portb pullups.
for (i=0;i<3;i++) {
if (mask==LCD_E) mask <<=1;
KEY_PORT = ~mask & ~(LCD_E);
delay_us(500);
val = (KEY_PORT & KEY_ROWS);
if ( (val & KEY_ROWS) != KEY_ROWS) {
return (val & KEY_ROWS) | mask;
}
mask = mask << 1;
}
return 0; // no keys return zero
}
| Listato 3 |






Un interessante circuito per testare tastiera e display con un MCU. E’ possibile attivare attraverso la tastiera alcuni sistemi, facendo un check dal display.