Tombol atau keypad merupakan alat input yg umum digunakan. Sebagai dasarnya adalah tactile switch seperti gambar berikut ini :
{
_delay_ms(200); // delay untuk mengatasi de-bounching efek
}
Gambar diatas menjelaskan bagaimana kombinasi dari 2 buah pin yang terhubung dan kemudian mewakili penekanan keypad. Keuntungan dari penggunaan matrix ini adalah berkurangnya penggunaan pin micro, yg seharusnya 12 pin menjadi hanya 7 pin Input Output saja. Mekanisme untuk pembacaan adalah dengan melakukan scanning dari kolom atau baris (pilih salah satu , digunakan sebagai OUTPUT) dan kemudian melakukan pembacaan pada pin yg dibuat sebagai INPUT.
Contoh penjabarannya adalah seperti berikut:
- Row / Baris digunakan sebagai OUTPUT dan Micro akan membaca 3 pin Kolom
- Micro akan melakukan output scanning "LOW" pada 4 pin baris (0111, 1011, 1101, 1110) secara bergantian
- Micro kemudian akan membaca adakah input yg juga bernilai "LOW" , semisal saat scanning 0111 (paling kiri row 3), maka jika kolom 0 (sesuaikan pin microcontroller) bernilai "LOW" berarti yg ditekan adalah tombol " * " bintang begitu pula jika kolom 1 bernilai "LOW" maka yang ditekan adalah tombol " 0 ".
- Pemilihan scanning aktif "LOW" atau "High" tergantung dari perlakuan pull up atau pull down dari pin input dalam hal ini pin kolom.
Secara scipt akan menjadi seperti ini :
uint8_t tombol(void)
{
uint8_t key=100; // nilai awal jika tidak ada penekanan
PORTD &= ~_BV(PD3);
PORTD |= _BV(PD4)|_BV(PD5)|_BV(PD6); // scanning 0111
_delay_ms(1);
// berikut ini pembacaan tombol kolom sebagai input
if(bit_is_clear(PIND, PIND0))
{
key= 1;
}
else if(bit_is_clear(PIND, PIND1))
{
key= 2;
}
else if(bit_is_clear(PIND, PIND2))
{
key= 3;
}
PORTD &= ~_BV(PD4);
PORTD |= _BV(PD3)|_BV(PD5)|_BV(PD6); // scanning 1011
_delay_ms(1);
// berikut ini pembacaan tombol kolom sebagai input
if(bit_is_clear(PIND, PIND0) )
{key= 4;
}
else if(bit_is_clear(PIND, PIND1) )
{
key= 5;
}
else if(bit_is_clear(PIND, PIND2) )
{
key= 6;
}
PORTD &= ~_BV(PD5);
PORTD |= _BV(PD4)|_BV(PD3)|_BV(PD6); // scanning 1101
_delay_ms(1);
// berikut ini pembacaan tombol kolom sebagai input
if(bit_is_clear(PIND, PIND0) )
{key= 7;
}
else if(bit_is_clear(PIND, PIND1) )
{
key= 8;
}
else if(bit_is_clear(PIND, PIND2) )
{
key= 9;
}
PORTD &= ~_BV(PD6);
PORTD |= _BV(PD4)|_BV(PD5)|_BV(PD3); // scanning 1110
_delay_ms(1);
// berikut ini pembacaan tombol kolom sebagai input
if(bit_is_clear(PIND, PIND1) )
{
key= 0;
}
else if(bit_is_clear(PIND, PIND2))
{
key= 21; //mewakili *
}
else if(bit_is_clear(PIND, PIND0) )
{key= 20; //mewakili #
}
return key; // nilai integer dari variable key dikembalikan ke pemanggil
}
Dengan mengasumsikan bahwa pembaca sudah melakukan praktek microcontroller "jam sederhana" maka kita dapat melanjutkan menuju ke praktek sesungguhnya. Skematik dapat dilihat pada gambar berikut, menggunakan micro AVR ATMEGA8535 , micro lain tinggal menyesuaikan.
#define F_CPU 1000000L #include <avr/io.h> #include <util/delay.h> uint8_t pencet, angka[4]; void segmen(int digit) // konversi angka ke segmen { switch (digit) { case 0 : { PORTC &= ~_BV(PC0) & ~_BV(PC1) & ~_BV(PC2) & ~_BV(PC3) & ~_BV(PC4) & ~_BV(PC5); PORTC |= _BV(PC6); break; } case 1 : { PORTC &= ~_BV(PC1) & ~_BV(PC2); PORTC |= _BV(PC0)| _BV(PC3)| _BV(PC4)| _BV(PC5)| _BV(PC6); break; } case 2 : { PORTC &= ~_BV(PC0) & ~_BV(PC1) & ~_BV(PC6) & ~_BV(PC4) & ~_BV(PC3); PORTC |= _BV(PC2)| _BV(PC5) ; break; } case 3 : { PORTC &= ~_BV(PC0) & ~_BV(PC1) & ~_BV(PC2) & ~_BV(PC3) & ~_BV(PC6); PORTC |= _BV(PC4)| _BV(PC5) ; break; } case 4 : { PORTC &= ~_BV(PC5) & ~_BV(PC1) & ~_BV(PC2) & ~_BV(PC6) ; PORTC |= _BV(PC3)| _BV(PC4) | _BV(PC0); break; } case 5 : { PORTC &= ~_BV(PC0) & ~_BV(PC2) & ~_BV(PC3) & ~_BV(PC6) & ~_BV(PC5); PORTC |= _BV(PC1) | _BV(PC4); break; } case 6 : { PORTC &= ~_BV(PC0) & ~_BV(PC2) & ~_BV(PC3) & ~_BV(PC6) & ~_BV(PC5) & ~_BV(PC4); PORTC |= _BV(PC1) ; break; } case 7 : { PORTC &= ~_BV(PC0) & ~_BV(PC1) & ~_BV(PC2); PORTC |= _BV(PC3)| _BV(PC4)| _BV(PC5)| _BV(PC6); break; } case 8 : { PORTC &= ~_BV(PC0) & ~_BV(PC1) & ~_BV(PC2) & ~_BV(PC3) & ~_BV(PC4) & ~_BV(PC5) & ~_BV(PC6); break; } case 9 : { PORTC &= ~_BV(PC0) & ~_BV(PC1) & ~_BV(PC2) & ~_BV(PC3) & ~_BV(PC5) & ~_BV(PC6); PORTC |= _BV(PC4); break; } case 10 : { PORTC |= _BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3)| _BV(PC4) | _BV(PC5) | _BV(PC6) ; break; } } } void posisi(uint8_t pos) //posisi scanning 7 segmen { switch (pos) { case 0 : { PORTA &= ~_BV(PA4) & ~_BV(PA5)& ~_BV(PA6) & ~_BV(PA7) ; break; } case 1 : { PORTA |= _BV(PA4); PORTA &= ~_BV(PA5) & ~_BV(PA6) & ~_BV(PA7) ; break; } case 2 : { PORTA |= _BV(PA5); PORTA &= ~_BV(PA4) & ~_BV(PA6) & ~_BV(PA7) ; break; } case 3 : { PORTA |= _BV(PA6); PORTA &= ~_BV(PA4) & ~_BV(PA5) & ~_BV(PA7) ; break; } case 4 : { PORTA |= _BV(PA7); PORTA &= ~_BV(PA4) & ~_BV(PA5) & ~_BV(PA6) ; break; } } } void tulis(void) //menulis angka ke 7 segmen { posisi(1); if( pencet <1) segmen(10); else segmen(angka[0]); } _delay_us(300); segmen(10); posisi(2); if( pencet <2) segmen(10); else segmen(angka[1]); } _delay_us(300); segmen(10); posisi(3); if( pencet <3) segmen(10); else segmen(angka[2]); } _delay_us(300); segmen(10); posisi(4); if( pencet <4) segmen(10); else segmen(angka[3]); } _delay_us(300); segmen(10); } uint8_t tombol(void) //penerjemahan penekanan tombol { uint8_t key=100; PORTD &= ~_BV(PD3); PORTD |= _BV(PD4)|_BV(PD5)|_BV(PD6); _delay_ms(1); if(bit_is_clear(PIND, PIND0) ) {key= 1; } else if(bit_is_clear(PIND, PIND1) ) { key= 2; } else if(bit_is_clear(PIND, PIND2)) { key= 3; } PORTD &= ~_BV(PD4); PORTD |= _BV(PD3)|_BV(PD5)|_BV(PD6); _delay_ms(1); if(bit_is_clear(PIND, PIND0) ) {key= 4; } else if(bit_is_clear(PIND, PIND1) ) { key= 5; } else if(bit_is_clear(PIND, PIND2) ) { key= 6; } PORTD &= ~_BV(PD5); PORTD |= _BV(PD4)|_BV(PD3)|_BV(PD6); _delay_ms(1); if(bit_is_clear(PIND, PIND0) ) {key= 7; } else if(bit_is_clear(PIND, PIND1) ) { key= 8; } else if(bit_is_clear(PIND, PIND2) ) { key= 9; } PORTD &= ~_BV(PD6); PORTD |= _BV(PD4)|_BV(PD5)|_BV(PD3); _delay_ms(1); if(bit_is_clear(PIND, PIND1) ) { key= 0; } else if(bit_is_clear(PIND, PIND2) ) { key= 21; // mewakili * } else if(bit_is_clear(PIND, PIND0) ) {key= 20; // mewakili # } return key; } int main(void) { uint8_t keypad; DDRA |= _BV(PA5) | _BV(PA6) | _BV(PA7) | _BV(PA4) ; //scanning 7 segmen DDRC |= _BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3) | _BV(PC4) | _BV(PC5) | _BV(PC6) ; //segmen //keypad DDRD &= ~_BV(PD0) & ~_BV(PD1) & ~_BV(PD2); //col DDRD |= _BV(PD3) | _BV(PD4) | _BV(PD5) | _BV(PD6); //row pencet=0; angka[0]=1; angka[1]=2; angka[2]=3; angka[3]=4; while(1) { keypad=tombol(); if(keypad!= 100 && pencet == 0) { angka[0]=keypad; pencet = 1; _delay_ms(150); } else if(keypad!= 100 && pencet == 1) { angka[1]=keypad; pencet = 2; _delay_ms(150); } else if(keypad!= 100 && pencet == 2) { angka[2]=keypad; pencet = 3; _delay_ms(150); } else if(keypad!= 100 && pencet == 3) { angka[3]=keypad; pencet = 4; _delay_ms(150); } if(keypad == 21 || keypad == 20) // penekanan * atau # membersihkan 7 segmen { pencet = 0; _delay_ms(150); } } return 0; }
SELAMAT MENCOBA