Catatan : Untuk mempelajari tutorial ini agar memulai dengan praktek dasar input/output dan jam 7segmen
Tombol atau keypad merupakan alat input yg umum digunakan. Sebagai dasarnya adalah tactile switch seperti gambar berikut ini :
Gambar dikiri adalah contoh tactile switch (switch yg sensitif dan sekali sentuh) dan gambar dikanan adalah koneksi umum menggunakan pull up resistor 10k ohm , yang nantinya akan memberikan input dari logika HIGH (vcc) menuju logika LOW (gnd). Fungsi dari resistor adalah sebagai pembatas arus saat tombol ditekan sehingga tidak terjadi short antara vcc dan ground. Pada penekanan tombol yang akan kita cek adalah kondisi turun atau naik (menggunakan interupt) atau kondisi High / Low dengan teknik scanning. Kali ini akan dibahas metode scanning dengan script dasar pembacaan tombol sebagai berikut :
if (bit_is_clear(PIND, PIND5)) //tombol ada di pin D5
{
// kondisi yg diinginkan ditulis disini
_delay_ms(200); // delay untuk mengatasi de-bounching efek
}
Juga agar diperhatikan untuk mengeset pin D5 sebagai pin input pada inisialisasi port. Jika ingin menambahkan tombol lainnya cukup hanya dengan menambahkan rangkaian yg sama dan pencabangan di script if..else if. Jika memerlukan banyak tombol maka banyak pula pin microcontroller yang digunakan. Ada suatu teknik yg umum digunakan yaitu teknik scanning matrix dari tombol dengan mengubah pembacaan input dan output seperti yg biasanya kita dapatkan pada keypad matrix dibawah ini :
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.
(klik pada gambar untuk memperjelas)
Sedangkan script lengkap pada percobaan ini sebagai berikut :
#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