Categories
Mikrokontroler

Memanfaatkan ADC Internal Mikrokontroler PIC16F877

Sebagaimana diketahui bahwa mikrokontroler PIC16F877 memiliki fasilitas 8 kanal ADC 10bit. Penggunaannya memang tidak bisa serentak untuk semua kanal, harus dilakukan satu persatu. Artikel kali ini akan mengulas tentang penggunaan ADC internal ini.

Rangkaian dasarnya sangat sederhana, cukup Anda hubungkan kanal-0 dan 1 (untuk contoh saja) ke sumber tegangan 5 volt (karena kita juga akan menggunakan tegangan referensi (Vref) yang sama) melalui potensiometer atau sejenisnya. Rangkaian dasar ini mirip dengan Gambar 1 pada artikel yang membahas aplikasi LED dan pushbutton pada PIC16F877 (klik disini untuk lihat gambar).

Instruksi terkait

Beberapa hal yang perlu diketahui dalam penggunaan ADC internal PIC16F877 dalam bahasa C (menggunakan kompilator CCS):

  • #device ADC = jumlah_bit
    • Digunakan untuk memberitahukan berapa resolusi bit yang akan digunakan apakah 8 atau 10bit.
  • setup_adc(mode)
    • Digunakan untuk melakukan kofigurasi awal (inisialisasi) ADC internal. Hanya dapat digunakan pada mikrokontroler dari Microchip yang memiliki fasilitas ADC internal. Paremeter mode memiliki beberapa pilihan, antara lain: ADC_OFF untuk mematikan ADC, ADC_CLOK_DIV_2, ADC_CLOK_DIV_8 dan ADC_CLOK_DIV_32 yang masing-masing digunakan untuk mengatur frekuensi kerja dari ADC-nya apakah detaknya dibagi 2, 8 atau 32, ADC_CLOK_INTERNAL yang digunakan untuk menentukan frekuensi kerja ADC sama dengan frekuensi kerja mikrokontroler.
  • setup_adc_ports(nilai)
    • Digunakan untuk menentukan pin ADC sebagai pin masukan analog, digital atau kombinasi keduanya serta tegangan referensi yang digunakan untuk menghitung nilai ADC. Kombinasi pin-pin analog tergantung pada mikrokontroler yang digunakan, cuman ada dua parameter yang bisa digunakan untuk semua jenis mikrokontroler yang dilengkapi ADC internal, yaitu ALL_ANALOG dan NO_ANALOGS. Pilihan lain untuk parameter nilai adalah RA0_RA1_RA3_ANALOG (RA0, RA1 dan RA3 saja sebagai masukan analog), A_ANALOG_RA3_REF (semua analog, RA3 digunakan sebagai tegangan referensi), RA0_ANALOG dan lain sebagainya.
  • set_adc_channel(kanal)
    • Digunakan untuk menentukan kanal ADC yang akan dibaca selanjutnya, berikan kesempatan mikrokontroler untuk menyiapkan diri, berikan tundaan minimal 10 mikrodetik (tergantung impedansi masukan) sebelum dilakukan pembacaan. Kanal berisikan angka 0, 1, 2 dan seterusnya sesuai dengan kanal ADC yang akan dibaca selanjutnya.
  • variabel = read_adc()
    • Jelas ini digunakan untuk membaca ADC itu sendiri.

Contoh program

// adc_in01.c
// reading multi-channel built-in ADC 10-bit
//
#include <16F877.h>                            // Preprocessor directive that selects the chip
#fuses HS,NOWDT,NOPROTECT,NOLVP                // Preprocessor directive that defines the chip fuses 
#device ADC=10                                  // using 10bit built-in ADC
#use delay(clock=20000000)                      // 20 MHz crystal
#use rs232(baud=9600, xmit=PIN_B7, rcv=PIN_B6)  // using UART software with PICKIT2
void main() {
//unsigned int8 i, value, min, max;
 long int x,y,z;
 float vx,vy,vz;

 delay_ms(2000);
setup_adc_ports(ALL_ANALOG);     // Built-in A/D setup function
 setup_adc(ADC_CLOCK_INTERNAL);   // using internal clock
 // the parameter for setup_adc() are
 // ADC_OFF, ADC_CLOCK_DIV_2, ADC_CLOCK_DIV_8, ADC_CLOCK_DIV_32 and
 // ADC_CLOCK_INTERNAL
do {
 set_adc_channel(1);     // set reading at ch-1
 delay_us(50);           // sould give it time to prepare
 x = read_adc();
set_adc_channel(2);     // set reading at ch-2
 delay_us(50);           // sould give it time to prepare
 y = read_adc();      

 set_adc_channel(3);     // set reading at ch-3
 delay_us(50);           // sould give it time to prepare
 z = read_adc();

 vx = x*5.0/1024;        // using 10-bit resolution
 vy = y*5.0/1024;        // 2^10 = 1024 or Vref/1024 resolution
 vz = z*5.0/1024;        // and calculate the voltage measured

 printf("%3.2f %3.2f %3.2f\r\n",vx,vy,vz);    // display it
 delay_ms(500);          // give a 500ms delay
 } while (TRUE);
}

Penjelasan

  • Perhatikan, bagian pembacaan masing-masing kanal ADC, diawali dengan set_adc_channel(), kemudian menunggu beberapa saat (saya gunakan waktu tunggu 50 mikrodetik), baru kemudian dilakukan pembacaan.
  • Saran saya, baca dulu semua ADC yang diperlukan baru kemudian dilakukan perhitungan seperlunya, seperti mengubah nilai menjadi tegangan dan lain sebagainya. Mengapa karena urusan menghitung membutuhkan cukup waktu sedangkan nilai terbaca ADC yang dikehendaki bisa berubah pada saat perhitungan.
  • Ada pertanyaan? Silahkan melalui komentar, terima kasih dan semoga bermanfaat.

Ditulis di Funabashi, Japan, 01 Desember 2011