Chương trình thực hiện kết hợp đo nhiệt độ, hiển thị lên LCD, và truyền dữ liệu lên máy tính qua giao tiếp RS232.
Mô phỏng trên ISIS - Proteus:
mô phỏng trên ISIS - Proteus
Mã nguồn C:
#include<at89x51.h>
#include<conio.h>
#include<stdio.h>
#include<string.h>
//========================= #DEFINE LCD
#define RS P3_5
#define RW P3_6//RW=0 => ghi
#define EN P3_7//RW=1 => doc
//RS=0 => code
//RS=1 => data
#define LCD_PORT P1
//========================= #DEFINE ADC
#define INTR P3_2
#define RD P3_3
#define WR P3_4
//============================================================== DELAY
void delay_ms(int n)
{
int k,j;
for(k=0;k<n;k++)
{
for(j=0;j<500;j++);
}
}
//==========================
void delay_5ms()
{
int i,j;
for(i=0;i<250;i++)
for(j=0;j<4;j++){}
}
//===========================
void delay_15ms()
{
int i,j;
for(i=0;i<250;i++)
for(j=0;j<100;j++){}
}
//============================================================== LCD
//============================== GUI LENH CHO LCD
void LCD_CODE(unsigned char c)
{
RS=0;//code
RW=0;//ghi
LCD_PORT=c;
EN=1;
EN=0;
delay_5ms();
}
//=============================== KHOI TAO LCD
void LCD_INIT()
{
delay_15ms();
LCD_CODE(0x38); //che do 8bit,2 hang,kieu ky tu 5x8 diem anh.
LCD_CODE(0x0C); //hien thi man hinh,có con tro, con tro nhâp' nháy.
LCD_CODE(0x01); // Xoa man hinh LCD
}
//============================== IN KY TU
void LCD_DATA(unsigned char c)
{
RS=1;//data
RW=0;//ghi
LCD_PORT=c;
EN=1;
EN=0;
delay_5ms();
}
//=============================== IN CHUOI KY TU
void LCD_STRING(unsigned char *s)
{
while(*s) //den NULL thi thoi
{
LCD_DATA(*s);
s++;
}
}
//============================================================== KHOI TAO RS232
void SetupSerial()
{
TMOD=0x20; /* timer 1 che do 2: 8-Bit tu dong nap lai. */
TH1=0xFD; /* toc do 9600 baud */
TL1=0xFD;
SCON=0x52; /* Che do 1: 8-bit UART, cho phep truyen */
TR1=1; /* timer 1 run */
TI=0; /* co ngat nha^n.=0*/
RI=0; /* co ngat' truye^n =0*/
ES=1; /* cho phep ngat noi tiep */
}
//============================================================== HIEN THI GIA TRI ADC LEN LCD
void HIENTHI_ADC(unsigned char t)
{
unsigned char v;
if(t<10)
LCD_DATA(t+48);
else
if(t<100)
{
LCD_DATA(t/10+48);
LCD_DATA(t%10+48);
}
else
{
v=t/10;
LCD_DATA(v/10+48);
LCD_DATA(v%10+48);
LCD_DATA(t%10+48);
}
}
//============================================================== HAM GUI SO LIEU LEN VB
void send(unsigned char a)
{
if(a<10)
{
SBUF=a+48;
while(TI==0){}
TI=0;
}
if(a>9&&a<100)
{
unsigned char c=a/10;
unsigned char d=a%10;
SBUF=c+48;
while(TI==0){}
TI=0;
SBUF=d+48;
while(TI==0){}
TI=0;
}
if(a>99)
{
unsigned char t=a/100;
unsigned char c=a/10-10*t;
unsigned char d=a%10;
SBUF=t+48;
while(TI==0){}
TI=0;
SBUF=c+48;
while(TI==0){}
TI=0;
SBUF=d+48;
while(TI==0){}
TI=0;
}
}
//============================================================== NGAT NOI TIEP
void RS232(void) interrupt 4
{
unsigned char *c,count=0;
while(RI==0){}
RI=0;
*c=SBUF;
if(count==1&&*c=='1') *c='3';
if(count==1&&*c=='2') *c='4';
switch(*c)
{
case '0': //xoa man hinh LCD
{
LCD_CODE(0x01);
}
break;
//o day co the su dung ma thap phan! (ngoai tru cac ky tu dieu khien)
case '-': //lui con tro hien thi LCD 1 don vi.
{
LCD_CODE(0x10);
}
break;
case '1': //truyen len may tinh: gia tri do duoc.
{
send(P2);
}
break;
case '2': //truyen len may tinh: gia tri do duoc.
{
send(P2);
}
break;
case '9': //thoat khoi ham ngat, cho ADC làm viec.
{
TI=0; //cho phep thoat khoi ham ngat.
count=0; //ket thuc viec truyen ky tu len LCD
}
break;
default : //truyen ky tu xuong LCD ^^.
{
if(TI==0)
LCD_CODE(0x01);
LCD_DATA(*c);
TI=1; //de cho chuong trinh ko thoat khoi ham ngat,phuc vu viec truyen ky tu len LCD.
count=1; //danh dau bat dau viec truyen ky tu len LCD
}
}
}
//============================================================== MAIN
void main()
{
SetupSerial(); //Khoi tao cac thong so cho truyen thong noi tiep
LCD_INIT();
//LCD_CODE(0x80);//hien thi 2 hang : dia chi hien thi + 80
EA = 1; //Cho phep ngat nhung chi? có ngat noi tiep duoc dung trong code nay
while(1)
{
//if(P0_3==1)
{
P0_0=P0_1=P0_2=0;
WR=0; //Bat dau chuyen doi gia tri tu ADC
delay_ms(10); //Tao tre de cap nhat du lieu tu ADC
WR=1; //Ket thuc chuyen doi
RD=0; //Chot du lieu da duoc chuyen doi: P2
LCD_CODE(0x01);
LCD_putstr("Nhiet do:");
HIENTHI_ADC(P2);
LCD_STRING(" oC");
delay_ms(300);
}
}
}
0 nhận xét:
Đăng nhận xét