#include"reg52.h"
#include <intrins.h>
#define uint unsigned int //偷懶
#define uchar unsigned char
sbit RS = P1^0;
sbit RW = P1^1; //
sbit EN = P2^5;
sbit trig=P2^1; //超聲波觸發引腳
sbit echo=P2^0; //超聲波接收引腳
bit flag1;
uchar count;
long int distance;
unsigned char code table[]={"0123456789"};
void delay(uint n) //延時函數
{
uint x,y;
for(x=n;x>0;x--)
for(y=110;y>0;y--);
}
void T0_init() //T0中斷初始化
{
TMOD=0x01; //定義計時器0工作方式為1
TL0=0x66; //裝入初始值
TH0=0xfc;
ET0=1; //開定時器0中斷
EA=1; //開總中斷
}
int delay_ms(unsigned char xms)
{
unsigned char x,y;
for(x=xms;x>0;x--)
for(y=110;y>0;y--);
return 0;
}
int write_com(unsigned char com)//寫命令的函數體
{
RS = 0; //寫指令
RW = 0;
P0 = com;
delay_ms(5);
EN = 1;
delay_ms(5);
EN = 0;
return 0;
}
int write_date(unsigned char date)//寫數據的函數體
{
RS = 1; //寫數據
RW = 0;
P0 = date;
delay_ms(5);
EN = 1;
delay_ms(5);
EN = 0;
return 0;
}
int init()//初始化函數體
{
EN = 0;
write_com(0X38);//設置16*2顯示,5*7點陣,8位數據接口
write_com(0X0C);//設置開顯示,不顯示光標
write_com(0X06);//寫一個字符時,光標自動+1
write_com(0X01);//顯示清零
return 0;
}
void dis() //顯示固定字符
{
write_com(0x80+0x40); //設定輸入位置
write_date('d'); //輸入用'',不可以用""
write_date('i');
write_date('s');
write_date('t');
write_date('a');
write_date('n');
write_date('c');
write_date('e');
write_date(':');
write_com(0x80+0x4c); //設定輸入位置
write_date('.');
write_com(0x80+0x4e); //設定輸入位置
write_date('c');
write_date('m');
}
void trigger() //超聲波模塊觸發函數
{
trig=1; //打開超聲波觸發端口
delay(1);
trig=0; //關閉超聲波觸發端口
}
void measure_init() //測量函數初始化
{
trig=0; //觸發端口低電平
echo=0; //接收端口低電平
count=0;
}
void measure() //測距函數
{
uchar a;
uint b,c;
TR0=1; //打開定時器
while(echo) //當超聲波接收打開時計時
{
;
}
TR0=0; //關閉定時器
a=TL0; //a,b分別賦予中斷函數高八位和第八位計時后的數值
b=TH0;
c=(b<<8)+a; //高八位左移八位之后與低八位做加法運算
c=c-0xfc66; //減去初始值高八位和低八位
distance=c+1000*count; //總的時間,單位是μs
TL0=0x66; //重新裝入初始值
TH0=0xfc;
delay_ms(30);
distance=3453*distance/20000; //計算距離,單位是cm
}
/*
距離計算原理:所求t μs,distance=t*0.34(聲速340m/s=0.34cm/μs)/2
*/
void echodisplay(uint x) //顯示距離函數
{
uchar q,b,s,g;
q=x/1000; //將測量函數測得的distance分為個位,十位,百位,千位
b=(x/100)%10;
s=(x/10)%10;
g=x%10;
write_com(0x80+0x49); //設定輸出位置
write_date(table[q]); //寫入數據
write_date(table[b]);
write_date(table[s]);
write_com(0x80+0x4d); //設定輸入位置
write_date(table[g]); //寫入數據
}
void main() //主函數
{
init(); //初始化LCD
T0_init(); //初始化T0計時器
measure_init();//初始化超聲波測量模塊
while(1) //循環
{
dis(); //顯示固定字符
trigger(); //觸發超聲波測距
while(echo==0)//當接收端沒有打開的時候在這里循環
{
;
}
measure();//測量距離distance
echodisplay(distance);//顯示距離distance
measure_init();//再次初始化測距模塊
delay_ms(500);//測量間隔500ms
}
}
void T_0() interrupt 1 //計時器中斷函數T0
{
TF0=0; //計時器溢出中斷 標志位
TL0=0x66; //填入初始數據
TH0=0xfc;
count++; //產生一次中斷就加一
if(count==18) //當計數到達18的時候,約1s
{
TR0=0; //關閉計時器中斷0
TL0=0x66; //重新裝入初始值
TH0=0xfc;
count=0; //把count清零
}
}
|