51单片机超声波测距数码管显示并报警(Proteus 仿真)
程序员文章站
2022-06-08 21:44:16
...
HC-SR04超声波
实物图
使用方法
1、给TRIG端口至少10us 的高电平信号
2、模块自动发送 8 个 40khz 的方波,自动检测是否有信号返回
3、有信号返回,ECHO端口会输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间
计算的话这里就不考虑温度的影响直接用声速340m/s
Proteus仿真
HC-SR04可以用Proteus中的SRF04代替
下面附上代码
/**************************************************************************
*******************************超声波测距***************************
** 按下K1后进行距离测量,当测得的距离超过预设的距离就进行报警 **
**** 当按下K2后增加预设距离,当按下K3后减小预设距离 ****
***** 若超过测量距离进行报警并显示“ERR” ******
******* 初始预设距离为100cm *******
**************************************************************************/
#include"reg51.h"
#include"intrins.h"
#define uchar unsigned char
#define uint unsigned int
#define LED P0//数码管段选
sbit LSA = P2^2;
sbit LSB = P2^3;
sbit LSC = P2^4;
sbit TR = P3^0; //超声波发射端
sbit EC = P3^2; //超声波接收端
sbit K1 = P1^0;//开始测量按钮
sbit K2 = P1^1;//预设值增加按钮
sbit K3 = P1^2;//预设值减小按钮
sbit buzzer = P1^5;//嗡鸣器控制按钮
uint biao = 0x64;//预设值定为100
uint S;//保存超声波距离
bit flag1;//开始按钮启动标志
bit flag2;//距离计算完成标志
//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码
uchar led_wei[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void delay(uint i)//延时函数
{
while(i--);
}
void init()//定时器初始化
{
TMOD = 0X01;//16位定时器
TH0 = TL0 =0x00;//装载初值 12MHZ晶振
TR0 = 0; //先关闭定时器0
TR = 0;//拉低超声波发射端
}
void key()//按钮功能
{
if(K1 == 0)
{
delay(1000);//按键消抖
if(K1 == 0)
{
flag1 = 1;//开启标志
flag2 = 0;//等待下次计算完成
while(~K1);//等待松开按键
}
}
if(K2 == 0)
{
delay(1000);//按键消抖
if(K2 == 0)
{
biao++;//增加预设值
if(biao == 400) biao = 399;//防止超过量程
while(~K2);//等待松开按键
}
}
if(K3 == 0)
{
delay(1000);
if(K3 == 0)
{
biao--;//减少预设值
if(biao == 2) biao = 3;//防止超过量程
while(~K3);//等待松开按键
}
}
}
void error()
{
uchar i;
for(i = 0; i<8; i++)//八个数码管依次显示
{
switch(i)
{
case 0 : LSA = 0;LSB = 0;LSC = 0;
LED=led_wei[biao/100]; break;//设定值取百位
case 1 : LSA = 1;LSB = 0;LSC = 0;
LED=led_wei[biao/10%10]; break;//设定值取十位
case 2 : LSA = 0;LSB = 1;LSC = 0;
LED = led_wei[biao%10]; break;//设定值取个位
case 3 : LSA = 1; LSB = 1; LSC = 0;
LED = 0x40; break; //显示“-”
case 4 : LSA = 0; LSB = 0; LSC = 1;
LED = 0x40; break; //显示“-”
case 5 : LSA = 1; LSB = 0; LSC = 1;
LED = 0x79; break;//显示“E”
case 6 : LSA = 0; LSB = 1; LSC = 1;
LED = 0X77; break;//显示“R”
case 7 : LSA = 1; LSB = 1; LSC = 1;
LED = 0X77; break;//显示“R”
}
delay(100);//延时
LED = 0X00;//清除数码管
}
}
void Led_Light()//数码管显示
{
uchar i;
for(i = 0; i<8; i++)//八个数码管依次显示
{
switch(i)
{
case 0 : LSA = 0;LSB = 0;LSC = 0;
LED=led_wei[biao/100]; break;//设定值取百位
case 1 : LSA = 1;LSB = 0;LSC = 0;
LED=led_wei[biao/10%10]; break;//设定值取十位
case 2 : LSA = 0;LSB = 1;LSC = 0;
LED = led_wei[biao%10]; break;//设定值取个位
case 3 : LSA = 1; LSB = 1; LSC = 0;
LED = 0x40; break; //显示“-”
case 4 : LSA = 0; LSB = 0; LSC = 1;
LED = 0x40; break; //显示“-”
case 5 : LSA = 1; LSB = 0; LSC = 1;
LED = led_wei[S/100]; break;//取测量值百位
case 6 : LSA = 0; LSB = 1; LSC = 1;
LED = led_wei[S/10%10]; break;//取测量值十位
case 7 : LSA = 1; LSB = 1; LSC = 1;
LED = led_wei[S%10]; break;//取测量值个位
}
delay(100);//延时
LED = 0X00;//清除数码管
}
}
void buzzer_sound()//嗡鸣器
{
buzzer = ~buzzer;
}
void ce_ju()//超声波测距
{
uint time;//计时
float temp;//转换
TR=1;//打开发射端
delay(1);//延时大于10us
TR=0;//关闭发射端
while(!EC);//等待EC拉高
TR0=1;//开启定时器0
while(EC);//等待EC拉低
TR0=0;//关闭定时器0
time = TH0*256+TL0;//计算时间单位us
TH0 = TL0 = 0;//装载定时器0初值
temp = time;
temp /= 1000;//转换单位ms
temp *= 17;//计算距离(cm) (声速=34cm/ms 结果/2)
S = temp + 0.5;//进行四舍五入
flag2 = 1;//计算完成标志
flag1 = 0;//等待下次测量
}
void bi_jiao()//比较设定值和测得值
{
if(S < biao) buzzer_sound();//打开嗡鸣器
}
void main()
{
init();//定时器初始化
while(1)
{
key();//判断哪个按键按下
if(flag1 == 1) ce_ju();//开始按钮按下开始测量
if(flag2 == 1) bi_jiao();//测量完成开始比较
if((S < 2 || S > 400) && flag2) //判断是否超过量程
{
error();//显示“ERR”
buzzer_sound();//打开嗡鸣器
}
else
Led_Light();//数码管进行显示
}
}
总结
这个程序仿真出来呢,有1~5cm误差,数值越高误差越大,**并且有一个问题就是在测量距离大于330cm的时候测得的数值直接扩大了近两倍,**这个我不知道是不是仿真软件的问题,希望哪位大佬知道哪有问题的话,指教一下!这里就先谢谢了!
上一篇: layui上传照片接口
下一篇: java 有序列表