Sửa bài tập ADC-LCD
Hầu như mọi công việc quan trọng đã thực hiện trong sample code post trong bài ADC (mục tài liệu và chương trình học), để làm bài tập này ta cần thêm:
- Công thức đổi giá trị chuyển đổi ADC (10-bit) thành dạng điện áp chính xác tới 3 chữ số thập phân.
Tầm điện áp đọc về là 0-5V --> ta phải nhân với 1000 để lấy 3 chữ số thập phân --> tầm giá trị cần quy đổi là 0 - 5000.
Ví dụ: điện áp đọc về là 4.356V thì số được lưu trong biến kết quả phải là 4356 (kết quả tính toán phải là số nguyên nên ta phải nhân 1000 thì mới lấy được 3 chữ số thập phân)
Lưu ý đến khi hiển thị lên LCD thì ta thêm kí tự dấu "." để biểu diễn kết quả.
Do ADC là 10-bit nên kết quả "thô" từ 2 thanh ghi ADRESH và ADRESL nằm trong phạm vi 0-1023.
=> Công thức tính:
ketqua=(ADRESH<<8)|ADRESL;
ketqua=ketqua*5*1000/1023;
- 1 đoạn chương trình con là đổi kết quả chuyển đổi ADC thành dạng kí tự để hiển thị lên LCD.
Một số điều chưa tốt trong code bài tập các bạn gửi:
- Về kiểu: biến ketqua nằm trong phạm vi 0-1023 chỉ cần đặt biến là
int, không cần tới double.
- Biến toàn cục: Thực ra bài này chưa cần đặt biến toàn cục, biến kết quả có thể đặt trong chương trình ngắt, trước
if (...)
Một số vấn đề đã nhắc nhưng một số bạn quên chưa thực hiện:
- Trình bày code theo form.
- Các phần liên quan tới khởi tạo, ngắt, xử lý kết quả để hiển thị lên LCD, ... nên viết thành chương trình con, trong hàm main càng ít chữ càng tốt
- 1 dòng code
không quá 80 kí tự kể cả chú thích (recommend là 67 kí tự - bằng với chiều dài các dòng chú thích **** hay ----- trong standard form.
Đây là code có thể tham khảo - tác giả Phan Cường (đã được 2death chỉnh sửa một số chỗ về mặt trình bày)
Code:
/****************************************************************
*
* PIC Training Course
*
****************************************************************/
/****************************************************************
*
* Module : main.c
* Description : ADC_LCD
* Tool : HI-TECH PIC
* Chip : 16F887A
* History : 09/03/2011
*
* Author : Phan Cuong, CLB NCKH
* Notes :
*
*
****************************************************************/
/****************************************************************
* IMPORT
****************************************************************/
#include <htc.h>
#include "lcd.h"
__CONFIG(XT & WDTDIS & PWRTEN & MCLREN & UNPROTECT & SWBOREN &
IESODIS & FCMDIS & LVPDIS & DEBUGDIS);
__CONFIG(BORV21);
#define _XTAL_FREQ 4000000
//----------------------------------------------------------------
// khoi tao port
void port_init() //config port
{
ANSEL|=1<<3; //BAT BIT 3
ANSELH=0; //RA3: INPUT
TRISA3=1; //PORTB: OUTPUT
TRISB=0x00;
RB0=1; //TAT LED
}
//----------------------------------------------------------------
// khoi tao ADC
void adc_init() // CONFIG ADC
{
ADCS1=1; //CHON TAN SO LAY MAU
ADCS0=0;
VCFG1=0; //CHON Vref
VCFG0=0;
CHS3=0; //CHON KENH AN3
CHS2=0;
CHS1=1;
CHS0=1;
ADFM=1;
ADON=1;
}
//----------------------------------------------------------------
// khoi tao ngat
void interrupt_init() //config chuong trinh NGAT
{
ADIF=0; //SET CO NGAT BANG 0
ADIE=1;
GIE=1;
PEIE=1;
}
//----------------------------------------------------------------
// chuyen so de hien thi
void adc_lcd(int i)
{
char a, b, c, d; //tach hang ngan, tram, chuc, don vi
a = i/1000;
b = (i - 1000*a)/100;
c = (i - 1000*a - 100*b)/10;
d = i - 1000*a - 100*b - 10*c;
//HIEN THI LEN LCD
lcd_putc(a + 0x30);
lcd_puts(".");
lcd_putc(b + 0x30);
lcd_putc(c + 0x30);
lcd_putc(d + 0x30);
lcd_puts(" V");
}
//----------------------------------------------------------------
void interrupt isr() //chuong trinh ngat
{
int t1;
if(ADIE && ADIF)
{
ADIF=0;
t1=(ADRESH<<8 |ADRESL);
t1=t1*5000/1024; //do chia nho nhat:5V/1024
adc_lcd(t1);
if(t1>=512) //neu Vra3> 2.5V
RB0=0;
else
RB0=1;
}
}
/****************************************************************
* MAIN
****************************************************************/
void main(void)
{
port_init();
adc_init();
interrupt_init();
lcd_init();
while(1)
{
__delay_ms(100);
lcd_clear();
GODONE=1;
};
}
/****************************************************************
* END OF adc_main.c
****************************************************************/