Đầu tiên mình xin giới thiệu qua về bộ ADC của PIC16f877a
- Là bộ ADC 10bit với 8 kênh, Điện áp mẫu có thể lựa chọn bằng phần mềm sử dụng điện áp mẫu là VDD và GND hoặc lấy từ 2 chân VREF+ và VREF- .
- Các thanh ghi cấu hình bộ ADC:
1. Thanh ghi ADCON0: thanh ghi cấu hình.
- Đây là ảnh mô phỏng protues.
- Là bộ ADC 10bit với 8 kênh, Điện áp mẫu có thể lựa chọn bằng phần mềm sử dụng điện áp mẫu là VDD và GND hoặc lấy từ 2 chân VREF+ và VREF- .
- Các thanh ghi cấu hình bộ ADC:
1. Thanh ghi ADCON0: thanh ghi cấu hình.
- Bit 7-6: Lựa chọn tần số chuyển đổi của bộ ADC.
- Bit 5-3 : Lựa chọn kênh chuyển đổi:
- Bit 2: GO/DONE.
Khi bộ ADC bắt đầu chuyển đổi, bit này ở mức 1, khi quá trình chuyển đổi hoàn thành bit này sẽ về mức 0 báo quá trình chuyển đổi hoàn tất
- Bit 1: ADON : Bit cho phép bộ ADC hoạt động
ADON = 1: Bộ ADC được làm việc
ADON = 0: Tắt bộ ADC
Khi bộ ADC bắt đầu chuyển đổi, bit này ở mức 1, khi quá trình chuyển đổi hoàn thành bit này sẽ về mức 0 báo quá trình chuyển đổi hoàn tất
- Bit 1: ADON : Bit cho phép bộ ADC hoạt động
ADON = 1: Bộ ADC được làm việc
ADON = 0: Tắt bộ ADC
2. Thanh ghi ADCON1:
- Bit 7 : ADFM:
Do có 2 thanh ghi chưa giá trị ADC sau khi chuyển đổi, nhưng bộ ADC là ADC10bit nên sẽ có 6bit chứa giá trị '0' , việc xác định 6bit đó ở bên phía thanh ghi ADRESH hay ADRESL do bit ADFM này quyết định
ADFM = 1 : 6bit này là 6bit cuối của thanh ghi ADRESH
ADFM = 0: 6bit này là 6bit đầu tiên của thanh ghi ADRESL
Do có 2 thanh ghi chưa giá trị ADC sau khi chuyển đổi, nhưng bộ ADC là ADC10bit nên sẽ có 6bit chứa giá trị '0' , việc xác định 6bit đó ở bên phía thanh ghi ADRESH hay ADRESL do bit ADFM này quyết định
ADFM = 1 : 6bit này là 6bit cuối của thanh ghi ADRESH
ADFM = 0: 6bit này là 6bit đầu tiên của thanh ghi ADRESL
- Bit 6 : loại chọn tuần số tác động
- Bit 5-4: không sử dụng
- Bit 3-0: 4 bit này có chức năng cấu hình chức năng của từng chân trong bộ ADC (Mình dịch theo mình hiểu, cũng k được sát với datasheet).
Và chúng ta sẽ làm 1 ví dụ nho nhỏ là đọc giá trị ADC để xuất ra 10 con LED như chúng ta đã biết bộ ADC chúng ta sử dụng trong bài này là ADC 10bit tương ứng với giá trị từ 0 - 1023 nếu đổi sang mã HEX thì giá trị sẽ là 0 - 1111111111 như vậy nếu giá trị ADC bằng 0 thì LED sẽ tắt hết ngược lại nếu bằng 1023 thì LED sẽ sáng hết.- Đây là ảnh mô phỏng protues.
Như trong ảnh mô phỏng protues các bạn thấy chúng ta có sử dụng 1 biến trở 10k để thay đổi giá trị ADC và kết quả đó sẽ được xuất ra LED các bạn có thể biết chính xác được giá trị ADC hiện tại là bao nhiêu thông qua 10 LED của chúng ta.
- Đây là code chương trình.
- Đây là code chương trình.
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _XTAL_FREQ 8000000
// CONFIG
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
void ADC_Init()
{
ADCON0 = 0x41;
ADCON1 = 0xC0;
}
unsigned int ADC_Read(unsigned char channel)
{
if(channel > 7)
return 0;
ADCON0 &= 0xC5;
ADCON0 |= channel<<3;
__delay_ms(2);
GO_nDONE = 1;
while(GO_nDONE);
return ((ADRESH<<8)+ADRESL);
}
void main()
{
unsigned int a;
TRISB = 0x00;
TRISC = 0x00;
ADC_Init();
do
{
a = ADC_Read(0);
PORTB = a;
PORTC = a>>8;
__delay_ms(100);
}while(1);
}
- Link download project Click here
EmoticonEmoticon