A gombmátrix leteszteléséhez egy ATMEL ATmega88-20PU típusú AVR mikrovezérlőt és egy 2x7-szegmenses LED-kijelzőt használtam.
Az ATmega88-20PU egy 28 lábú jószág, és tudásához képest olcsó.
Mielőtt megnéznénk a tasztatúrát működés közben, nézzük meg a mikrovezérlőben futó programot.
A 7-szegmenses kijelző az AVR B portjára van kötve. Mivel a 7-szegmenses kijelzőkön van egy pont is, így teljesen ki tudjuk használni a mikrovezérlő portját, mivel a B portnak 8 kivezetése / portlába van (0-tól 7-ig). Az én 2x7-szegmenses kijelzőm nincs gyárilag multiplexelve, így ezt bedugós panelon vezetékekkel kellett megoldjam. Aki még nem multiplexelt, az könnyen elsajátíthatja a módszert Topi cikke alapján.
Íme a kód:
#include <avr/io.h>
#include <util/delay.h>
unsigned char characters[10] = { // Egy 10 elemű tömbben felvesszük az egyes számok bináris formáit, és itt nem a reális bináris formára gondolok, hanem az AVR lábainak bekötéséből adódó bináris számsorra.
//PB portok 76543210 - ezek a B port lábainak sorszámai
/* 0 */ 0b01000000,
/* 1 */ 0b01111001,
/* 2 */ 0b00100100,
/* 3 */ 0b00110000,
/* 4 */ 0b00011001,
/* 5 */ 0b00010010,
/* 6 */ 0b00000010,
/* 7 */ 0b01011000,
/* 8 */ 0b00000000,
/* 9 */ 0b00010000,
};
unsigned char beolvas(void) { // Ez a beolvasófüggvény fog
// gondoskodni a tasztatúra kezeléséről.
DDRB = 0b00000010; // Itt végezzük el a portváltásokat
PORTB = 0b00011100;
_delay_us(100); // Megvárjuk, míg a portváltások aktualizálódnak
if ((PINB & (1<<PINB2)) == 0) { // Elvégezzük az ellenőrzéseket
return 1;
}
if ((PINB & (1<<PINB3)) == 0) {
return 2;
}
if ((PINB & (1<<PINB4)) == 0) {
return 3;
}
DDRB = 0b00000000; // Visszaállítunk minden portot
_delay_us(100); // Ismét várakozunk
DDRB = 0b00000100; // Innentől ugyanaz a logika, csak más lábakon
PORTB = 0b00011010;
_delay_us(100);
if ((PINB & (1<<PINB1)) == 0) {
return 4;
}
if ((PINB & (1<<PINB3)) == 0) {
return 5;
}
if ((PINB & (1<<PINB4)) == 0) {
return 6;
}
DDRB = 0b00000000;
_delay_us(100);
DDRB = 0b00001000;
PORTB = 0b00010110;
_delay_us(100);
if ((PINB & (1<<PINB1)) == 0) {
return 7;
}
if ((PINB & (1<<PINB2)) == 0) {
return 8;
}
if ((PINB & (1<<PINB4)) == 0) {
return 9;
}
DDRB = 0b00000000;
_delay_us(100);
DDRB = 0b00010000;
PORTB = 0b00001110;
_delay_us(100);
if ((PINB & (1<<PINB1)) == 0) {
return 10;
}
if ((PINB & (1<<PINB2)) == 0) {
return 11;
}
if ((PINB & (1<<PINB3)) == 0) {
return 12;
}
DDRB = 0b00000000;
_delay_us(100);
return 0;
}
void kiiras(unsigned char mit) { // A kiírás függvényt a főprogramban paraméterezve fogjuk meghívni, és a paraméter a beolvas függvény
unsigned char mit10es = mit/10; // A beolvas függvény visszatérési értékét simán elosztjuk 10-zel...
unsigned char mit1es = mit%10; // ...majd ismét elosztjuk, de itt maradékos osztást csinálunk.
DDRC = 0b00000011; // Beállítjuk a portok állapotát
DDRD = 0b01111111;
PORTC = 0b00000010; // Itt kapcsolunk közöst a 10-es helyiértéken lévő szegmensnek...
PORTD = characters[mit10es]; // ...és kiírjuk az osztás eredményét ide.
_delay_ms(5); // Várunk... :S
PORTC = 0b00000001; // Itt kapcsolunk közöst az 1-es helyiértéken lévő szegmensnek...
PORTD = characters[mit1es]; // ...majd a maradékos osztás eredményét íratjuk ki ide.
_delay_ms
(5);
// Hadd ne mondjam...
}
int main(void) {
MCUCR = MCUCR & (!(1<<PUD));
while (1) { // Egy végtelen ciklus felel a program folyamatos futásáért.
kiiras(beolvas()); // Íme a fentebb említett paraméterezéses módszer.
}
}
A cikk még nem ért véget, lapozz!
Értékeléshez bejelentkezés szükséges!