//************************************************* // Utilizzo di un tastierino a matrice 4x4 // www.settorezero.com // // modulo: main.c // autore: Bernardo Giovanni // data: 13/06/10 // picmicro: PIC16F877A // clock: 20MHz // //************************************************* // ATTENZIONE: il programma è stato adattato per funzionare su PIC18F4550 e IDE MPLAB X /* tastierino numerico collegato su PORTB uso un tastierino 4x4 (16 pulsanti) Per comodità ho collegato il tastierino in questo modo (C=colonna R=riga) R1 = RB1 R2 = RB3 R3 = RB5 R4 = RB7 C1 = RB0 C2 = RB2 C3 = RB4 C4 = RB6 I pin di riga saranno input ed attiveremo le resistenze di pullup interne i pin di colonna saranno output e messi a 1 di default */ #include #include // Librerie Laurtec #include #include #include #include #define BUZZER RC0 // cicalino #define LCDBL RC1 // backlight LCD unsigned char lcdXpos=0; // posizione colonna attuale unsigned char lcdYpos=0; // posizione riga attuale #define MAX_X 16 // numero di colonne del display #define MAX_Y 2 // numero di righe del display 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 unsigned char rowMask[]= { 0b00000010, // Riga 1 0b00001000, // Riga 2 0b00100000, // Riga 3 0b10000000 // Riga 4 }; unsigned char rowScan=0; 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 bit keyok; // flag di pulsante premuto void settings(void); extern void main(void); extern void sound(void); void settings(void) { TRISA = 0; PORTB = 0xFF; TRISB = 0b10101010; TRISC = 0; TRISD = 0; INTCON = 0b00000000; RBPU = 0; // resistenze di pullup su portb attivate } void sound(void) { for (unsigned char a=10; a>0; a--) { delay_ms(1); BUZZER = 1; delay_ms(1); BUZZER = 0; } } void main(void) { settings(); LCDBL=1; initialize_LCD(20); // inizializzo l'LCD delay_ms(100); // piccolo ritardo iniziale clear_LCD(); // ripulisco il display goto_xy_LCD(1,1); // posiziono il cursore sull'LCD: riga1, colonna1 write_string_LCD("Numeric Keypad"); goto_xy_LCD(2,1); // riga2, colonna1 write_string_LCD("settorezero.com"); delay_ms(250); delay_ms(250); delay_ms(250); clear_LCD(); keyok=0; while(1) { for (colScan=0; colScan<4; colScan++) // porto a massa una colonna alla volta { PORTB=0xFF; // porto tutte le colonne a 1 PORTB &= colMask[colScan]; // porto a zero la colonna attuale // mi controllo le righe for (rowScan=0; rowScan<4; rowScan++) { if (!(PORTB & rowMask[rowScan])) // Riga rowScan trovata a massa { delay_ms(50); if (!(PORTB & rowMask[rowScan])) { keypressed=rowScan+(4*colScan); // numero di pulsante premuto keyok=1; // è stato premuto un pulsante } } } // fine scansione righe } // fine scansione colonne if (keyok) // è stato premuto un pulsante { if (lcdXpos==MAX_X) // sono arrivato all'ultima colonna dell'LCD? { lcdXpos=0; // devo ritornare alla colonna zero lcdYpos++; // della riga successiva if (lcdYpos==MAX_Y) // sono finite le righe dell'LCD? { lcdYpos=0; // devo ritornare alla prima riga } goto_xy_LCD(lcdYpos+1, lcdXpos+1); // posiziono il cursore sulla cella giusta } // solo dopo che ho controllato in che punto si trova il // cursore posso piazzare il carattere premuto write_char_LCD(keys[keypressed]); sound(); // incremento la colonna sull'LCD lcdXpos++; keyok=0; // resetto il flag di pulsante premuto // rimango in un ciclo continuo fino a che il pulsante non viene rilasciato PORTB=0b10101010; while(PORTB != 0b10101010) {continue;} } } }