单片机超声波测距-实训报告
基于STC11F04E单片机的超声波测距仪
实训报告
班级:信息091
姓名:邓志晓
学号:6311093128
目录
摘要….…………………………………………………………………3
一.超声波测距原理…………………………………………………4
二.超声波测距仪原理图……………………………………………4 1. 单片机最小系统电路/按键电路/LCD显示电路………………………5 2. 程序下载电路/电源电路/指示灯电路……………………………….…5 3. 超声波发送电路………………………………………………………...5 4. 超声波接收电路………………………………………………………...5 5. 其他电路………………………………………………………………..5
三.超声波测距仪功能介绍…………………………………………..6
四.超声波测距仪图片………………………………………………..6
五.实训心得…………………………………………………………..8
六.程序设计简介……………………………………………………..9
七.超声波测距仪部分程序………………………………………….10
摘要
本超声波测距仪是基于STC11F04E单片机的,该测距仪可测得精确距离为3~100CM,误差小于1CM,使用NOKIA 5110 LCD显示,全过程中文显示,便于用户使用。
单片机产生超声波经功率放大发送出去,接收到的超声波经CX20106产生中断让单片机计算距离,再通过LCD显示距离,本测距仪还有可调的报警距离设定功能、即将进入盲区提示功能、即将超出量程提示功能、开机显示各种预设画面功能。其中,进入报警距离调整状态时还有对应按键功能提示的功能。
一. 超声波测距原理
超声波测距原理是通过超声波发射器向某一方向发射超声波(一般为40KHz的超声波),在发射时刻的同时开始计时,超声波在空气中传播时碰到障碍物就立即返回来,超声波接收器收到反射波就立即停止计时。超声波在空气中的传播速度为v ,而根据计时器记录的测出发射和接收回波的时间差△t ,就可以计算出发射点距障碍物的距离S ,即:
S = v•△t /2
其中,超声波在空气中的传播速度给温度有关,速度V=332+0.607*T,T是环境温度,单位是摄氏度,因此,要精确测距要考虑温度的影响,采用温度补偿方式进行计算。
二. 超声波测距仪原理图
STC11F04E单片机最小系统电路/ 程序下载电路/
按键电路/NOKIA 5110LCD显示电路 电源电路/指示灯电路
超声波发送电路 超声波接收电路
其他功能:温度检测电路/日期时间电路/外部存储电路
1. 单片机最小系统电路/按键电路/LCD显示电路
STC11F04E单片机是51单片机的升级版,内置复位电路和振荡电路,本系统使用内置复位电路,按单片机说明书所说:在1号脚接1K电阻接地即可。
由于超声波测距要精确计时,如使用单片机内置的RC振荡电路,会因温度影响产生意想不到的测量误差,故使用外部振荡电路,本系统接11.0592MHz晶体振荡器电路。
按键电路是4个独立按键电路(由于本系统还有其它功能,IO口不够用,按键用的IO口和其它器件共用)。
显示部分采用NOKIA 的5110LCD显示,该LCD分辨率是48乘84,可显示中文,比1602LCD显示更加直观,且一个裸屏的价格仅为5元,该LCD外围电路简单,综上因素,本系统采用5110LCD显示测量距离等。
本测距仪开机还能显示预设的图片、文字等,详见超声波测距仪图片。
2. 程序下载电路/电源电路/指示灯电路
本系统采用基于PLC2132芯片的USB下载器,下载接口包含的线有:TXD、RXD、+5V、GND这四条线。
本系统的电源可由下载器或外部电源提供,连接到外部电源的接口是
3.5MM的电源母接口,至于由哪一路提供电源,可通过双刀双掷的锁定开关来进行选择。
指示灯电路是LED电路。
3. 超声波发送电路
由单片机产生40KHz的矩形波,送至非门驱动电路发送超声波,本系统超声波发送电路是采用74HC04的非门驱动电路,采用两个非门并联使用,以增加该发射电路的功率,而超声波发射器两引脚都接1K的上拉电阻,进一步增大了改电路的功率。
4. 超声波接收电路
本系统超声波接收电路选用了SONY公司的专用集成前置放大器CX20106,该芯片接收超声波能达到了比较好的效果。
超声波接收器接收到超声波信号经CX20106的前置放大器、限幅放大器、带通滤波器、检波器、积分器、整型电路从芯片的7号脚产生下降沿去触发单片机的外部中断,单片机接收到中断后做相应的处理和计算、显示。
5.其他电路
本测距仪除了测距功能外,还可以扩展基于DS1302时钟芯片的日期、星期、时间显示、DS18B20温度显示、24C256数据存储显示的功能。
由于STC11F04E单片机只有4K的内存,所以以上这三个功能只能写在另一个程序中,未能组合在本测距仪的程序中。
三. 超声波测距仪功能介绍
1. 测量范围:3CM~100CM。小于3CM是超声波的测量盲区,大于100CM时测量的距离跳动大,且不够稳定,这是由硬件电路所决定的。
2. 测量误差:小于1CM。超声波测距仪在某段距离内测量值等于真实值,当距离小于该段距离时,测量值比真实值小,当距离大于该段距离时,测量值比真实值大,故本测距仪根据实际差值,在软件中采用人工修正距离的方式来减小测量误差。虽然本系统还有测温功能,但不同温度下的人工修正值都不同,如果系统采用温度补偿,这每个温度刻度都需要一组人工修正值,这样工作量将无比庞大,故本系统未采用温度补偿来计算距离。
3. 报警方式:LED闪烁提示。LED
是5110LCD的四个背光灯,报警
距离默认值为15CM,可通过按键
设定,(正对着LCD,从左到右,
四个按键的功能分别是:确定、调
整/调位、加一、减一),当按“调
整/调位”键后,LCD将如右图显
示,图中最下面的一行显示的汉字
是对应每个按键功能的简称,此时
可通过按键调整报警距离,此时按
键要长按1S以上才有效。当测得的距离等于、小于设定的报警值时,LED闪烁,距离越小,闪烁的频率越高。
4.其它功能1:超出量程报警。该超声波测距仪最大量程为100CM,当超出
量程时,背光LED也会闪烁,超出量程越多,闪得越慢。
5. 其它功能2:本测距仪最小测距为3CM,当距离小于、等于10CM时,文
字提示“距进入盲区:X-3CM”X为测得的距离,且LED闪烁提示。
6. 其它功能3:当距离大于、等于90CM时,文字提示“距超出量程100-XCM” X为测得的距离。
四. 超声波测距仪图片
开机显示1 开机显示
2
开机显示3
俯视图
取下LCD的俯视图
正常测距 开机显示
4
侧视图
底视图 正常测距
扩展功能1:将进入盲区提示 扩展功能2:将超出量程提示
五. 实训心得
本次单片机实训的内容是制作一个超声波测距仪,超声波测试仪虽然网上资料很多,典型电路也多得很,一些看似简单的电路其实做出来一点都不简单,本测距仪的电路看似简单,但在做的过程中遇到的问题可不少。
通过本次单片机实训,我深深地感受到一个看似简单的作品也许不屑一顾,但再简单的东西部做出来,是不知道它的“简单”的。
首先,本测距仪的电路时现成的,所以,测试仪原理部分是没有什么问题的。画PCB主要要注意的是元件的封装问题,只要封装正确,硬件基本上没什么问题了。
由于5110LCD的显示驱动以前就写好了,现在直接调用就行了,显示部分没什么大问题。
难点主要在程序的调试上,刚开始时,我用定时器产生38KHz~42KHz的超声波发射出去,但在CX20106的7号引脚怎么都接收不到下降沿触发中断熄灭LCD的背光,开始以为,没有发射出去,但用示波器检测了发送38KHz~42KHz的超声波都接收不到,怀疑过超声波的收发器有问题、74HC04坏了、CX20106坏了等,连续折腾了好几天,先换超声波收发器,再换74HC04 最后换CX20106,才发现是CX20106坏了。换上好的CX20106后采用中断检测下降沿熄灭LCD背光的方法还是不行,最后写了测距显示的程序才勉强收到信号,连续几天的折腾终于看到了希望。
超声波是能接收到了,但是不准确,于是,不断调试,用过分10次测距100次距离,然后去掉一些最大值和最小值来求平均值的方法来提高精度,用过温度补偿的方式来测距,但效果都不是很理想,不是偏大就是偏小…… 最后还是采用测一次显示一次的方式来测距,测距仪不断地测距不断的显示,屏幕显示的数据在不断的刷新,由于不断测距显示中正确的距离占大多数,可能10次中才有一两次是错误的数据,因此显示的数据是显示中相同的或相近的数据,即显示的是正确的距离数据。由于本测距仪在某段距离内测得的距离是正确的,其它的误差很大,所以,根据实际情况在程序中采用人工修正距离的方式去进一步提高测量精度。
测距显示正确后,其它的LED报警、按键设定报警距离这些都能迎刃而解了,但是,想不到的是,程序太大了!即使把汉字显示数组存储在24C256中,4K的存储空间还是太小了。本来要加的时间、温度显示等扩展功能只能
舍弃,用了另外一个程序专门实现。
通过这次制作超声波测距仪的实训,我学到了很多很多。当然该作品还有很多不足之处,我会进一步去完善。
六. 程序设计简介
本测距仪的显示部分是NOKIA 5110 LCD,由于该液晶是
48行84列的无字库的点阵液晶,所以要自己用软件生成字库,生成的字库通过另外的程序存储在24C256中(24C256的驱动程序要自己写,这涉及IIC通信和24C256的读、连续读和写、页写);由于买来的5110LCD没有驱动程序,还是要自己写驱动程序,写的驱动有16乘16汉字显示、8乘16数字、符号显示、48乘84图形显示等。
单片机产生约40KHz的超声波波发射出去,定时器开始
计时,等待外部中断则停止定时器计数,所计的时间的一半乘以相应的速度,即可计算出距离,把距离分离出百位、十位、个位,然后调用5110LCD驱动显示。
主程序一开始就进行初始化设置,然后显示预设的图案文
字等。然后进入大循环不断判断标志位的值,该标志位的值通过按键控制,标志位的值不同,显示状态会相应改变,开始默认为正常测距状态,该状态下不断测距显示,还对距离和设定的报警值进行比较,当达到指定的条件时,则会采取相应的措施,如报警、显示“距进入盲区:X CM”等。还有一个是报警调整状态,进入该状态后,即启动按键扫描程序和执行调整显示程序,可通过按键设置报警距离。
七. 超声波测距仪部分程序
/************************************/
/*公司名称:广交电协*/
/*模块名:基于STC11F04E单片机超声波测距仪*/
/*功能描述:测距显示“距前方距离:***cm”,无温度补偿。带图形显示、文字提示报警
显示等*/
/*硬件:STC11F04E单片机超声波模块*/
/*编程:邓志晓 */
/*时间:2011/06/09*/
/*版本:V1.0*/
/************************************/
#include
#include"reg52.h"
#include"5110_display.h"
#define uint unsigned int
#define uchar unsigned char
sbit fasong = P3^4;//超声波发送端
sbit js = P3^2;//超声波接收
sbit black_led = P1^7;//液晶背光灯
sbit jian = P3^0;//减一键
sbit jia = P3^1;//加一键
sbit wei = P3^3;//位控、调整键
sbit que = P3^5;//确定键
bit flag;
bit flag1;
bit flag2;
int time;
//外部中断(测距计时的)接受标志 //定时器中断标志 //报警距离调整状态/正常显示状态标志 //超声波测距时间 //距离 //储存定时器1高八位 long float juli; uint a; uint th1;
uint tl1; //储存定时器1低八位
uchar bai,shi,ge;//距离的百、十、个位
char data baojing;//报警距离
char baoshi,baoge;//报警距离的个位和十位
uchar shan;//报警位闪烁控制
/**********************************
*函数名:delay
*功能描述:延时
**********************************/
void delay(uint z) //延时
{
uint a; uint b; for (a=z; a>0; a--) for (b=80; b>0; b--); }
/**********************************
*函数名:init
*功能描述:初始化函数
**********************************/
void init( void ) //初始化函数
{
TMOD = 0x11;
ET0 = 1;
fasong = 0;
//设置定时器1为十六进制计时工作方式 //允许定时器0中断 //无发射 EX0 = 0; //关外部中断0; IT0 = 1; //设置外部中断0工作为下降沿触发模式 EX1 = 1; //开外部中断1; IT1 = 1; //设置外部中断1工作为下降沿触发模式 PX1 = 1; //(外部中断0)接收优先
//开总中断 EA = 1;
flag2=1;//正常显示状态
shan=1;
baojing=15;//默认报警距离是15CM
black_led=1;//点亮LCD背光
}
/**********************************
*函数名:ceju
*功能描述:发送超声波
**********************************/
void ceju(void)
{
uchar e;
flag = 0;
//清零标志 flag1 = 0; TH1 = 0x00; TL1 = 0x00; //清零标志 //装初值,从零开始计时
TR1 = 0; //关闭定时器1
EX0 = 0; //关外部中断
for(e = 5; e>0; e--) //发送两40k个波
{
_nop_(); _nop_(); _nop_(); fasong = 1; _nop_(); _nop_(); _nop_();
_nop_();
fasong = 0;
_nop_(); _nop_();
}
TR1 = 1;
delay(1); //开始计时 //避忙延时1.5ms
IE0 = 0; //清除中断标志位
EX0 = 1; //开外部中断;
while( flag==0 && flag1==0 ); //等待中断
}
/**********************************
*函数名:xiuzheng
*功能描述:测得的数据有误差,人为修正、显示距离
**********************************/
void xiuzheng(void)
{
if(a
}
else if(34
/**********************************
*函数名:Key
*功能描述:按键扫描
**********************************/
void Key(void)
{
if(que==0)//确定键按下 { delay(10);//消抖 if(que==0) { while(!que); delay(10);//消抖 while(!que);//等待松手 shan=1;//下次进入调整状态仍在十位闪烁 flag2=1;//正常显示状态标志 clear_LCD();//清屏 display_hanzi();//显示“到前方距离: cm” } } if(wei==0)//调位键按下 { delay(10);//消抖 if(wei==0) {
delay(10);//消抖 while(!wei);//等待松手 shan++; if(shan==3) { shan=1; } } } if(jia==0)//加一键按下 { delay(10);//消抖 if(jia==0) { while(!jia); delay(10);//消抖 while(!jia);//等待松手 if(shan==1)//十位闪烁 { baoshi++;//十位加一 if(baoshi==10) { baoshi=0; } } else//个位闪烁 { baoge++;//个位加一 if(baoge==10) { baoge=0; } } } } if(jian==0)//减一键按下 { delay(10);//消抖 if(jian==0) { while(!jian); delay(10);//消抖
if(shan==1)//十位闪烁 { baoshi--;//十位减一 if(baoshi
}
/**********************************
*函数名:chuli
*功能描述:分离距离的百十个位,显示距离
**********************************/
void chuli(void)
{
uchar i;
EA = 0;
a = juli;
xiuzheng();
if(a>=3&&a
{
display_hanzi1(a-3);
}
else if(a10&&a100)//小于3CM或大于100CM或在10~90CM之间清屏“距进入盲区:a-3 cm”
{
for(i=7;i
for(i=1;i
}
else if(a>=91&&a
{
display_hanzi2(100-a);
}
bai = a % 1000 / 100; // 分离百位
shi = a % 1000% 100/10 ; // 分离十位
ge = a % 1000 % 100%10; // 分离个位
display_juli(bai,shi,ge);//显示测得的数据 bai shi ge (cm)
EA = 1;
}
/**********************************
*函数名:main
*功能描述:主函数
**********************************/
void main()
{
uint i;
init();//主程序初始化
Init_5110LCD();//初始化5110
display_tuxing();//显示图形DC 艺术字“邓志晓” QQ:************ 小志工作室荣誉
出品!
clear_LCD();//清屏
display_hanzi();//显示“到前方距离: cm”
while(1)
{
if(flag2==1)//正常显示
{ ceju ();//测距 chuli();//分离数据显示
if(a100&&a
{ black_led=~black_led;//LCD背光闪烁 if(a0;i--)
chuli();//分离数据显示 //当延时用 } } else if(a>100)//超出量程越近闪得越快 { for(i=a-100;i>0;i--) { chuli();//分离数据显示 //当延时用 } } } else { } black_led = 1;//点亮LCD背光 } else if(flag2==0)//报警距离调整状态 { black_led = 1;//点亮LCD背光
display_hanzi3(baoshi,baoge,shan);//显示“报警距离: baoshi baoge cm 确 位 加 for(i=9000;i>0;i--)
{
Key();//按键扫描 当延时用
} 减”
}
}
}
/**********************************
*函数名:timer1
*功能描述:超声波测距
**********************************/
void timer1(void) interrupt 3
{
TR1 = 0;
}
/**********************************
*函数名:IntX0 EX0 = 0; juli = 0; flag1 = 1; //停止T1计数 //关接收中断 //置定时标志位(表定时到)
*功能描述:超声波接收(外部中断计时)
**********************************/
void IntX0 (void) interrupt 0 //外部中断函数 { TR1 = 0; //停止T1计数
}
/**********************************
*函数名:zhongduan1
*功能描述:进入调整报警距离状态
**********************************/
void zhongduan1 (void) interrupt 2 //外部中断1函数 { flag2=0;//进入调整报警距离状态
baoshi=baojing/10;//报警距离的十位
baoge=baojing%10;//报警距离的个位
} EX0 = 0; th1 = TH1; //关接收中断 //把计数值放在 th1,tl1 //time的单位是us,time是超声波往返的时间 tl1 = TL1; time = th1*255 + tl1; juli = 0.0175 * time; time = 0; flag = 1; //单位厘米(340M/s=0.00034m/US=0.034cm/us) //清零寄存器 //置接收标志位(表接收到)