#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清零
}
}
|