用keil5写一个超声波测距,超声波管脚:sbit Tring=p3^6;sbit Echo=p3^7;具有蜂鸣器,管脚:sbit Feng=p2^0;sbit k2=p2^7;k3=p2^6;k4=p2^5;用oled屏幕显示距离,管脚:p1^0;p2p1^1;要求:(1)测量距离范围0-3米,液晶显示距离信息(厘米),测量误差小于5%;(2)液晶显示内容及形式可以自定,但必须包括测量距离信息,设置警戒距离;动态更新测量结果,更新时间小于0.5秒; (3)通过按键设定警戒距离,当距离小于1米,蜂鸣器报警;
时间: 2023-06-01 11:02:15 浏览: 82
#include <reg51.h>
#include <intrins.h>
#include <stdio.h>
#include "oled.h"
#define Tring P3_6
#define Echo P3_7
#define Feng P2_0
#define k2 P2_7
#define k3 P2_6
#define k4 P2_5
unsigned int distance = 0; //测量距离
unsigned int warn_distance = 100; //警戒距离,初始值为100cm
unsigned int warn_flag = 0; //警戒标志,0-未警戒,1-警戒中
unsigned int error_flag = 0; //错误标志,0-无错误,1-超出测量范围
//延时函数,约1us
void delay_us(unsigned int us)
{
while(us--)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
//超声波模块测距函数
unsigned int ultrasonic_measure()
{
unsigned int distance;
Tring = 1; //发射超声波脉冲
delay_us(10);
Tring = 0;
while(!Echo); //等待Echo脚变高
TH0 = 0;
TL0 = 0;
TR0 = 1; //启动计数器
while(Echo); //等待Echo脚变低
TR0 = 0; //关闭计数器
distance = TH0 * 256 + TL0; //计算距离
distance = distance / 58; //换算成厘米
if(distance < 2 || distance > 300) //超出测量范围
{
error_flag = 1; //设置错误标志
}
else
{
error_flag = 0;
}
return distance;
}
//警报函数
void warn()
{
Feng = 1;
delay_us(500);
Feng = 0;
delay_us(500);
}
//按键扫描函数
void key_scan()
{
if(!k2) //设置警戒距离为50cm
{
warn_distance = 50;
OLED_Clear();
OLED_ShowString(0,0,"Warn distance:50cm");
delay_us(100000);
}
if(!k3) //设置警戒距离为100cm
{
warn_distance = 100;
OLED_Clear();
OLED_ShowString(0,0,"Warn distance:100cm");
delay_us(100000);
}
if(!k4) //设置警戒距离为150cm
{
warn_distance = 150;
OLED_Clear();
OLED_ShowString(0,0,"Warn distance:150cm");
delay_us(100000);
}
}
//主函数
void main()
{
unsigned char str[20];
TMOD = 0x01; //设置计数器0为模式1
TH1 = 0xfd; //计时1ms
TL1 = 0xfd;
ET1 = 1; //开启计时器1中断
EA = 1; //开启总中断
OLED_Init(); //初始化OLED屏幕
OLED_ShowString(0,0,"Distance: cm");
OLED_ShowString(0,2,"Warn distance:100cm");
while(1)
{
key_scan(); //按键扫描
distance = ultrasonic_measure(); //测量距离
if(error_flag) //超出测量范围
{
OLED_ShowString(10,0,"Error!");
}
else //在测量范围内
{
sprintf(str,"%d",distance);
OLED_ShowString(10,0,str);
if(distance < warn_distance) //距离小于警戒距离
{
warn_flag = 1; //设置警戒标志
}
else
{
warn_flag = 0;
}
}
if(warn_flag) //警戒中
{
OLED_ShowString(0,4,"Warning!");
warn(); //警报
}
else //未警戒
{
OLED_ShowString(0,4," ");
}
}
}
//计时器1中断服务函数
void timer1_isr() interrupt 3
{
static unsigned int cnt = 0;
TH1 = 0xfd; //计时1ms
TL1 = 0xfd;
cnt++;
if(cnt >= 500) //更新频率0.5s
{
cnt = 0;
OLED_ShowString(10,2," ");
sprintf(str,"%d",warn_distance);
OLED_ShowString(10,2,str);
}
}