#include<reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
//---定义lcd1602使用的IO口---//
#define LCD_DATA P0
sbit RS=P2^7;
sbit RW=P2^6;
sbit EN=P2^5;
//---定义 按键 使用的IO口---//
sbit key1=P1^5;
sbit key2=P1^6;
sbit key3=P1^7;
//---定义 led 使用的IO口---//
sbit led=P2^1;
//HCSR04/US100超声波接口
sbit Trig1 = P2^0;
sbit Echo1 = P2^1;
sbit Trig2 = P2^2;
sbit Echo2 = P2^3;
sbit Trig3 = P3^7;
sbit Echo3 = P3^6;
uint time=0;
uchar distance1=0,distance2=0,distance3=0;
/***********延时函数相关**********************************************************/
void delay(uint z)//1毫秒延时函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/***********lcd相关****************************************************************/
void lcd_write_com(uchar com) //1602写指令
{
RS=0;
RW=0;
EN=1;
LCD_DATA=com;
delay(1);
EN=0;
}
void lcd_init() //1602初始化
{
lcd_write_com(0x38);
delay(1);
lcd_write_com(0x08);
delay(1);
lcd_write_com(0x01);//1602清屏指令
delay(1);
lcd_write_com(0x06);
delay(1);
lcd_write_com(0x0C);
delay(1);
}
void lcd_write_data(uchar date)//1602写数据
{
RS=1;
RW=0;
EN=1;
LCD_DATA=date;
delay(1);
EN=0;
}
void dis_str(uchar x,uchar y,uchar *s)//在任意地址写符号字母或数字
{
if(y==0)lcd_write_com(0x80+x);
else lcd_write_com(0xc0+x);
while(*s)
{
lcd_write_data(*s);
s++;
}
}
void dis_shu(uchar x,uchar y,uchar num)//数据显示函数
{
uchar s,g,b;
if(y==0)lcd_write_com(0x80+x);
else lcd_write_com(0xc0+x);
b=num/100;// 数据分离显示
lcd_write_data(0x30+b);
s=num%100/10;// 数据分离显示
lcd_write_data(0x30+s);
g=num%100%10;//数据分离显示
lcd_write_data(0x30+g);
}
/***********按键相关****************************************************************/
void key_scan(void)
{
if(key1==0)
{
delay(3); //按键消抖
if(key1==0)
{
while(key1==0); //松手监测
}
}
if(key2==0)
{
delay(3);
if(key2==0)
{
while(key2==0);
}
}
if(key3==0)
{
delay(3);
if(key3==0)
{
led=!led;
while(key3==0);
}
}
}
void StartModule(uchar num)
{
if(num==1)Trig1=1; //启动一次模块
else if(num==2)Trig2=1;
else if(num==3)Trig3=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
if(num==1)Trig1=0; //启动一次模块
else if(num==2)Trig2=0;
else if(num==3)Trig3=0;
}
void Conut(uchar num)
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
if(num==1)distance1=(time*1.7)/100; //算出来是CM
else if(num==2)distance2=(time*1.7)/100; //算出来是CM
else if(num==3)distance3=(time*1.7)/100; //算出来是CM
}
void get_distance(uchar num)
{
StartModule(num);
if(num==1)
{
while(!Echo1); //当RX为零时等待
TR0=1; //开启计数
while(Echo1); //当RX为1计数并等待
TR0=0; //关闭计数
}
else if(num==2)
{
while(!Echo2); //当RX为零时等待
TR0=1; //开启计数
while(Echo2); //当RX为1计数并等待
TR0=0; //关闭计数
}
else if(num==3)
{
while(!Echo3); //当RX为零时等待
TR0=1; //开启计数
while(Echo3); //当RX为1计数并等待
TR0=0; //关闭计数
}
Conut(num); //计算
}
void Timer_Init()
{
TMOD=0x21; //T0 方式1 T1方式2
TH0=0;
TL0=0;
ET0=1; //允许T0中断
EA=1; //总中断闭合导通
}
void main()
{
lcd_init(); //1602初始化
Timer_Init(); //初始化定时器
while(1) //循环读取 并更新数据显示
{
key_scan(); //扫描按键(预留)
get_distance(1); //计算超声波1距离
dis_str(0,0,"US1:");dis_shu(4,0,distance1); //超声波1距离显示
get_distance(2); //计算超声波2距离
dis_str(0,1,"US2:");dis_shu(4,1,distance2); //超声波2距离显示
get_distance(3); //计算超声波3距离
dis_str(9,1,"US3:");dis_shu(13,1,distance3);//超声波3距离显示
}
}