Top Banner
AVR Digital Voltmeter (LCD Display & CodeVisionAVR) Posted by Herlambang on May 16, 2011 Leave a comment (7) Go to comments Mengukur tegangan dan menampilkan hasil pengukuran pada LCD nama kerennya (DIGITAL VOLT METER) adalah hal yang mudah, apalagi dengan CodeVisionAVR , semuanya jadi leb mudah. Sebagai contoh, kita akan membuat program yang bisa mengukur tegangan antara 5V dengan ketelitian tegangan yang dapat diukur sebesar 0.00488V atau 4.88mV. Dalam ap kita akan menggunakan ADC internal AVR dengan resolusi maksimal 10bit dengan data m dari 0 1023 atau 2n-1 dan jumlah total data 1024. Untuk menentukan ketelitian yang a diperoleh sangat mudah, yaitu dengan membagi nilai tegangan referensi dengan resolu Misal tegangan referensi yang kita pakai adalah AVCC yang bernilai 5V maka akan did resolusi sebesar 0.00488V yang didapat dari 5/1024 = 0.00488V atau 4.88mV. Contoh d diasumsikan bahwa tegangan AVCC adalah bernilai pas 5V. Untuk aplikasi riil dengan kepresisian tinggi disarankan untuk melakukan trim tegan pembagi tegangan yang menggunakan multiturn VR dan buffer DC dan gunakan referensi Vref bukan AVCC . Akan tetapi kalau hanya sekedar ingin mengetahui nilai tegangan t kepresisian tinggi, referensi pada AVCC sudah cukup. Dan bila diinginkan mengukur t dengan level yang lebih tinggi, bisa digunakan pembagi tegangan seperti pada voltme
6

AVR Digital Voltmeter

Jul 21, 2015

Download

Documents

Bejojo Bejo
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript

AVR Digital Voltmeter (LCD Display & CodeVisionAVR)Posted by Herlambang on May 16, 2011 Leave a comment (7) Go to comments Mengukur tegangan dan menampilkan hasil pengukuran pada LCD nama kerennya (DIGITAL VOLT METER) adalah hal yang mudah, apalagi dengan CodeVisionAVR , semuanya jadi lebih mudah. Sebagai contoh, kita akan membuat program yang bisa mengukur tegangan antara 0 5V dengan ketelitian tegangan yang dapat diukur sebesar 0.00488V atau 4.88mV. Dalam aplikasi ini kita akan menggunakan ADC internal AVR dengan resolusi maksimal 10bit dengan data mulai dari 0 1023 atau 2n-1 dan jumlah total data 1024. Untuk menentukan ketelitian yang akan diperoleh sangat mudah, yaitu dengan membagi nilai tegangan referensi dengan resolusi ADC. Misal tegangan referensi yang kita pakai adalah AVCC yang bernilai 5V maka akan didapatkan resolusi sebesar 0.00488V yang didapat dari 5/1024 = 0.00488V atau 4.88mV. Contoh disini diasumsikan bahwa tegangan AVCC adalah bernilai pas 5V.

Untuk aplikasi riil dengan kepresisian tinggi disarankan untuk melakukan trim tegangan dengan pembagi tegangan yang menggunakan multiturn VR dan buffer DC dan gunakan referensi pada Vref bukan AVCC . Akan tetapi kalau hanya sekedar ingin mengetahui nilai tegangan tanpa kepresisian tinggi, referensi pada AVCC sudah cukup. Dan bila diinginkan mengukur tegangan dengan level yang lebih tinggi, bisa digunakan pembagi tegangan seperti pada voltmeter digital

dan tentu saja jangan lupa saklar bwt select range dan lagi.. jangan lupa modifikasi programnya hehe . Wokey lets check it out#include #include #include // Alphanumeric LCD Module functions #asm .equ __lcd_port=0x18 ;PORTB #endasm #include

Seperti code diatas, tentukan dulu library yang mo dipake.. berhugung kita akan menggunakan LCD, delay dan fungsi sprintf jadi kita include librarinya masing2. Jangan lupa sesuaikan port yang akan digunakan untuk LCD.#define ADC_VREF_TYPE 0x40 //AVCC

Yang tak kalah pentingnya adalah menentukan referensi untuk ADC. Dalam program ini ane gunakan referensi AVCC.unsigned char buffer[16]; //Untuk buffer sprintf float tegangan; //Untuk data perhitungan tegangan (float) unsigned int temporary; //Untuk temporary data ADC (komparasi)

code diatas berfungsi untuk menentukan variable global yang akan digunakan.. buffer berfungsi untuk buffer sprintf. Berhubung sprintf disini akan digunakan dalam formating LCD jadi cukup dah arraynya cuman 16 char. Sedangkan untuk variabel tegangan berfungsi untuk menampung perhitungan hasil bagi dari (data ADC*(referensi/1024)/1000) tipe datanya adalah float biar presisi hasil pembacaanya . nah kalo variabel temporary berfungsi cuman untuk pembanding data ADC yang sebelumnya tersimpan dan data ADC terbaca (bwt update aja biar gk terus kerja LCDnya).void sett_regs(void); //Fungsi untuk setting register di awal proses unsigned int read_adc(unsigned char adc_input);//Fungsi baca ADC

code yang tertulis persis diatas tulisan ini adalah cuman untuk function prototype dan digunakan bila fungsi main mau diletakkan dimana saja termasuk diatas fungsi tersebut.// Routine baca ADC unsigned int 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 ADCW;

}

Fungsi diatas digunakan untuk pengambilan data ADC. Bila dipanggil akan mengembalikan nilai berupa data ADC terbaru dengan tipe unsigned int.// Function for setting register void sett_regs(void){ // Port a initialization PORTA=0x00;DDRA=0x00; // Port b initialization PORTB=0x00;DDRB=0x00; // Port c initialization PORTC=0x00;DDRC=0x00; // Port D initialization PORTD=0x00;DDRD=0x00; // ADC initialization // ADC Clock frequency: 1000.000 kHz // ADC Voltage Reference: AVCC pin // ADC Auto Trigger Source: Free Running ADMUX=ADC_VREF_TYPE & 0xff; ADCSRA=0xA2; SFIOR&=0x1F; // LCD module initialization lcd_init(16); // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x00; ACSR=0x80; SFIOR=0x00; // Watchdog Timer initialization // Watchdog Timer Prescaler: OSC/2048k #pragma optsizeWDTCR=0x1F; WDTCR=0x0F; #ifdef _OPTIMIZE_SIZE_ #pragma optsize+ #endif }

Fungsi diatas untuk inisialisasi register port maupun SFR. Silahkan baca sendiri ada keterangannya disamping atau diatas baris code.// Main function void main(void){ //--------------- Setting IO and peripheral at startup! sett_regs(); _lcd_ready(); //--------------- Time for going CRAZY (looping forever).. for(;;){ //mainloop looping forever until ERROR/POWER SHUTDOWN/RST/WDT ACTIVE #asm("wdr") //kick your DOG before timeout! hwahwa... :D if (temporary != read_adc(0)){ tegangan = (read_adc(0)*4.8828125)/1000; lcd_gotoxy(0,0);

lcd_putsf("WWW.NUBIELAB.COM");//Don't forget to visit :) lcd_gotoxy(0,1); sprintf(buffer,"TEGANGAN: %0.2fV",tegangan); lcd_puts(buffer); temporary = read_adc(0); delay_ms(100); } #asm("nop") }; }

Fungsi yang paling penting dalam C yaitu main() dalam fungsi ini terdapat kode yang berfungsi untuk pengolahan data ADC sampai dengan formatting character untuk ditampilkan di LCD. Pengambilan dan penulisan data tegangan tidak dilakukan secara terus menerus.. tapi menunggu perubahan nilai dulu. Kasihan kalo LCDnya dipenetrasi terus menerus haha.. OK, berikut adalah listing program komplitnya:/*__ ___ __ __ ___ ___ ___ ___ _ _ |_ _| ___ | / |_ _|/ __| _ / _ | | - eMBEDDED Design & | || |) ||___|| |/| || | (__| / (_)| .` | - System Development |___|___/ |_| |_|___|___|_|_\___/_|_|______________________+ ;Homepage : http://www.nubielab.com ;Email : [email protected] ;Code by : Herlambang Aribowo. -----------input tegangan dihubungkan ke PINA.0 atau ADC 0 dalam aplikasi real, mungkin diperlukan buffer dan bisa dibuat dari opamp single supply misal LM358. Jangan lupa kalo mo dibuat beneran, PIN AVCC dan VREF ADC dihubungkan ke tegangan 5V yg stabil. Atmega16 X-tall 4Mhz ;*/ #include #include #include // Alphanumeric LCD Module functions #asm .equ __lcd_port=0x18 ;PORTB #endasm #include //#define ADC_VREF_TYPE 0xC0 //Internal //#define ADC_VREF_TYPE 0x00 //AREF #define ADC_VREF_TYPE 0x40 //AVCC unsigned char buffer[16]; //Untuk buffer sprintf float tegangan; //Untuk data perhitungan tegangan (float) unsigned int temporary; //Untuk temporary data ADC (komparasi) void sett_regs(void); //Fungsi untuk setting register di awal proses unsigned int read_adc(unsigned char adc_input);//Fungsi baca ADC // Main function void main(void){

//--------------- Setting IO and peripheral at startup! sett_regs(); _lcd_ready(); //--------------- Time for going CRAZY (looping forever).. for(;;){ //mainloop looping forever until ERROR/POWER SHUTDOWN/RST/WDT ACTIVE #asm("wdr") //kick your DOG before timeout! hwahwa... :D if (temporary != read_adc(0)){ tegangan = (read_adc(0)*4.8828125)/1000; lcd_gotoxy(0,0); lcd_putsf("WWW.NUBIELAB.COM");//Don't forget to visit :) lcd_gotoxy(0,1); sprintf(buffer,"TEGANGAN: %0.2fV",tegangan); lcd_puts(buffer); temporary = read_adc(0); delay_ms(100); } #asm("nop") }; } // Function for setting register void sett_regs(void){ // Port a initialization PORTA=0x00;DDRA=0x00; // Port b initialization PORTB=0x00;DDRB=0x00; // Port c initialization PORTC=0x00;DDRC=0x00; // Port D initialization PORTD=0x00;DDRD=0x00; // ADC initialization // ADC Clock frequency: 1000.000 kHz // ADC Voltage Reference: AVCC pin // ADC Auto Trigger Source: Free Running ADMUX=ADC_VREF_TYPE & 0xff; ADCSRA=0xA2; SFIOR&=0x1F; // LCD module initialization lcd_init(16); // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x00; ACSR=0x80; SFIOR=0x00; // Watchdog Timer initialization // Watchdog Timer Prescaler: OSC/2048k #pragma optsizeWDTCR=0x1F; WDTCR=0x0F; #ifdef _OPTIMIZE_SIZE_ #pragma optsize+ #endif } // Routine baca ADC

unsigned int 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 ADCW; }