超声波测距系统设计
课程
设 计 说 明 书
学生姓名:
学 院:
专 业:
题 目:
指导老师
J Guo 学 号: 计算机与控制工程学院 自动化 倒车测距系统设计 职职称 副教授 称 讲 师
2013 年10月21日
1 设计内容
设计一个由单片机控制的倒车测距监测系统,倒车时可以监测车尾与障碍物的距离,近距离时可报警提示。
2 设计要求
选择传感器,设计键盘、测距和报警电路,按下“启动”键,每隔1秒,检测1次车尾和障碍物的距离,检测范围0-2m ,测量精度±0.1米,距离小于0.5米时自动报警提示;倒车完毕,按下“停止”键,系统停止运行。 3 系统设计方案
本设计主要是进行距离的测量和报警,设计中涉及到的内容较多,主要是将单片机控制模块、测距模块、蜂鸣器报警模块、显示模块这几个模块结合起来。而本设计的核心是测距模块,其他相关模块都是在测距的基础上拓展起来的,首先选择合适的测距传感器,之后选择合适单片机芯片,以下就是从相关方面来论述的。
3.1 激光测距
一个典型的激光测距系统应具备以下几个单元:激光发射单元,激光接收单元,距离计算与显示单元,准直与聚焦单元。系统工作时,激光由发射单元发出,以光速到达目标物后反射回来,被接收单元接收,通过距离计算与显示单元得到目标物距离。激光测距中的一种方法是脉冲测距法。目前,脉冲激光测距获得了广泛的应用。脉冲激光测距利用激光脉冲持续时间极短,能量在时间上相对集中。其基本原理是:在测距点向被测目标发射一束短而强的激光脉冲,光脉冲发射到目标上后其中一小部分激光反射到测距点被光功能接收器所接收。假定光脉冲在发射点与目标间来回一次所经历的时间间隔为t ,那么被测目标的距离D 为: D=c.t/2 (3-1)
在式3-1 中C 表示光速,当认为光速一定时(不考虑大气中光速的微小变化) ,脉冲时间误差为△t ,那么由此可以确定测距精度: ∆D =c ⋅∆t 2 (3-2)
测距系统设计该系统主要由脉冲半导体激光二极管发射电路、光学元件、漫反射物体、接收系统、高精度时间转换芯TDC-GP1、单片机构成,激光发射电路打出窄脉宽光脉冲,同时将发射脉冲输入TDC-GP1 的START 端口,触发时差测量。一旦从物体传回的发射脉冲达到了光电探测器(接收电路) 则给了TDC 产生一个STOP 信号,这个时候时差测量完成。TDCGP1记录从START 到STOP 脉冲之间的时差,用于计算所测物体与发射端的距离。单片机对于TDC-GP1 进行寄存器配置以及时间测量控制,时间测量结果传回给单片机通过算法进行距离的精
确计算和处理,再将结果送给液晶显示出来。
3.2 红外测距
红外线发射器不断发射出频率为40 kHz 的红外线, 经障碍物反射, 红外线接收器接收到反射波信号, 并将其转变为电信号。测出发射波与接收到反射波的时间差t ,即可求出距离: s =c ∙t 2 (3-3)
(3-3) 式中, c 为光速度, 一般取3 ×108 m/ s。本文采用“计数”方式, 通过单片机处理进行测量, 其基本原理是:红外线发射器始终处于发射红外线的状态, 当红外接收器第一次接收到障碍物反射回的红外线时, 经电路处理单片机给出一个计数启动信号, 单片机的计数器开始以一定频率计数;当红外线接收器第二次接收到反射回的红外线时, 经电路处理单片机给出一个停止计数脉冲, 计数器停止计数。通过编程, 单片机自动处理, 用脉冲的周期T 乘以脉冲数n 就得到发射红外线到接收红外线的时间差t , 即:t = nT (3-4) ,(3-4) 式代入(3-3) 式就得测量距离。系统的建立根据以上的测距原理, 设计出系统的基本构架。红外线测距系统的红外发射电路发射出40 kHz 频率的红外线, 当遇到障碍物红外线发生漫反射, 红外线接收电路第一次接收到反射的红外线时, 给单片机一个信号脉冲, 启动单片机内的计数器, 计数器置位进入计数状态; 当接收电路第二次接收到反射器的红外线时, 经单片机处理给出一个信号脉冲, 使计数器停止计数, 数据被锁存, 然后经单片机处理, 将测量的距离显示在显示器上。
3.3 超声波测距
与激光测距、红外线测距相比, 超声波对外界光线、色彩和电磁场不敏感, 更适于黑暗、电磁干扰强、有毒、灰尘或烟雾的恶劣环境, 在识别透明及漫反射性差的物体上也更有优势。超声波测距是一种非接触式测量, 广泛应用于倒车防撞雷达、机器人接近觉、海洋测量、物体识别等领域。 超声波测距原理超声波测距从机理上可以分为共振式和脉冲反射式两种, 该设计采用后者。工作时由超声波发射极发射超声波, 同时开始计时, 超声波在空气中传播, 当碰到障碍物时, 由于其良好的反射能力而被反射, 由超声波接收极接收, 此时计时结束。记超声波往返的时间为t, 根据s= ct / 2 计算超声波收发极与障碍物之间的距离, 这就是通常所说的渡越时间法, 也称时间差测距法。其中c 为超声波波速, 与环境温度有关, 在测量精度要求高的场合要考虑温度影响, 可由软件进行调整补偿; 在测量精度要求不是很严格的情况下, 可以忽略温度的影响, 认为c 为常数, 设计中取c= 340 m/ s。
根据对以上三种传感器性能的比较,虽然能明显看出来激光传感器是比较理想的选择,但是它的价格却比较高,而且安全度不够高。而且汽车在行驶的过程中测距传感器测距时应具有较强的抗干扰能力和较短的响应时间,因此选用超声波传感器作为此设计方案的传感器探头。
4 系统硬件设计
此方案选择51单片机作为控制核心,所测得的距离数值LCD 液晶显示器显示,与障碍物之间的距离低于安全距离时利用蜂鸣器报警声提示,超声波发射信号由51单片机的P2.1口送出到超声波发射电路,将超声波发送出去,超声波接收电路由CX20106A 芯片和超声波接收探头组成的电路构成,报警系统由蜂鸣器电路构成。该超声波测距系统硬件电路组成比较简单, 包括单片机、超声波测距模块、LCD1602液晶显示器、按键4 部分。总体框图如图4-1。
图4-1 总体框图 4.1控制核心STC12C5A60S2
STC12C5A60S2/AD/PWM系列单片机是宏晶科技生产的单时钟、机器周期(1T)的单片机,是高速、低功耗、超强抗干扰的新一代8051单片机,指令代码完全兼容传统8051, 但速度快8-12倍。内部集成MAX810专用复位电路,2路PWM,8路高速10位A/D转换(250K/S),针对实时性要求比较高的系统。完全可以满足本系统设计要求。最小系统图如图
4-2。
图4-2单片机最小系统
4.2超声波测距模块
根据经济适用的原则,选择DYP-ME007超声波传感器作为测距模块,其基本性指标如下:
1. 使用电压:DC5V
2.静态电流:小于2mA
3. 电平输出:高5V
4. 电平输出:低0V
5. 感应角度:不大于15度
6. 探测距离:2cm-750cm
7. 高精度:可达3mm
接线方式,VCC 、trig (控制端)、echo (接收端)、GND 地线。
本产品使用方法:一个控制口发一个10US 以上的高电平, 就可以在接收口等待高电平输出. 一有输出就可以开定时器计时, 当此口变为低电平时就可以读定时器的值, 此时就为此次测距的时间, 方可算出距离. 如此不断的周期测, 就可以达到你移动测量的值了。
模块工作原理:
(1)采用IO 触发测距,给至少10us 的高电平信号;
(2)模块自动发送8个40khz 的方波,自动检测是否有信号返回;
(3)有信号返回,通过IO 输出一高电平,高电平持续的时间就是超声波从发射到返回的时间.测试距离=(高电平时间*声速(340M/S))/2。超声波传感器实物图如图4-3.
图 4-3超声波传感器实物图
4.3数据显示模块
出于人性化设计考虑,系统设计采用LCD 液晶显示器实时显示汽车与障碍物之间的距离,便于驾驶员倒车操作。
1602液晶也叫1602字符型液晶,它是一种专门用来显示字母、数字、符号等的点阵型液晶模块。它由若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用,正因为如此所以它不能很好地显示图形(用自定义CGRAM ,显示效果也不好)。1602LCD 是指显示的内容为16X2, 即可以显示两行,每行16个字符液晶模块(显示字符和数字)。市面上字符液晶大多数是基于HD44780液晶芯片的,控制原理是完全相同的,因此基于HD44780写的控制程序可以很方便地应用于市面上大部分的字符型液晶。本设计所选用的LCD1602的规格及硬件原理如图4-4、4-5。
图4-4 LCD1602的规格示意图
图4-5LCD1602的硬件原理图
5系统软件设计
由超声波测距模块的工作原理:采用I/O触发测距,给至少10us 的高电平信号;模块自动发送8个40khz 的方波,自动检测是否有信号返回;有信号返回,通过IO 输出一高电平,高电平持续的时间就是超声波从发射到返回的时间.测试距离=(高电平时间*声速(340M/S))/2。系统软件设计中包括触发程序、时间记录及距离计算程序、LCD 显示程序、蜂鸣器驱动发生程序及各程序块的连接程序。
5.1总体流程
首先是单片机给超声波模块至少10us 的高电平信号,当超声波模块接收到回波后超声波模块输出管脚输出高电平,随即启动定时器,直至管脚电平变成低电平,计时结束,结合公式即可计算出距离。距离的数据经转化后用LCD1602直观显示出来,与此同时单片的一直对距离数据进行判断,如果距离小于设定的安全距离时,执行蜂鸣器驱动程序,发出报警。主程序图如图
5-1.
图5-1 主程序图
5.2启动超声波模块程序
采用I/O触发测距,单片机通过I/O口给超声波测距模块至少10us 的高电平信号。为保证精确计时同时节约硬件资源减少冗余代码,可采用_nop()库函数做延时函数进行触发操作。部分代码如下:
void StartModule()
{
TX=1;//启动模块,(TX )向超声波模块发出大于10us 的触发脉冲 _nop_();
_nop_(); //一个_nop_()相当于延时1us ,从而启动超声波测距模块 _nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
TX=0;//脉冲发射结束
}
5.3 LCD1602显示算法程序
工作时由超声波发射极发射超声波, 同时开始计时, 超声波在空气中传播, 当碰到障碍物时, 由于其良好的反射能力而被反射, 由超声波接收极接收, 此时计时结束。记超声波往返的时间为t, 根据s= ct / 2 计算超声波收发极与障碍物之间的距离。计算出来的距离通过算法处理可用LCD1602液晶显示器直观显示出来。部分算法代码如下:
void Conut(void)
{
time=TH0*256+TL0;//超声波发射返回时间用定时器来计时(16位) TH0=0;//重新初始化
TL0=0;
S=(time*1.7)/10; //单位为MM ,结合超声波340m/s来计算
if(S
{
WriteCommandLCM(0x01,1); //显示清屏
DisplayListChar(0, 1, table2);//显示倒车完毕警告!! Ring();//驱动蜂鸣器发声
}
else if((S>=7000)||flag==1) //超出测量范围,7M 为最大范围
{
flag=0;
DisplayListChar(0, 1, table1); //显示相应超出范围的提示 }
else //正常距离范围则实时显示距离
{
disbuff[0]=S%10;
disbuff[1]=S/10%10;
disbuff[2]=S/100%10;
disbuff[3]=S/1000;
DisplayListChar(0, 0, Range);
DisplayListChar(0, 1, table);
DisplayOneChar(9, 1, ASCII[disbuff[3]]);
DisplayOneChar(10, 1, ASCII[disbuff[2]]);
DisplayOneChar(11, 1, ASCII[disbuff[1]]);
DisplayOneChar(12, 1, ASCII[10]);
DisplayOneChar(13, 1, ASCII[disbuff[0]]);
}
}
5.4 蜂鸣器驱动算法程序
在本设计中,以简单易行为设计准则,报警装置用蜂鸣器充当。单片机的I/O口可以直接驱动小型蜂鸣器,但是由于电流很小,声音强度不足,所以可将I/O口输出的驱动信号经放大电路放大后驱动蜂鸣器。蜂鸣器驱动代码如下:
void Ring(void)
{
unsigned int i;
for(i=0;i
{
DelayUs2x(200);
SPK=!SPK;
}
SPK=0;//防止一直给喇叭通电造成损坏
for(i=0;i
{
DelayMs(1);
}
}
6 倒车测距系统实物
在设计完毕后,根据设计进行硬件仿真,仿真结果表明,设计原理符合客观实际,很好地实现了设计要求指标:距离检测范围:0.02M —7.00M ,响应速度:小于1s,, 安全距离:设定为0.5M 。硬件仿真效果如图6-1,6-2。
图6-1 硬件仿真
图 6-2 硬件仿真
7 结论
本文采用超声波传感器设计了一种可视化的倒车测距系统, 并比较了红外测距系统及激光测距系统在汽车防撞系统的运用。根据系统设计,为使测量的时间差t 准确, 采取两种方法提高精确度:
1) 安装多个超声波传感器,避免死角;
2) 减小扫描周期,进行N 次测量,以N 次测量时间的平均值作为有效值。当然, 为了使汽车倒车防撞系统实用化还需解决如下几个问题:
1) 怎样防止倒车时, 因道路两旁物体, 临车道上的车辆产生错觉问题;
2) 增加减震措施,防止系统因震动影响工作可靠性的问题;
3) 发出什么样的报警信号才能使司机不造成紧张不安的情绪;
4) 如何进一步提高单片机计数工作频率, 减少误差;
5) 动态探测距离有待进一步提高。
这些问题有待进一步研究、探讨。相信随着器件的改进和实验条件的改善, 这些问题会得到圆满解决。总之, 由于本系统成本低、精确度较高、功能多、人性化具有广阔的市场。
8 致谢
本文是在导师张艳兵副教授的悉心指导下完成的" 感谢他在课题的理论研究和技术细节方面给予我的指导和帮助" 导师严谨的治学态度, 实事求是的工作作风和勇于开拓进取的精神使我受到深刻的教育, 让我获益菲浅, 为我今后的工作和学习打下了良好的基础" 在此, 谨向导师致以崇高的敬意! 感谢我所在学院的领导和同志们, 感谢他们为我完成本课题而提供了必要的时间和条件" 本论文的顺利完成是和他们的热情支持和帮助分不开的" 感谢学院的各位领导! 老师以及班主任加俊老师, 正是由于他们的热情指导和帮助, 使得本课题在规定的时间内按要求得以完成" 最后, 向所有关心! 理解! 支持和帮助过我的老师! 领导! 同志和朋友们致以诚挚的谢意!
9 参考文献
[1]赵广涛, 程荫杭. 基于超声波传感器的测距系统设计[J].微计算机信息,2006,01:129-130+149.
[2]孙骁苗, 周东辉, 栗欣, 李立. 移动机器人的多传感器测距系统设计[J].传感器与微系统,2006,02:50-52.
[3]陆晓元, 林久令, 张海明, 王晋疆. 一种激光测距系统用纳秒脉冲变压器的设计
[J].仪表技术,2008,03:65-66+59.
[4]张瑞玲, 刘洪运. 单模VCSEL 激光自混和测距系统设计[J].西南民族大学学报(自然科学版),2008,04:758-762.
[5]宋永东, 周美丽, 白宗文. 高精度超声波测距系统设计[J].现代电子技
术,2008,15:137-139.
[6]陈安健, 郑炜. 脉冲激光测距系统中非球面物镜的设计[J].激光与红外,2005,07:524-526.
[7]李田泽, 李增祥, 孙永伟. 激光测距系统的设计[J].计量技术,2003,03:6-8.
[8]戴曰章, 吴志勇. 基于AT89C51单片机的超声波测距系统设计[J].计量与测试技术,2005,02:17-19.
[9]贺静, 王树才, 胡炼. 基于声纳传感器和C8051F040的测距系统设计[J].现代电子技术,2009,18:144-146.
[10]李航, 王可人. 基于STC89C52RC 的超声波测距系统设计[J].电子测试,2010,01:55-58.
[11]赵小强. 简易的超声波测距系统[J].天津理工大学学报,2010,01:49-52.
[12]蒋晓玲, 孟志强, 陈燕东, 许亮, 罗廷芳, 常金武. 汽车追尾防撞红外测距系统
[J].光电子技术,2011,01:67-72.
[13]杨旭, 刘小方, 张泽奇, 温婷. 基于单片机的超声波测距系统设计[J].机床与液压,2011,08:106-108+124.
[14]张邦成, 张玉玲, 王昕, 韩跃营, 姜艳青. 超声红外复合测距系统设计[J].制造业自动化,2011,14:122-124.
[15]顾国荣, 鲍骏成, 李海乐. 基于单片机的超声波测距系统设计[J].沿海企业与科技,2012,02:42-45.
[16]杨光照, 许春晖, 张德浩, 郑莎, 谭明香. 基于单片机的激光测距系统设计[J].中国新技术新产品,2012,10:36-37.
[17]岳文豹, 杨录, 张艳花.FMCW 雷达近程测距系统设计[J].电子技术应用,2012,04:73-75+79.
[18]王小华, 周松青, 殷严刚. 基于温度补偿的超声波测距系统设计[J].广西物理,2012,02:10-14.
[19].中小学尝试教育骨干教师研修班及校长论坛11月中旬在上海举行[J].人民教育,2012,19:58.
[20]陈安健, 路晓东. 一种新型军用激光测距系统的设计与研究[J].激光与红外,2001,02:90-92.
[21]兰羽. 基于40kHz 超声波测距系统的设计[J].机械与电子,2013,08:66-69.
[22]吕涛, 刘志刚, 邓忠文, 陶龙, 龚海. 一种光纤组量程扩增的激光频率扫描干涉绝对测距系统[J].西安交通大学学报,2013,09
[23] 赵负图. 传感器集成电路手册[M ]. 北京: 化学工业出版社, 2002. 4
[24] 孙宝元等. 传感器及应用手册[M ]. 北京: 机械工业出版社, 2004. 1
[25] 郑国钦等. 集成传感器应用入门[M ] . 浙江: 浙江科学技术出版社, 2003. 2
[26] 何希才. 传感器及其应用立例[M ]. 北京: 机械工业出版社, 2004. 1
[27] 沙占友. 集成化智能传感器原理与应用[M ]. 北京: 电子工业出版社, 2004. 6
[27]毕满清.模拟电子技术基础[M].电子工业出版社. 北京.2008,06
[28]王划一, 杨西侠. 自动控制原理[M]. 国防工业出版社. 北京.2010,08.
[29]赵山林. C程序设计[M]. 高等教育出版社. 北京.2010,08.
10 程序清单
10.1 主要代码
/*------超声波倒车雷达(用LCD1602显示)-----------*/
/*------修改日期:2013年10月21日------------------*/
/*------修改人: ------------------------------*/
/*------超声波模块芯片DYP-ME007-------------------*/
//DYP-ME007共5个引脚,tri (控制端TX )单片机对其输入大于10us 的触发脉冲 //Echo:(接收端RX ),接收超声波反射回来的信号,输出高电平
//out:为空引脚,一般不接
#include
#include
#include"lcd1602.h"
#include"ring.h"
#include"ring.h"
sbit RX=P2^0; //超声波模块接收发射信号trig
sbit TX=P2^1; //单片机相超声波模块发出激发脉冲Echo
sbit START=P2^2;//启动
sbit STOP=P2^3;//停止
unsigned char flagkey;
/*******************************************************
距离计算函数
*********************************************************/
void Conut(void)
{
time=TH0*256+TL0; //计算时间,超声波发射返回时间用定时器来计时(16位计时器) TH0=0;
TL0=0;
S=(time*1.7)/10; //算出来是MM ,结合超声波340m/s来计算
if(S
{
WriteCommandLCM(0x01,1); //显示清屏
DisplayListChar(0, 1, table2); //显示倒车完毕警告!!
Ring();
}
else if((S>=7000)||flag==1) //超出测量范围
{
flag=0;
DisplayListChar(0, 1, table1); //显示相应超出范围的提示
}
else
{
disbuff[0]=S%10;
disbuff[1]=S/10%10;
disbuff[2]=S/100%10;
disbuff[3]=S/1000;
DisplayListChar(0, 0, Range);
DisplayListChar(0, 1, table);
DisplayOneChar(9, 1, ASCII[disbuff[3]]);
DisplayOneChar(10, 1, ASCII[disbuff[2]]);
DisplayOneChar(11, 1, ASCII[disbuff[1]]);
DisplayOneChar(12, 1, ASCII[10]);
DisplayOneChar(13, 1, ASCII[disbuff[0]]);
}
}
/*******************************************************
定时器0中断函数
功能:T0中断用来纪录回波时间间隔,计数器溢出, 超过测距范围
*********************************************************/
void inter_T0() interrupt 1
{
flag=1; //中断溢出标志
RX=0;
}
/*******************************************************
启动超声波模块函数
*********************************************************/
void StartModule()
{
TX=1; //启动一次模块,(TX )向超声波模块发出大于10us 的触发脉冲 _nop_();
_nop_(); //一个-nop-()相当于延时1us ,从而启动超声波测距模块
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_(); //脉冲发射结束
TX=0;
}
/*******************************************************
计算超声波发射接收时间的函数
原理:信号返回,超声波模块输出高电平,持续时间即为从发射到返回的时间
*******************************************************/
void Timer_Count(void)
{
TR0=1; //开启计数
while(RX); //
TR0=0; //关闭计数
Conut(); //计算距离
}
/********************************************************
主函数
*********************************************************/
void main(void)
{
unsigned int valA;
Delay400Ms(); //启动等待,等LCM 讲入工作状态
LCMInit(); //LCM初始化
Delay5Ms(); //延时片刻
DisplayListChar(0, 0, Range);
DisplayListChar(0, 1, table);//初始状态LCD 显示
TMOD=0x01;//定时器0工作在模式1,16位定时器;
EA=1; //开总中断
TH0=0; //计时器赋初值,
TL0=0;
ET0=1; //允许T0中断
while(1)
{
if(STOP==0)
{
flagkey=1;
WriteCommandLCM(0x01,1); //显示清屏
DisplayListChar(0, 1, table3); //显示倒车完毕警告!!
}
else if(START==0)
{
flagkey=0;
}
if(flagkey==0)
{
RX=1; //接收引脚初始化
StartModule(); //启动超声波模块
for(valA=7500;valA>0;valA--) //扫描周期
{
if(RX==1) //表示超声波模块信号已经返回,开始计时;
{
Timer_Count(); //计算显示距离
}
}
}
}
}
10.2 LCD1602 .H代码
#ifndef __LCD1602_H__
#define __LCD1602_H__
#include
sbit LCM_RW=P2^5; //定义LCD1602的引脚
sbit LCM_RS=P2^4;
sbit LCM_E=P2^6;
sbit waring=P3^2;
#define LCM_Data P0
#define Busy 0x80 //用于检测LCM 状态字中的Busy 标识
void LCMInit(void);//LCD初始化函数
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);//LCD显示一个字符函数
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);//LCD显示一个字符串函数
void Delay5Ms(void);//延时5毫秒函数
void Delay400Ms(void);//延时400毫秒函数
void Decode(unsigned char ScanCode);
void WriteDataLCM(unsigned char WDLCM);//LCD1602写数据函数
void WriteCommandLCM(unsigned char WCLCM,BuysC);//LCD写命令函数
unsigned char ReadStatusLCM(void);
unsigned char code Range[] ="=DistanceFinder=";//LCD1602显示格式
unsigned char code ASCII[13] = "0123456789.-M";
unsigned char code table[]="Distance:000.0cm";
unsigned char code table1[]="!!! Out of range";
unsigned char code table2[]="!!! Denger";
unsigned char code table3[]="STOP";
unsigned int time=0; //超声波发射返回时间
unsigned long S=0; //距离
bit flag =0; // 测量超出量程的标志,主要以定时器的溢出来判定
unsigned char disbuff[4]={ 0,0,0,0,};
//写数据
void WriteDataLCM(unsigned char WDLCM)
{
ReadStatusLCM(); //检测忙
LCM_Data = WDLCM;
LCM_RS = 1;
LCM_RW = 0;
LCM_E = 0; //若晶振速度太高可以在这后加小的延时
LCM_E = 0; //延时
LCM_E = 1;
}
//写指令
void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测 {
if (BuysC) ReadStatusLCM(); //根据需要检测忙
LCM_Data = WCLCM;
LCM_RS = 0;
LCM_RW = 0;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
}
//读数据
unsigned char ReadDataLCM(void)
{
LCM_RS = 1;
LCM_RW = 1;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
return(LCM_Data);
}
//读状态
unsigned char ReadStatusLCM(void)
{
LCM_Data = 0xFF;
LCM_RS = 0;
LCM_RW = 1;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
while (LCM_Data & Busy); //检测忙信号
return(LCM_Data);
}
void LCMInit(void) //LCM初始化
{
LCM_Data = 0;
WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,1); //显示模式设置, 开始要求每次检测忙信号
WriteCommandLCM(0x08,1); //关闭显示
WriteCommandLCM(0x01,1); //显示清屏
WriteCommandLCM(0x06,1); // 显示光标移动设置
WriteCommandLCM(0x0c,1); // 显示开及光标设置
}
//按指定位置显示一个字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
Y &= 0x1; //x代表液晶屏g 上显示时在该行的位置,Y 代表行号,最大两行,分别为0,1行
X &= 0xF; //限制X 不能大于15,Y 不能大于1
if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
X |= 0x80; //算出指令码
WriteCommandLCM(X, 1); //发命令字
WriteDataLCM(DData); //发数据
}
//按指定位置显示一串字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData) {
unsigned char ListLength;
ListLength = 0;
Y &= 0x1;
X &= 0xF; //限制X 不能大于15,Y 不能大于1
while (DData[ListLength]>0x19) //若到达字串尾则退出
{
if (X
{
DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符 ListLength++;
X++;
}
}
}
//5ms延时
void Delay5Ms(void)
{
unsigned int TempCyc = 5552;
while(TempCyc--);
}
//40ms延时
void Delay400Ms(void)
{
unsigned char TempCycA = 5;
unsigned int TempCycB;
while(TempCycA--)
{
TempCycB=7269;
while(TempCycB--);
};
}
#endif
10.3 Ring.H
#ifndef __RING_H__
#define __RING_H__
/*-----------------------------------------------
内容:模拟报警声,如闹钟 滴 滴 滴 滴
------------------------------------------------*/
#include //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义 sbit SPK=P1^2; //定义喇叭端口
unsigned char frq;
void DelayUs2x(unsigned char t);//函数声明
void DelayMs(unsigned char t);
/*------------------------------------------------
报警函数
------------------------------------------------*/
void Ring(void)
{
unsigned int i;
for(i=0;i
{
DelayUs2x(200);
SPK=!SPK;
}
SPK=0;//防止一直给喇叭通电造成损坏
for(i=0;i
{
DelayMs(1);
}
}
/*------------------------------------------------
uS 延时函数
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{
while(--t);
}
/*------------------------------------------------
mS 延时函数
------------------------------------------------*/
void DelayMs(unsigned char t)
{
while(t--)
{
//大致延时1mS DelayUs2x(245); DelayUs2x(245); }
}
#endif
11 电路原理图
12 PCB图