Mikrokontroller ATMega16 memiliki fasilitas Analog to Digital Converter yang sudah built-in dalam chip. Fitur ADC internal inilah yang menjadi salah satu kelebihan mikrokontroler ATMega16 bila dibandingkan dengan beberapa jenis mikrokontroler yang lain. Dengan adanya ADC internal ini kita tidak akan direpotkan lagi dengan kompleksitas hardware saat membutuhkan proses pengubahan sinyal dari analog ke digital seperti yang harus dilakukan jika kita memakai komponen IC ADC eksternal.
ATmega16 memiliki resolusi ADC 10-bit dengan 8 channel input dan mendukung 16 macam penguat beda. ADC ini bekerja dengan teknik successive approximation. Rangkaian internal ADC ini memiliki catu daya tersendiri yaitu pin AVCC. Tegangan AVCC harus sama dengan VCC +- 0.3 V .
Data hasil konversi ADC dirumuskan sebagai berikut :
ADC = Vin.1024/Vref dimanan Vin : Tegangan masukan pada pin yang dipilih
Vref = tegangan referensi yang dipilih
Push Button dengan ADC
Dengan terbatasnya pin pada ATmega16 maka diperlukan penggunaan pin tersebut seefektif mungkin. Maka dari hal tersebut pemanfaatan ADC untuk mendeteksi banyak tombol dengan menggunakan prinsip pembagi tegangan. Dalam kasus projek ini menggunakan tiga buah tombol hanya memanfaatkan satu buah pin ADC yang biasannya tidak memanfaatkan ADC menggunakan minimal 3 buah pin.
- Prinsip pembagi tegangan :
Misal dalam sebuah rangkaian berikut :
R1= 1 k R2 = 2 k maka tegananya yang diukur pada titik V1 adalah pembagian dari R2/(R1+R2) * Vin = 2k/(1k+2k) * 5 V = 2/3 *5 = 3,3 Volt dan nilai V2 adalah sama dengan tegangan pada Vin yaitu 5 Volt. Berikut hasil pengukuran jika rangkaian tersebut disimulasikan :
Maka dengan cara yang sama dapat diterapkan pada projek ini yaitu pada rangkaian berikut :
- Bila PB1 ditekan dan tombol lain tidak ditekan maka nilai V1 yaitu
(R2+R3+R4) / (R1+R2+R3+R4) * Vin
= 3k/4k *5V = 3,75 volt.
- Bila PB2 ditekan dan tombol lain tidak ditekan maka nilai V2 yaitu
(R3+R4) / (R1+R2+R3+R4) * Vin
= 2k/4k *5V = 2,5 volt.
- Bila PB3 ditekan dan tombol lain tidak ditekan maka nilai V3 yaitu
(R4) / (R1+R2+R3+R4) * Vin
= 1k/4k *5V = 1,25 volt.
Saat PB1 ditekan :
Saat PB2 ditekan :
Saat PB3 ditekan :
Kemudian tegangan saat penekanan yang masih berupa data analog dikonversi menjadi data digital oleh feature ADC pada mikrokontroler. Feature ADC ini memiliki resolusi 10 bit yaitu maksimal memiliki nilai 1024 namun yang dipakai dalam projek ini hanya resolusi 8 bit dengan maksimal hasil konversi sebesar 256, Sedangkan tegangan referensi yang dipakai sama dengan teganan input sebesar 5 volt. Persamaan konversi data analog menjadi data digital :
ADC = Vin.256/Vref dimanan Vin : Tegangan masukan pada pin yang dipilih
Vref = tegangan referensi yang dipilih.
Jadi pada saat PB ditekan maka secara perhitungan nilai ADC hasil konversi yaitu :
- Saat PB1 ditekan à (3.75 * 256)/ 5 = 192
- Saat PB2 ditekan à (2.5 * 256)/ 5 = 128
- Saat PB3 ditekan à (1.25 * 256)/ 5 = 64
Dan hasil data digital tersebut ditampilkan pada LCD saat ada penekanan push button, kemudian melalui sebuah rumus data digital tersebut dirubah lagi agar bisa ditampilkan data analognya dalam LCD melalui sebuah program. è (dataADC * 5)/ 256 = dataADC * 0.0196 .
berikut listing program :
Instruksi Program
#include <mega16.h>
#include <stdio.h>
#include <delay.h>
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd.h>
#include <delay.h>
char lcd_buffer[33];
#define ADC_VREF_TYPE 0x20
// Read the 8 most significant bits
// of the AD conversion result
unsigned char read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCH;
}
void cek(int tes,float vin2)
{
if(tes>187 && tes<200)
{
lcd_clear();
lcd_gotoxy(0,0);
sprintf(lcd_buffer,”ADC:%d V:%0.1fV”,tes,vin2);
lcd_puts(lcd_buffer);
lcd_gotoxy(0,1);
lcd_putsf(“tombol 1″);
PORTD.0=0;
PORTD.1=1;
PORTD.2=1;
}
else if(tes>125 && tes<130)
{
lcd_clear();
lcd_gotoxy(0,0);
sprintf(lcd_buffer,”ADC:%d V:%0.1fV”,tes,vin2);
lcd_puts(lcd_buffer);
lcd_gotoxy(0,1);
lcd_putsf(“tombol 2″);
PORTD.0=1;
PORTD.1=0;
PORTD.2=1;
}
else if(tes>60 && tes<70)
{
lcd_clear();
lcd_gotoxy(0,0);
sprintf(lcd_buffer,”ADC:%d V:%0.1fV”,tes,vin2);
lcd_puts(lcd_buffer);
lcd_gotoxy(0,1);
lcd_putsf(“tombol 3”);
PORTD.0=1;
PORTD.1=1;
PORTD.2=0;
}
}
// Declare your global variables here
void main(void)
{
float vin1;
unsigned int temp1;
// Declare your local variables here
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x0F;
DDRA=0x00;
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T tate3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;
// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;
// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0xFF;
DDRD=0xFF;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// ADC initialization
// ADC Clock frequency: 691.200 kHz
// ADC Voltage Reference: AREF pin
// ADC Auto Trigger Source: None
// Only the 8 most significant bits of
// the AD conversion result are used
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x84;
// LCD module initialization
lcd_init(16);
lcd_gotoxy(0,0);
lcd_putsf(“Keypad With ADC”);
while (1)
{
// Place your code here
temp1=read_adc(0);
vin1=((float)temp1*0.0196);
cek(temp1,vin1);
};
}