标题:
AT89S51单片机超声波测距系统Proteus仿真+注释详细的代码
[打印本页]
作者:
太太天真
时间:
2019-6-20 14:02
标题:
AT89S51单片机超声波测距系统Proteus仿真+注释详细的代码
测距精度不是特别的准确。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
0.png
(15.65 KB, 下载次数: 71)
下载附件
2019-6-20 17:56 上传
单片机源程序如下:
// 基于AT89C51/52单片机的超声波测距系统
// 测量范围:40-690厘米
// 晶振:12MH
// 2015年5月
#include <REGX51.H> //头文件
#include <intrins.h> //头文件
#define uchar unsigned char
#define uint unsigned int
#define bjh P3_1 //定值输出(继电器)
#define sx P0_2 //报警值输出(声音)
#define csbout P2_7 //超声波发送
#define csbint P3_5 //超声波接收
uchar ec,cls,cs,mq,xm0,xm1,xm2,sec20,sec,sec1,buffer[3]; //程序中使用的变量
uchar convert[10]={0x81,0xED,0xA2,0xA8,0xCC,0x98,0x90,0xAD,0x80,0x88};//0~9段码
uint zzz,dz,i,jsz,t;//程序中使用的变量 zzz:测量上限,dz:报警定值,i:延时变量,jsz:距离测量结果,t:时间
static uchar bdata ke; //可位寻址的状态寄存器
float csbc; //超声波速储存单元
sbit LED1 = P3^4; //数码管位驱动
sbit LED2 = P3^2; //数码管位驱动
sbit LED3 = P3^3; //数码管位驱动
void delay(i); //延时函数
void scanLED(); //显示函数
void timeToBuffer(); //显示转换函数
void time(); //计时处理
void csbcj(); //超声波测量处理
void bgcl(); //继电器报警处理
void csbfs(); //超声波发送
void offmsd(); //百位为零时不显示处理
void main() //主程序
{
EA=1; //开中断
TMOD=0x11; //设定时器1定时
csbout=1; //单片机超声波输出端口置高电平
TR1=0; //定时器1停止工作
zzz=699; //测量上限值
mq=40; //盲区值
dz=120; //报警值初值
cls=1; //每秒测量次数
csbc=0.034; //20度时的超声波速度:厘米/uS
bjh=1; //继电器停止工作
sx=0; //蜂鸣器停止工作
ec=100;
while(1)
{
ec++;
if (ec>100) //超声波测量标志为100时进行测量
{
cls=~cls;
ec=0; //超声波测量标志置0
csbcj(); //调用超声波测量程序
timeToBuffer(); //调用转换段码功能模块
offmsd(); //调用显示转换程序
bgcl(); //调用报警处理程序
}
scanLED(); //调用显示函数
if((jsz<dz)&(cls==1)) //判断是否达到报警值
{
i=5;
while(i--)
{
sx=~sx; //发出“滴”声响
delay(70);
}
}
else {sx=0;}
}
}
void delay(i) //延时子程序
{
while(--i);
}
void scanLED() //显示功能模块
{
P2=buffer[2]; //显百位段
LED1=0; //显百位位
delay(40); //百位显示延时 程序要下载到实物中时改为delay(2); 下同
LED1=1; //关闭百位显示
delay(2); //关闭百位显示延时 程序要下载到实物中时改为delay(50); 下同
P2=buffer[1]; //显十位段
LED2=0; //显十位位
delay(40); //百十位显示延时
LED2=1; //关闭十位显示
delay(2); //关闭十位显示延时
P2=buffer[0]; //显个位段
LED3=0; //显个位位
delay(40); //显个位段
LED3=1; //百关闭个位显示
delay(2); //百关闭个位显示延时
}
void timeToBuffer() //转换段码功能模块
{
if (jsz>zzz) //测量值大于测量上限时显示“CCC”
{
buffer[0]=0x93; //显示 C
buffer[1]=0x93; //显示 C
buffer[2]=0x93; //显示 C
}
else if (jsz<mq) //测量值小于测量下限时显示“CCC"
{
buffer[0]=0xFE; //显示 -
buffer[1]=0xFE; //显示 -
buffer[2]=0xFE; //显示 -
}
else
{
xm0=jsz/100; //计算百位值
xm1=(jsz-xm0*100)/10; //计算十位值
xm2=jsz-xm0*100-xm1*10; //计算个位值
buffer[0]=convert[xm2]; //进行个位显示段码转换
buffer[1]=convert[xm1]; //进行十位显示段码转换
buffer[2]=convert[xm0]; //进行百位显示段码转换
if (buffer[2]==0x81) //判断百位是否为零
{
buffer[2]=0xFF; //百位为零时不显示
}
}
}
void csbcj() //超声波测距程序
{
TR0=0; //停止定时器1工作
TH1=0x00; //计时器1清零
TL1=0x00; //计时器1清零
csbint=1; //置单片机超声波接收口高高电平
sx=0; //停止报警声响
delay(1700); //进行延时
csbfs(); //调用超声波发送子程序:CSBFS.ASM
csbout=1; //置单片机超声波输出端口P2.7为高电平
TR1=1; //超声波发头发送完超声波后,启动定时器1进行计时
i=250; //盲区处理系数
while(i--) //盲区延时处理
{
}
i=0;
while(csbint) //进行超声波回波判断,判断接收回路是否收到超声波的回波,接收到回波时,csbint=0
{
i++;
if(i>=3300) //规定时间没收到回波时退出判断处理程序
csbint=0; //规定时间内接收到回波时,置csbint=0
}
TR1=0; //停止计时器1计时
t=TH1; //提取计时器记录的高8位值
t=t*256+TL1; //计算计时的总时间
TR0=1; //恢复定时器0工作
csbint=1; //超声波接收端置高电平,这下次测量做准备
jsz=t*csbc; //计算测量结果
jsz=jsz/2; //计算测量结果
}
void bgcl() //报警处理继电器动作判断程序
{
if (jsz<dz) //测量值低于设定的报警值,继电器吸合
{
bjh=0; //继电器吸合
}
else
{
bjh=1; //继电器断开
}
}
void offmsd() //百位为数0判断模块
{
if (buffer[2]==0x81) //如果值为零时百位不显示
buffer[2] = 0xff;
}
复制代码
所有资料51hei提供下载:
超声波.7z
(27.31 KB, 下载次数: 69)
2019-6-20 14:00 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1