测试工具
软件:Proteus8.13
仿真器件:蜂鸣器警报,按键输入,SRF04超声波,LCD1602显示。
功能叙述
测量裂缝,短距离到达与否之类
利用SRF04超声波测量与目标距离,并实时显示到LCD1602上,并在下面显示测量到的距离与设置的距离是否符合的结果,测量到的距离>设置的距离,显示false,测量到的距离<设置的距离,显示true。并且在false时,红灯亮。在true时,绿灯亮。独立按键,可以进入设置模式,设置距离。
仿真图示
仿真运行原图
原理图在未运行仿真时,LCD1602有点显示不出,运行了就能显示了。
图中在SRF04超声波的时序中的双线引到,一个示波器上,是为稳定SRF04超声波读取时序时稳定,不加,数据读取可能会出问题。

原图中LCD1602显示数据解释

设置模式数据解释

程序代码

代码主体
#include<reg52.h>
#include<intrins.h>
#include <STDIO.H>
typedef unsigned int uint;
typedef unsigned char uchar;
#define lcd P1 //液晶屏端口定义
/************引脚定义**********************/
sbit rs=P3^3; //LCD1602控制端
sbit en=P3^5;
sbit k1=P2^0; //设置键
sbit k2=P2^1; //增加键
sbit k3=P2^2; //减少键
sbit LED1=P3^6; //蜂鸣器引脚
sbit LED2=P3^7; //蜂鸣器引脚
sbit RX=P2^7; //超声波接收引脚
sbit TX=P2^6; //超声波发送引脚
uint time=0; //超声波计时
uint S=0; //超声波测得的距离
uint length=0,set_length=300; //缺陷直径,直径阈值
uint tmp; //脉冲计数
uchar flag,flag1; //设置标志
uchar table0[]=" Depth=000cm "; //用于液晶显示
uchar table1[]=" XXX ";
uchar table2[]="000";
uchar table3[]="000.0";
uchar table1_1[]=" true ";
uchar table1_0[]=" false ";
void keyscan();
void delay_ms(uint x) //延时函数 1ms延时
{
uint i;
while(x--)for(i=0;i<120;i++);
}
/*************************液晶驱动程序*************************/
void w_cmd(uchar com) //lcd1602写命令
{
rs=0;
lcd=com;
en=1;
delay_ms(5);
en=0;
}
void w_data(uchar dat) //lcd1602读数据
{
rs=1;
lcd=dat;
en=1;
delay_ms(5);
en=0;
}
void w_str(uchar *s) //lcd1602写字符串
{
while(*s) w_data(*s++);
}
void lcd_int() //lcd1602初始化
{
en=0;
w_cmd(0x38);
w_cmd(0x0c);
w_cmd(0x06);
w_cmd(0x01);
w_cmd(0x80+0x00);
w_str(table0);
w_cmd(0xc0+0x00);
w_str(table1);
}
/*********************传感器识别函数******************/
void keyscan()
{
if(k1==0) //设置
{
delay_ms(5); //延时
if(k1==0)
{
while(!k1);
flag=!flag;
flag1=0;
}
}
if(flag)
{
if(k2==0) //增加
{
delay_ms(5); //延时
if(k2==0)
{
while(!k2);
set_length=set_length+10;
if(set_length>9990) set_length=9990; //限幅
}
}
if(k3==0) //减少
{
delay_ms(5); //延时
if(k3==0)
{
while(!k3);
set_length=set_length-10;
if(set_length<10) set_length=10; //限幅
}
}
}
}
/**************************************************************
40KHZ方波
***************************************************************/
void StartModule() //T1中断用来扫描数码管和计800MS启动模块
{
TX=1; //800MS 启动一次模块
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
TX=0;
}
/**************************************************************
距离计算函数
***************************************************************/
void Conut(void)
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
S=(time*1.7)/100; //算出来是CM
if(S>999) S=999;
}
/**************************************************************
定时器0初始化函数
用来计算距离
***************************************************************/
void Time0_init(void)
{
TMOD |=0x01; //设T0为方式1,GATE=1;
TH0=0;
TL0=0;
TR0=0;
ET0=1; //允许T0中断
EA=1; //开启总中断
}
/**************************************************************
中断用来检测是否超出测量距离
***************************************************************/
void zd0() interrupt 1 //T0中断用来计数器溢出,超过测距范围
{
TH0=0;
TL0=0;
}
void Init_timer2()
{
RCAP2H=(65535-50000)/256;//赋T2初始值
RCAP2L=(65535-50000)%256;
TR2=1; //启动定时器2
ET2=1; //打开定时器2中断
EA=1; //打开总中断
}
void Timer2() interrupt 5 //定时器2是5号中断
{
static uchar t;
TF2=0;
t++; //d电机控制计数
if(t>=20) //1s时间到
{
t=0;
length=tmp*10; //计算缺陷直径
if(length>9999) length=9999;
tmp=0;
}
keyscan(); //按键识别
}
/*********************液晶显示******************/
void display()
{
if(flag==0) //正常模式
{
if(flag1==0)
{
w_cmd(0x80+0x00);
w_str(table0);
w_cmd(0xc0+0x00);
w_str(table1);
flag1=1;
}
table2[0]=S%1000/100+48; //深度
table2[1]=S%100/10+48;
table2[2]=S%10+48;
w_cmd(0x80+0x08);
w_str(table2);
// table3[0]=length/1000+48; //路程
// table3[1]=length%1000/100+48;
// table3[2]=length%100/10+48;
// table3[4]=length%10+48;
// w_cmd(0xc0+0x06);
// w_str(table3);
if(S<(set_length/10))
{
w_cmd(0xc0+0x00);
w_str(table1_1);
LED1=0;
LED2=1;
}
else
{
w_cmd(0xc0+0x00);
w_str(table1_0);
LED1=1;
LED2=0;
}
}
else //设置阈值模式
{
if(flag1==0)
{
w_cmd(0x80+0x00);
w_str(" SET... ");
w_cmd(0xc0+0x00);
w_str(table1);
flag1=1;
}
table3[0]=set_length/1000+48; //路程
table3[1]=set_length%1000/100+48;
table3[2]=set_length%100/10+48;
table3[4]=set_length%10+48;
w_cmd(0xc0+0x06);
w_str(table3);
}
}
void handle() //数据处理函数
{
StartModule(); //启动超声波
while(!RX); //当RX为零时等待
TR0=1; //开启计数
while(RX); //当RX为1计数并等待
TR0=0; //关闭计数
Conut(); //计算
// if(length>set_length) //大于阈值是缺陷
// {
// spk=!spk; //报警
// delay_ms(300); //延时
// }
// else
// spk=1; //停止报警
}
void main(void)//主函数
{
Time0_init(); //定时器0初始化
Init_timer2(); //定时器2初始化
lcd_int(); //液晶初始化
while(1)
{
display();//液晶显示
handle();
}
}
工程源码
链接:https://pan.baidu.com/s/1odytlA38YKHagei0ZIxPyA
提取码:1234