Bismillah..
Berawal dari mencoba mempraktekkan teori cara kerja (scan) pembacaan keypad, sehingga Sy bisa share hasilnya disini. :)
Salah satu perangkat yang sering dibutuhkan pada aplikasi mikrokontroler adalah kemampuan berinteraksi dengan pengguna peralatan tersebut. Salah satu cara berinteraksi dengan pengguna adalah dengan menggunakan keypad. Di sini akan kita pelajari tentang pemrograman keypad 3x4 pada mikrokontroler AVR128 dengan menggunakan Code Vision.
Berikut adalah contoh gambar fisik keypad yang sering digunakan:
Keypad tersebut memiliki konfigurasi internal berupa skema berbentuk matrix baris (ROW) dan kolom (COL) sebagai berikut:
Pada mikrokontroler setiap COLOM keypad akan dihubungkan dengan pin "output" mikrokontroler. Sedangkan pada setiap ROW keypad akan dihubungkan dengan pin "input" mikrokontroler.
Salah satu cara untuk membaca data dari matrix keypad adalah dengan teknik scanning,
dimana baris atau kolom selalu discan untuk mendeteksi tombol yang
ditekan. Caranya yaitu dengan memberikan status ‘0’ (low) pada salah satu pin COL (dan yg lain kondisi HIGH)
secara bergantian, lalu pin ROW dideteksi apakah ada salah satunya yang
berkondisi ‘0’ (low). Berikut ilustrasi urutan scaning dan pembacaan keypad:
- Apabila Kolom 1 diberi logika ‘0’, kolom kedua dan kolom ketiga diberi logika ‘1’ maka program akan mengecek tombol 1, 4, 7, dan *, sehingga apabila salah satu baris berlogika '0' maka ada tombol yang ditekan.
- Apabila Kolom 2 diberi logika ‘0’, kolom pertama dan kolom ketiga diberi logika ‘1’ maka program akan mengecek tombol 2, 5, 8, dan 0, sehingga apabila salah satu baris berlogika '0' maka ada tombol yang ditekan.
- Apabila Kolom 3 diberi logika ‘0’, kolom pertama dan kolom kedua diberi logika ‘1’ maka program akan mengecek tombol 3, 6, 9, dan #, sehingga apabila salah satu baris berlogika '0' maka ada tombol yang ditekan.
Cara ini dilakukan secara terus menerus sehingga setiap kali keypad ditekan maka akan langsung terdeteksi posisi tombol yang ditekan.
Kali ini Sy akan mencontohkan pemrograman keypad dan menampilkannya pada LCD 16x2 sehingga mudah mengecek tombol yang ditekan. LCD Sy hubungkan dengan PORTC sedangkan Keypad Sy hubungkan dengan PORTE, dengan konfigurasi keypad sebagai Berikut
row1 -> PINE.0
row2 ->PINE.1
row3 ->PINE.2
row4 ->PINE.3
col1 ->PINE.6
col2 ->PINE.5
col3 ->PINE.4
row2 ->PINE.1
row3 ->PINE.2
row4 ->PINE.3
col1 ->PINE.6
col2 ->PINE.5
col3 ->PINE.4
Berikut skema proteusnya
Pada program kali ini Sy membuat procedure bernama keypad(), yang kemudian prosedur keypad() tersebut akan dieksekusi oleh Timer0 secara terus menerus dan akan mengupdate posisi tombol yg ditekan (bila ada). Penggunaan Timer ini cukup penting karena Timer bisa bekerja secara paralel dengan program utama pada mikrokontroler itu sendiri. (Tolong dicross cek apabila salah).
Berikut adalah coding untuk konfigurasinya:
#include <alcd.h>
#include <stdio.h>
unsigned char text[16],nilai_keypad; /*kalo ada yg tdk sesuai pada saat awal sebelum ada tombol yg ditekan maka perlu inisialisasi nilai_keypad=13 (angka diluar range angka yang benar)*/
#include <stdio.h>
unsigned char text[16],nilai_keypad; /*kalo ada yg tdk sesuai pada saat awal sebelum ada tombol yg ditekan maka perlu inisialisasi nilai_keypad=13 (angka diluar range angka yang benar)*/
// Port E initialization
// Func7=In Func6=Out Func5=Out Func4=Out Func3=In Func2=In Func1=In Func0=In
// State7=T State6=0 State5=0 State4=0 State3=P State2=P State1=P State0=P
PORTE=0x0F;
DDRE=0x70;
// Func7=In Func6=Out Func5=Out Func4=Out Func3=In Func2=In Func1=In Func0=In
// State7=T State6=0 State5=0 State4=0 State3=P State2=P State1=P State0=P
PORTE=0x0F;
DDRE=0x70;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 10000.000 kHz
// Mode: Normal top=0xFF
// OC0 output: Disconnected
ASSR=0x00;
TCCR0=0x01;
TCNT0=0x00;
OCR0=0x00;
// Clock source: System Clock
// Clock value: 10000.000 kHz
// Mode: Normal top=0xFF
// OC0 output: Disconnected
ASSR=0x00;
TCCR0=0x01;
TCNT0=0x00;
OCR0=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x02;
ETIMSK=0x00;
// Alphanumeric LCD initialization
// Connections are specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTC Bit 0
// RD - PORTC Bit 2
// EN - PORTC Bit 1
// D4 - PORTC Bit 4
// D5 - PORTC Bit 5
// D6 - PORTC Bit 6
// D7 - PORTC Bit 7
// Characters/line: 16
lcd_init(16);
// Global enable interrupts
#asm("sei")
TIMSK=0x02;
ETIMSK=0x00;
// Alphanumeric LCD initialization
// Connections are specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTC Bit 0
// RD - PORTC Bit 2
// EN - PORTC Bit 1
// D4 - PORTC Bit 4
// D5 - PORTC Bit 5
// D6 - PORTC Bit 6
// D7 - PORTC Bit 7
// Characters/line: 16
lcd_init(16);
// Global enable interrupts
#asm("sei")
Program Procedure keypad()
unsigned char keypad(){
unsigned char x,i,j;
bit y;
x=0b01000000;
for (i=0;i<3;i++) {
PORTE =~((x>>i) & 0x70);
for (j=0;j<4;j++) {
y=(PINE >> j) & 0x1;
if(y==0) return((i+1)+(3*j));
unsigned char x,i,j;
bit y;
x=0b01000000;
for (i=0;i<3;i++) {
PORTE =~((x>>i) & 0x70);
for (j=0;j<4;j++) {
y=(PINE >> j) & 0x1;
if(y==0) return((i+1)+(3*j));
//rumus ini untuk menentukan posisi sesuai baris dan kolom
}
}
}
}
}
}
Scaning keypad() pada Timer0 supaya dilakukan scan terus menerus
// Timer 0 output compare interrupt service routine
interrupt [TIM0_COMP] void timer0_comp_isr(void)
{
// Place your code here
nilai_keypad=keypad();
}
interrupt [TIM0_COMP] void timer0_comp_isr(void)
{
// Place your code here
nilai_keypad=keypad();
}
Program utama sekaligus mengecek apakah benar nilai_keypad selalu discan oleh Timer0
while (1)
{
// Place your code here
lcd_gotoxy(0,0);
lcd_putsf("* Program Utama ");
lcd_gotoxy(0,0);
lcd_putsf("**--Cek--** ");
//mengecek apakah nilai_keypad selalu update
lcd_gotoxy(0,1);
if(nilai_keypad<10){
sprintf(text,"%u",nilai_keypad);
lcd_puts(text);}
else if(nilai_keypad==10) lcd_putsf("*");
else if(nilai_keypad==11) lcd_putsf("0");
else if(nilai_keypad==12) lcd_putsf("#");
}
{
// Place your code here
lcd_gotoxy(0,0);
lcd_putsf("* Program Utama ");
lcd_gotoxy(0,0);
lcd_putsf("**--Cek--** ");
//mengecek apakah nilai_keypad selalu update
lcd_gotoxy(0,1);
if(nilai_keypad<10){
sprintf(text,"%u",nilai_keypad);
lcd_puts(text);}
else if(nilai_keypad==10) lcd_putsf("*");
else if(nilai_keypad==11) lcd_putsf("0");
else if(nilai_keypad==12) lcd_putsf("#");
}
Alhamdulillah akhirnya berhasil jg menerapkan teori keypad ini.. hehe simple tapi harus teliti memang..
Catatan: Procedure keypad() bisa dieksekusi langsung di program utama tanpa menggunakan Timer. Sy hanya mengetes kinerja Timer saja..