You are on page 1of 4

Trong bài này chúng ta sử dụng biến trở kết nối với 1 chân ADC của

PIC16F887.
Khi vặn biến trở thì mức điện áp vào chân ADC sẽ thay đổi từ 0-5V.

Sơ đồ nguyên lý (schematic):

- Các bạn có thể gắn trên breadboard, hàn trên mạch lỗ, hoặc làm mạch
in.
- Biến trở có giá trị 10k (103), nên mua loại volume cho dễ vặn (tất
nhiên là các loai nào khác cũng được)
- Chân ở giữa của biến trở là “chân chạy” thì các bạn hàn với trở 1k
rồi nối vào 1 header để gắn vào chân ADC của PIC.

Kết nối:
+ Header source in: cấp nguồn 5VDC.
+ Header 1: Kết nối với 1 chân ADC bất kì của PIC (ANx).
- Khi vặn biến trở xuống vị trí (3) thì áp đọc vào là 0V.
- Khi vặn biến trở lên vị trí (1) --> Đọc về 5V, nếu không có điện trở
R5 1kOhm hạn dòng thì chân I/O của PIC có khả năng sẽ chết.
Chương trình sau đây có nhiệm vụ:
- Chọn kênh ADC là AN3.
- Cấu hình cho module ADC (xem phần chú thích trong code)
- Đọc kết quả chuyển đổi ADC và kiểm tra nếu áp ngõ vào analog > 2.5V
thì bật các LEDs gắn ở PORTB lên.

Các phần cấu hình, khởi tạo, đọc kết quả ADC, ... đều được viết thành
các chương trình con.
Các chú thích cần thiết được viết đầy đủ để có thể dễ dàng chỉnh sửa
cấu hình khi cần.
/****************************************************************
*
* www.payitforward.edu.vn
*
****************************************************************/
/****************************************************************
*
* PIC Training Course
*
****************************************************************/
/****************************************************************
*
* Module : adc_main.c
* Description : Read ADC from AN3 channel
* If ADC_result > 2.5V then Turn On LEDs
* Tool : HI-TECH PIC
* Chip : 16F887
* History : 05/03/2011
*
* Author : Nguyen Tien Manh, CLB NCKH
* Notes :
*
*
****************************************************************/

/****************************************************************
* IMPORT
****************************************************************/

#include <htc.h>
__CONFIG(XT & WDTDIS & PWRTEN & MCLREN & UNPROTECT & SWBOREN &
IESODIS & FCMDIS & LVPDIS & DEBUGDIS); //1st config. Word

__CONFIG(BORV21); //2st config. Word

#define _XTAL_FREQ 4000000

/****************************************************************
* EXTERN
****************************************************************/
/*none...*/

/*****************************************************************
GLOBAL VARIABLE
******************************************************************/
/*none...*/

/*****************************************************************
* ROUTINES
******************************************************************/
void port_init()
{
ANSEL = 0x08; // Chon kenh ADC AN3
ANSELH = 0;
TRISA3 = 1; //RA3 phai la Input de doc ADC
TRISB = 0; //PortB de xuat LED nen la OutPut
PORTB = 0xFF // Tat het LED o portB
}

//----------------------------------------------------------------
void adc_init()
{
// ADC conversion clock: = Fosc/8
// ADCS <1:0> = 00 Fosc/2
// ADCS <1:0> = 01 Fosc/8
// ADCS <1:0> = 10 Fosc/32
// ADCS <1:0> = 11 F_RC
ADCS1 = 0;
ADCS0 = 1;

// Voltage reference: Internal Vref


// VCFG <1:0> = 00 Internal Vref
// VCFG <1:0> = 11 External Vref
VCFG1 = 0;
VCFG0 = 0;

// Select Input chanel: AN3


// CHS <3:0> = 0000 Select AN0
// CHS <3:0> = 0001 Select AN1
// CHS <3:0> = 0010 Select AN2
// ...
// CHS <3:0> = 1101 Select AN13
CHS3 = 0;
CHS2 = 0;
CHS1 = 1;
CHS0 = 1;

// Result format: Right


// ADFM = 1 Right justified
// ADFM = 0 Left justified
ADFM = 1;

// Turn on ADC Module


ADON = 1;

//delay to wait for adc module init.


__delay_ms (1);
}

//----------------------------------------------------------------
//interrupt initialization
void int_init()
{
GIE = 1; //Global Interrupt Enable
PEIE = 1; //Peripheral Interrupt Enable
ADIE = 1; //ADC Interrupt Enable
ADIF = 0; //Clear ADC Interrupt Flag
}

//----------------------------------------------------------------
//Interrupt service rountine
void interrupt isr()
{
int ADC_result;
if (PEIE && ADIE && ADIF)
{
ADIF = 0; //Clear ADC Interrupt Flag

//Read ADC result


ADC_result = (ADRESH<<8)|ADRESL;

//V_in > 2.5V <=> ADC_result > 512


if (ADC_result> 512)
{
PORTB = 0; //Turn LEDs ON
}
else
{
PORTB = 0xFF;
}
}
}

/****************************************************************
* MAIN
****************************************************************/

/* -- void main (void) -----------------------------------------


*
* Description : Configure port, adc module and enable interrupt
* then wait for ADC interrupt
* Parameters : none
* Return : don't care
* Notes :
*/

void main(void)
{
port_init();
adc_init();
int_init();
while(1)
{
__delay_us(50); //delay between 2 AD conversions
GODONE = 1; //Set GODONE bit to start conversion
};
}

/****************************************************************
* END OF adc_main.c
****************************************************************/

You might also like