Το πληκτρολόγιο matrix 4x4
αποτελείται από 16 πλήκτρα – διακόπτες τα οποία είναι συνδεδεμένα μεταξύ τους ανά
4 σε τέτοια διάταξη ώστε, με το ένα άκρο τους να σχηματίζουν 4 σειρές και με το
άλλο 4 στήλες. Στο θεωρητικό κύκλωμα του σχήματος παρουσιάζεται η σύνδεση ενός
πληκτρολογίου matrix 4x4 στο port ενός μικροελεγκτή. Οι 4 σειρές
συνδέονται στη μισή θύρα του μικροελεγκτή P0 – P3,
η οποία λειτουργεί ως έξοδος με αρχική κατάσταση 1111
και οι 4 στήλες στην άλλη μισή θύρα P4 – P7, η οποίαλειτουργεί ως είσοδος με ενεργοποιημένες τις pull up αντιστάσεις
σε κάθε pin. Οι έξοδοι P0
έως P3 περνούν μια – μια διαδοχικά σε λογικό 0 για ένα χρονικό διάστημα της τάξεως ms
σαρώνοντας τις σειρές. Οι είσοδοι P4 – P7 ανιχνεύουν τη
χαμηλή λογική σε περίπτωση που πατηθεί κάποιο πλήκτρο από τις στήλες. Ο
συνδιασμός στήλης – σειράς καθορίζει το πλήκτρο που έχει πατηθεί. Αν για παράδειγμα
πατηθεί το πλήκτρο 6, η είσοδος P6
θα δεχτεί λογικό 0 όταν η έξοδος P1
περάσει σε λογικό 0. O καταχωρητής κατάστασης της θύρας τη
στιγμή εκείνη θα γίνει 10111101. Το
byte αυτό αντιστοιχίζεται στη συνέχεια στο νούμερο 6 ή σε κάποια άλλη
λειτουργία. Η αντιστοίχιση μπορεί να γίνει με μια εντολή switch.
Επειδή κατά το κλείσιμο και κατά το άνοιγμα της επαφής του διακόπτη
δημιουργούνται παρασιτικοί παλμοί, εισάγονται κάποιες καθυστερήσεις από το
λογισμικό, ώστε να αποφεύγονται λανθασμένες πληροφορίες. Οι δίοδοι D1 έως D4
είναι απαραίτητες για προστασία από βραχυκύκλωμα σε περίπτωση που πατηθούν ταυτόχρονα
δύο πλήκτρα που βρίσκονται στην ίδια στήλη. Αν συμβεί αυτό η έξοδος που είναι
σε λογικό 0 θα κλείσει κύκλωμα με την
άλλη έξοδο που είναι σε λογικό 1. Η
δίοδος τότε που βρίσκεται στη δεύτερη έξοδο πολώνεται ανάστροφα και
προστατεύεται το κύκλωμα. Στη συνέχεια παρουσιάζεται ένα παράδειγμα κώδικα σε
γλώσσα C που μπορεί να
χρησιμοποιηθεί για αναγνώριση πληκτρολογίου:
#include <avr/io.h>
#include <util/delay.h>
uint8_t line;
uint8_t data;
void Keyb (void)
//Keyboard rutine
{
line = 1;
for (uint8_t
i1 = 0; i1 < 4; i1++)
{
PORTA = ~line;
line = line << 1;
//_delay_ms(1);
while (PINA < 0b11101111)
{
_delay_ms (5);
switch (PINA)
{
case 0b11101110: //Button 1 pressed
data = 1;
while (PINA == 0b11101110); //Button still pressed
break;
case 0b11101101:
//Button 4 pressed
data = 4;
while (PINA == 0b11101101);
break;
case 0b11101011:
//Button 7 pressed
data = 7;
while (PINA == 0b11101011);
break;
case 0b11100111:
//Button * pressed
data = 14;
while (PINA == 0b11100111);
break;
case 0b11011110:
//Button 2 pressed
data = 2;
while (PINA == 0b11011110);
break;
case 0b11011101:
//Button 5 pressed
data = 5;
while (PINA == 0b11011101);
break;
case 0b11011011:
//Button 8 pressed
data = 8;
while (PINA == 0b11011011);
break;
case 0b11010111:
//Button 0 pressed
data = 0;
while (PINA == 0b11010111);
break;
case 0b10111110:
//Button 3 pressed
data = 3;
while (PINA == 0b10111110);
break;
case 0b10111101:
//Button 6 pressed
data = 6;
while (PINA == 0b10111101);
break;
case 0b10111011:
//Button 9 pressed
data = 9;
while (PINA == 0b10111011);
break;
case 0b10110111:
//Button # pressed
data = 15;
while (PINA == 0b10110111);
break;
case 0b01111110:
//Button A pressed
data = 10;
while (PINA == 0b01111110);
break;
case 0b01111101:
//Button B pressed
data = 11;
while (PINA == 0b01111101);
break;
case 0b01111011:
//Button C pressed
data = 12;
while (PINA == 0b01111011);
break;
case 0b01110111:
//Button D pressed
data = 13;
while (PINA == 0b01110111);
break;
}
}
}
}
int main(void)
{
DDRA = 0b00001111; //Port
A upper inputs, lower outputs
PORTA = 0b11111111; //Enable pull up on inputs,
send 1 to outputs
while (1)
{
/* Your code here */
Keyb (); //Check keyboard
/* Your code here */
}
}
Η ρουτίνα του πληκτρολογίου Keyb() καλείται μέσα από το κυρίως πρόγραμμα και
αποθηκεύει στη μεταβλητή data την πληροφορία από το πλήκτρο που
πατήθηκε. Στον κώδικα που παρουσιάστηκε αποθηκεύεται η αριθμητική τιμή του
πλήκτρου. Συνήθως το πάτημα ενός πλήκτρου διαρκεί 100 – 200ms,
συνεπώς θα πρέπει στο διάστημα αυτό να έχει ολοκληρωθεί ο βρόχος του κυρίως
προγράμματος ώστε να γίνει η κλήση της ρουτίνας του πληκτρολογίου στο χρόνο που
διαρκεί το πάτημα του πλήκτρου, διαφορετικά δε θα αναγνωριστεί. Αν ο βρόχος του
κυρίως προγράμματος διαρκεί αρκετό χρόνο θα πρέπει η ρουτίνα του πληκτρολογίου
να καλείται με διακοπή από έναν Timer του
μικροελεγκτή ή να καλείται η ρουτίνα σε διάφορα σημεία του προγράμματος. Σε
αυτές τις περιπτώσεις χρειάζεται προσοχή στη χρήση των δεδομένων της data ώστε να είναι ενημερωμένη όταν
διαβάζεται.
Όταν γίνει η κλήση της ρουτίνας Keyb() δίνεται αρχική τιμή 0b00000001
στη μεταβλητή line και στη
συνέχεια ξεκινάει ένας βρόχος με μια for
που επαναλαμβάνεται 4 φορές για τη σάρωση των γραμμών του πληκτρολογίου.
Ξεκινώντας ο βρόχος δίνεται τιμή στο PORTA το συμπλήρωμα της line
δηλαδή 0b11111110,
ώστε να ελεγχθεί η πρώτη γραμμή και γίνεται αριστερή ολίσθηση στην line για να προετοιμαστεί για τον
επόμενο κύκλο. Σε αυτό το σημείο μπορεί να εισαχθεί μια καθυστέρηση της τάξεως
του ms αν η συχνότητα λειτουργίας του μικροελεγκτή
είναι υψηλή (στο παράδειγμα υπάρχει ως σχόλιο). Ακολουθεί ένας βρόχος με μια while όπου η συνθήκη της ικανοποιείται
μόνο όταν υπάρχει πατημένο πλήκτρο σε αυτή τη γραμμή. Αν δεν υπάρχει πατημένο
πλήκτρο το πρόγραμμα συνεχίζει με τον επόμενο κύκλο της for. Δίνεται ξανά τιμή στο PORTA το συμπλήρωμα της line, ώστε να ελεγχθεί αυτή τη φορά η δεύτερη
γραμμή[1]
και γίνεται αριστερή ολίσθηση στην line
για να προετοιμαστεί για τον επόμενο κύκλο. Αν υπάρχει πατημένο πλήκτρο το πρόγραμμα
εισέρχεται στην while. Στην while εκτελείται αρχικά μια εντολή
καθυστέρησης για τους παρασιτικούς παλμούς και στη συνέχεια με την switch γίνεται
αναγνώριση του πλήκτρου και αποθήκευση της πληροφορίας στην data. Πριν την έξοδο από την switch με την break σε κάθε case υπάρχει μια while η οποία έχει ως συνθήκη ισότητα του PINA με τη σταθερά της αντίστοιχης case που βρίσκεται. Ο ρόλος της while είναι να σταματάει το πρόγραμμα
εκεί για όσο χρόνο είναι πατημένο το πλήκτρο, ώστε να μην καταχωρείται ως νέο
πάτημα κάθε φορά που καλείται η ρουτίνα. Το πρόγραμμα συνεχίζει τη λειτουργία
του με την απελευθέρωση του πλήκτρου. Αν είναι δύο πλήκτρα πατημένα στην ίδια
γραμμή δεν ικανοποιείται καμιά case και συνεπώς βγαίνει το πρόγραμμα από τη switch χωρίς να κάνει
καμία ενέργεια. Αν είναι πατημένα δύο πλήκτρα στην ίδια στήλη θα αναγνωριστεί
το πλήκτρο που η γραμμή του είναι σε χαμηλή λογική κατά τη σάρωση. Όταν
ολοκληρωθεί η σάρωση και των τεσσάρων γραμμών το πρόγραμμα εξέρχεται από τη
ρουτίνα του πληκτρολογίου.
©2016 Πορλιδάς Δημήτριος
|