单片机超声波测距+WTD588D语音播报的设计

第一章 绪论

1.1 课题设计目的及意义

1.1.1设计的目的

随着科学技术的快速发展,超声波在测距中的应用越来越广。但就目前的急速水平来说,人们可以具体利用的测距技术还十分有限,因此,这是一个正在蓬勃发展而又有无限前景的技术及产业领域。由于超声波指向性强,能量消耗缓慢,在介质中传播的距离较远,因此超声波经常用于距离测量,如超声波测距和物位测量等都可以通过超声波来实现。利用超声波检测往往比较迅速、方便、计算简单、易于做到实时控制。为了研究和利用超声波,人们已经设计和制成了许多超声波发生器。研制具有更高定位精度的被动测距声纳,以满足水中武器实施全隐蔽攻击的需求;继续发展采用低频线谱检测的潜艇拖拽线列阵声纳,实现超远程的被动探测和识别;研制更适合与前还工作的潜艇声纳,特别是解决浅海水中目标识别问题;搭理降低潜艇自噪声,改善潜艇声纳的工作环境。毋庸置疑,无线的超声波测距将于自动化智能化接轨,与其他的测距仪集成和融合,形成多测距。随着测距仪的技术进步,测距仪将从具有单纯判断功能发展到具有学习功能,最终发展到具有创造力。在新的世纪里,面貌一新的测距仪将发挥更大的作用。

1.1.2设计的意义

由于超声测距是一种非接触检测技术,不受光线、被测对象颜色等的影响,较其它仪器更卫生,更耐潮湿、粉尘、高温、腐蚀气体等恶劣环境,具有少维护、不污染、高可靠、长寿命等特点,所以超声波测距系统主要应用于汽车的倒车雷达、机器人自动避障行走、建筑施工工地以及一些工业现场中的液位、井深、管进长度测量等场合。因此研究超声波测距系统有着很大的现实意义。对本课题的研究与设计,还能进一步提高自己的电路设计水平,深入对单片机的理解和应用。

1.2 国内外研究动态

    国外在提高超声波测距方面做了大量的研究,国内一些学者也作了相关的研究。目前超声波测距方法主要有三种:(1)相位检测法:精度高,但检测范围有限;(2)声波幅值检测法:易受反射波的影响;(3)渡越时间法:工作方式简单,直观。现在对超声波测距的精度主要取决于所测的超声波传输时间和超声波在介质中的传输速度,二者中以传输时间的精度影响较大,所以大部分文献采用降低传输时间的不确定度来提高测距精度。温度对传感器的影响也很大,因此,需要用温度传感器进行校正,目前相位探测法和声谱轮廓分析法或二者结合起来的方法是主要的降低探测传输不确定度的方法。

1.3 本课题研究的主要内容

超声波是指频率高于20KHz的机械波。为了以超声波作为检测手段,必须产生超生波和接收超声波。完成这种功能的装置就是超声波换能器。超声波传感器有发送器和接收器,但一个超声波换能器也可具有发送和接收声波的双重作用。超声波换能器是利用压电效应的原理将电能和超声波相互转化,即在发射超声波的时候,将电能转换,发射超声波;而在收到回波的时候,则将超声振动转换成电信号。
超声波测距的原理一般采用渡越时间法TOF(time of flight)。首先测出超声波从发射到遇到障碍物返回所经历的时间,再乘以超声波的速度就得到二倍的声源与障碍物之间的距离,拟应用以下三种技术:

    a、单片机技术:STC89C52系列的单片机具有体积小,重量轻,结构较为简单,成本低廉,可以实现一般的控制功能的优点。而且单片机更适用应用于小型的嵌入式系统,因此它得到了广泛的应用。现代人类生活大部分电子和机械产品中都会集成有单片机。

    b、超声波测距技术:超声波测距技术与一般测距技术相比,具有操作方便、系统简单以及计算简单的优点。

    c、显示技术:数据处理,数码管显示测出与物体之间的距离。

    d、语音模块技术:ISD1730A芯片来语音播报距离。

第二章 总体方案

2.1 方案选择

采用单片机来控制超声波测距,信号线发射到与超声波发射器相连的信号端,超声波发射器向既定方向发射,在发射的同时开始计时,超声波在空气中传播,途中碰到障碍物将产生回波。

2.2 超声波测距仪的设计思路
2.2.1 超声波测距原理

超声波测距的方法有多种,如相位检测法、声波幅值检测法和渡越时间检测法等。相位检测法虽然精度高,但检测范围有限,声波幅值检测法易受反射波的影响。

本测距系统采用超声波渡越时间检测法。其原理为:检测从发射传感器发射的超声波经气体介质传播到接收传感器的时间t,这个时间就是渡越时间,然后求出距离l。设l为测量距离,t为往返时间差,超声波的传播速度为c,则有l=ct/2。超声波接收器收到反射波就立即停止计时。再由单机计算出距离,送数码管显示测量结果。

超声波测距的算法设计: 超声波在空气中传播速度为每秒钟340米(15℃时)。t2是接收超声波时刻,t1是超声波声波发射时刻,t2-t1得出的是一个时间差的绝对值,假定t2-t1=0.03S,则有340m×0.03S=10.2m。由于在这10.2m的时间里,超声波发出到遇到返射物返回的距离如下: 如图2-2-1为测距原理[4]

图2-1测距原理

因为θ/2角度较小,可以忽略不计,所以L≈S。

超声波发出到遇到返射物返回的距离如下:

L=C x ( t2 -t1 )/ 2

由于超声波也是一种声波,其声速c与空气温度有关,一般来说,温度每升高1摄氏度,声速增加0.6米/秒。表2-1列出了几种温度下的声速。

表2-1  声速与温度的关系表

温度(摄氏度)

-30

-20

-10

0

10

20

30

100

声速(米/秒)

313

319

325

323

338

344

349

386

在使用时,如果温度变化不大,则可认为声速c是基本不变的,计算时取c为340m/s。如果测距精度要求很高,则可通过改变硬件电路增加温度补偿电路的方法或者在硬件电路基本不变的情况下通过软件改进算法的方法来加以校正。

2.2.2 超声波测距原理框图

     超声波测距模块用HC-SR04,温度传感器使用DS18B20,微处理器使用STC89C52单片机,显示部分采用共阳数码管。HC-SR04集成的发射电路模块发出超声波,遇到障碍物产生回波,被接收电路模块接收,STC89C52单片机统计出声波传输所用时间,经过温度补偿温,计算出正确的待测距离,同时ISD1730A根据相关数据处理进行组合播报当前测试距离,并且由数码管显示。

图2-2 超声波测距系统结构图



2.3 使用元件选择

由于测量距离的精度和长度要求不是很高,精度达到2cm,测量距离达到2m即可,因此超声波模块选用价格低廉且实用的HC-SR04即可。

    控制核心部分选择实用的STC89C52单片机即可满足计算和控制要求。

温度补偿的温度传感器选择普遍且实用的DS18B20。

    语音播报:ISD1730A是华邦公司新推出的语音芯片,用来替代已经停产的ISD1400 系列及ISD2500 系列芯片。ISD1730A不仅在录音时间上有更多的选择(从20秒到240 秒),而且在功能上继承14及25系列的所有录放功能,并增加了一些更加人性化的提示功能及对存储地址的精确操作。根据我们经营 ISD 系列芯片多年的经验来看,ISD1700 的音质也较14及25系列有明显的提高

ISD1700 系列芯片是华邦公司新推出的单片优质语音录放电路,该芯片提供多项新功能,包括内置专利的多信息管理系统,新信息提示(vAlert ),双运作模式(独立&嵌入式),以及可定制的信息操作指示音效。芯片内部包含有自动增益控制、麦克风前置扩大器、扬声器驱动线路、振荡器与内

存等的全方位整合系统功能。。

    显示部分:选择了四位数码管。

第三章 系统的硬件结构设计
3.1 STC89C52单片机的功能及特点

    STC89C52单片机是宏晶科技推出的新一代高速/低功耗/超强抗干扰的单片机,指令代码完全兼容传统 8051 单片机,12 时钟/机器周期和 6 时钟/机器周 期可以任意选择。

    主要特性如下:

    增强型 8051 单片机,6 时钟/机器周期和 12 时钟/机器周期可以任 意选择,指令代码完全兼容传统 8051.

    工作电压:5.5V~3.3V(5V 单片机)/3.8V~2.0V(3V 单片机)

    工作频率范围:0~40MHz,相当于普通 8051 的 0~80MHz,实际工 作频率可达 48MHz

    用户应用程序空间为 8K 字节

    片上集成 512 字节 RAM

    通用 I/O 口(32 个)复位后为:P1/P2/P3/P4 是准双向口/弱上拉,P0口是漏极开路输出,作为总线扩展用时,不用加上拉电阻,作为 I/O 口用时,需加上拉电阻。

    ISP(在系统可编程)/IAP(在应用可编程) ,无需专用编程器,无 需专用仿真器,可通过串口(RxD/P3.0,TxD/P3.1)直接下载用户程 序,数秒即可完成一片

    具有 EEPROM 功能

    具有看门狗功能

    共 3 个 16 位定时器/计数器。即定时器 T0、T1、T2

    外部中断 4 路,下降沿中断或低电平触发电路,Power Down 模式可由外部中断低电平触发中断方式唤醒

    通用异步串行口(UART),还可用定时器软件实现多个UART

    工作温度范围:-40~+85℃(工业级)/0~75℃(商业级)

STC89C52RC单片机的工作模式

掉电模式:典型功耗<0.1μA,可由外部中断唤醒,中断返回后,继续执行原 程序
    空闲模式:典型功耗 2mA 典型功耗

正常工作模式:典型功耗 4Ma~7mA 典型功耗

掉电模式可由外部中断唤醒,适用于水表、气表等电池供电系统及便携设备
    STC89C52RC 引脚功能说明

    VCC(40 引脚):电源电压

VSS(20 引脚):接地

    P0 端口(P0.0~P0.7 P0.7,39~32 引脚) :P0口是一个漏极开路的 8 位双向 I/O 口。作为输出端口,每个引脚能驱动 8 个 TTL 负载,对端口 P0 写入 每个引脚能驱动 写入“1”时,可 以作为高阻抗输入。在访问外部程序和数据存储器时 在访问外部程序和数据存储器时,P0 口也可以提供低 8 位 地址和 8 位数据的复用总线 位数据的复用总线。此时,P0 口内部上拉电阻有效。在 Flash ROM编在程时,P0 端口接收指令字节 端口接收指令字节;而在校验程序时,则输出指令字节 则输出指令字节。验证时,要求外接上拉电阻。

P1 端口(P1.0~P1.7,1~8 引脚) :P1口是一个带内部上拉电阻的 8 位双向 I/O 口。P1 的输出缓冲器可驱动(吸收或者输出电流方式)4 个 TTL 输入。对端 口写入 1 时,通过内部的上拉电阻把端口拉到高电位,这是可用作输入口。P1 口作输入口使用时,因为有内部上拉电阻,那些被外部拉低的引脚会输出一个电 流( ) 。

此外,P1.0 和 P1.1 还可以作为定时器/计数器 2 的外部技术输入(P1.0/T2)和定时器/计数器 2 的触发输入(P1.1/T2EX),具体参见下表:

在对 Flash ROM 编程和程序校验时,P1接收低 8 位地址。

表 XX P1.0 和 P1.1引脚复用功能

P2 端口(P2.0~P2.7,21~28 引脚) :P2 口是一个带内部上拉电阻的 8 位双向 I/O 端口。P2 的输出缓冲器可以驱动(吸收或输出电流方式)4个TTL输入。对端口写入 1 时,通过内部的上拉电阻把端口拉到高电平,这时可用作输入口。P2 作为输入口使用时,因为有内部的上拉电阻,那些被外部信号拉低的引脚会 输出一个电流(I) 。

    在访问外部程序存储器和16位地址的外部数据存储器(如执行“MOVX @DPTR”指令)时,P2 送出高 8 位地址。在访问 8 位地址的外部数据存储器(如 执行“MOVX @R1”指令)时,P2口引脚上的内容(就是专用寄存器(SFR)区 中的 P2 寄存器的内容),在整个访问期间不会改变。

    在对 Flash ROM 编程和程序校验期间,P2也接收高位地址和一些控制信号。

    P3 端口(P3.0~P3.7,10~17 引脚) :P3 是一个带内部上拉电阻的 8 位双向 I/O 端口。P3 的输出缓冲器可驱动(吸收或输出电流方式)4 个 TTL 输入。对端 口写入 1 时,通过内部的上拉电阻把端口拉到高电位,这时可用作输入口。P3 做输入口使用时,因为有内部的上拉电阻,那些被外部信号拉低的引脚会输入一 个电流( ) 。
    在对 Flash ROM 编程或程序校验时,P3 还接收一些控制信号。
    P3 口除作为一般 I/O 口外,还有其他一些复用功能,如下表所示:

表XX P3口引脚复用功能 复用功能

    RST(9 引脚) :复位输入。当输入连续两个机器周期以上高电平时为有效,用来完成单片机单片机的复位初始化操作。看门狗计时完成后,RST 引脚输出 96 个晶振周期的高电平。特殊寄存器 AUXR(地址 8EH)上的 DISRTO 位可以使此功 能无效。DISRTO 默认状态下,复位高电平有效。

    ALE/ ROG(30 引脚) 地址锁存控制信号 :(ALE)是访问外部程序存储器时, 锁存低 8 位地址的输出脉冲。在 Flash 编程时,此引脚( ROG)也用作编程输入 脉冲。

    在一般情况下,ALE 以晶振六分之一的固定频率输出脉冲,可用来作为外部 定时器或时钟使用。然而,特别强调,在每次访问外部数据存储器时,ALE 脉冲 将会跳过。

    如果需要,通过将地址位 8EH 的 SFR 的第 0 位置“1”,ALE 操作将无效。这 一位置“1”,ALE 仅在执行 MOVX 或 MOV 指令时有效。否则,ALE 将被微弱拉 高。这个 ALE 使能标志位(地址位 8EH 的 SFR 的第 0 位)的设置对微控制器处于 外部执行模式下无效。
    外部程序存储器选通信号(SEN)是外部程序存储器选 SEN(29引脚)
通信号。当 STC89C52RC 从外部程序存储器执行外部代码时,SEN在每个机器周 期被激活两次,而访问外部数据存储器时, SEN将不被激活。A/VPP(31引脚) 访问外部程序存储器控制信号。为使能从 0000H 到 FFFFH 的外部程序存储器读取指令,A必须接 GND。注意加密方式 1 时, A将内部锁 定位 RESET。为了执行内部程序指令, A应该接 VCC。在 Flash 编程期间, A也接收 12 伏 VPP 电压。 XTAL1(19 引脚) :振荡器反相放大器和内部时钟发生电路的输入端。 XTAL2(18 引脚):振荡器反相放大器的输入端。

图3-1 STC89C52引脚图

3.2单片机最小系统

    单片机最小系统,或者称为最小应用系统,是指用最少的元件组成的单片机可以工作的系统.
    对52系列单片机来说,最小系统一般应该包括:单片机、晶振电路、复位电路.

    单片机最小系统电路介绍
    52单片机最小系统复位电路的极性电容C1的大小直接影响单片机的复位时间,一般采用10~30uF,51单片机最小系统容值越大需要的复位时间越短。
    52单片机最小系统晶振Y1也可以采用12MHz,在正常工作的情况下可以采用更高频率的晶振,51单片机最小系统晶振的振荡频率直接影响单片机的处理速度,频率越大处理速度越快。
    52单片机最小系统起振电容C2、C3一般采用15~33pF,并且电容离晶振越近越好,晶振离单片机越近越好4.P0口为开漏输出,作为输出口时需加上拉电阻,阻值一般为10k。
    设置为定时器模式时,加1计数器是对内部机器周期计数(1个机器周期等于12个振荡周期,即计数频率为晶振频率的1/12)。计数值N乘以机器周期Tcy就是定时时间t。
    设置为计数器模式时,外部事件计数脉冲由T0或T1引脚输入到计数器。在每个机器周期的S5P2期间采样T0、T1引脚电平。当某周期采样到一高电平输入,而下一周期又采样到一低电平时,则计数器加1,更新的计数值在下一个机器周期的S3P1期间装入计数器。由于检测一个从1到0的下降沿需要2个机器周期,因此要求被采样的电平至少要维持一个机器周期。当晶振频率为12MHz时,最高计数频率不超过1/12MHz,即计数脉冲的周期要大于2 ms。

图3-2单片机最小系统


 

3.4 语音播报
    语音模块采用WT588D语音模块,WT588D是广州唯创与台湾华邦合作研发的一款语音芯片(单片机)。WT588D不仅可以作为一般语音芯片,当从片发声,而且因为I/O口多,带控制功能和外置FLASH存储器,所以能做FLASH单片机;最重要的是还可以按照样品直接投掩膜,管脚完全不用改动,价钱便宜一半。WT588D性能卓越,简单易用,与51单片机有着极为相似的性能。WT588D语音芯片是一款功能强大的可重复擦除烧写的语音单片机芯片。配套WT588D VioceChip上位机操作软件可随意更换WT588D语音单片机芯片的任何一种控制模式,把信息下载到SPI-Flash上即可。软件操作方式简洁易懂,撮合了语音组合技术,大大减少了语音编辑的时间。 MP3控制模式下,完全迎合市场上MP3的播放/暂停、停止、上一曲、下一曲、音量+、音量-等功能; 按键控制模式下触发方式灵活,可随意设置任意按键为脉冲可重复触发、脉冲不可重复触发、无效按键、电平保持不循环、电平保持可循环、非电平保持可循环、单键向前不循环、单键向后不循环、单键向前可循环、单键向后可循环、音量+、音量-、播放/暂停、停止、播放/停止等15种触发方式,最多可控制10个按键触发输出; 3×8按键组合控制模式下能以脉冲可重复触发的方式触发24个地址位语音,所触发地址位语音可在0~219之间设置;并口控制模式最多可用8个I/O口进行控制; 一线串口控制模式可通过发码端控制语音播放、停止、循环播放和音量大小,或者直接触发0~219地址位的任意语音,发码速度600us~2000us; 三线串口控制模式和三线串口控制I/O口扩展输出模式之间可通过发码切换,三线串口控制模式下,能控制语音播放、停止、循环播放和音量大小,或者直接触发0~219地址位的任意语音,三线串口控制I/O口扩展输出可以扩展输出8位,在两种模式下切换,能让上一个模式的最后一种状态保持着进入下一个模式。 PWM和DAC输出方式,PWM输出可直接推动0.5W/8Ω的扬声器,DAC输出外接功放,音质好。 应用范围广,几乎可以涉及到所有的语音场所,如报站器、报警器、提醒器、闹钟、学习机、智能家电、治疗仪、电子玩具、电讯、以及各种自动控制装置等场所,工艺上达到工业应用的要求。

WT588D的特性:
1.外挂2M~32M的Flash,时间从32—1054秒。掩膜为内置ROM,最长支持400秒(@6K采样)。采样率支持6K~22K
2.DAC输出:13Bit,PWM输出:12Bit
3.内置0.5W功放,可直接推动0.5W/8Ω扬声器
4.支持加载MP3/WAV/WMA三种音频格式
5.工作电压:DC2.8V~5.5V
6.静态休眠电流:<10uA
7.可通过电脑软件,随意组合语音,可插入静音,插入的静音不占用内存的容量,一个已加载语音可重复调用到多个地址,重复调用的,不占空间,这是其它芯片所不具备的
8.USB下载方式,支持在线下载/ISP下载
9.7种控制方式: MP3控制模式、按键控制模式、3×8矩阵控制模式、并口控制模式、一线串口控制模式、三线串口控制模式以及三线串口控制I/O口扩展输出模式
10.掩膜后的管脚与原来一致,性能一样,音质一样。不用更改电路。且不用焊接FLASH
11.最多可加载500段语音;210段可控制地址位,单个地址位最多可加载128段语音,地址位内的语音组合播放;
12.插入的静音时间范围10ms~25min;静音不占用存储空间;
语音提示模块电路图如图17所示


 

图3-3 语音播报电路

3.5 显示单元
本设计在接收端部分采用LCD1602液晶显示模块来显示温度,,P1由上拉电阻提高驱动能力,作为数据输出并作为LCD的驱动,P2口的P2.7-P2.6分别作为液晶显示模块的使能信号E,数据/命令选择RS,R/W端则配置成写。具体电路如图2.11所示。

图3-6 显示电路图

第四章 系统的软件设计

超声波测距仪的软件设计主要有主程序、超声波发生程序、超声波接收中断程序及显示子程序组成。我们知道C语言程序有利于实现较复杂的算法,汇编语言程序则具有较高的效率且容易精细计算程序运行的时间,而超声波测距仪的程序需要有较复杂的计算(计算距离时),所以控制程序可采用C语言编程。

4.1 主程序流程图

软件分为两部分,主程序和中断服务程序,如图4-1、图4-2、图4-3所示。主程序完成初始化工作、各路超声波发射和接收顺序的控制。

定时中断服务子程序完成单方向超声波的发射,外部中断服务子程序主要完成时间值的读取、距离计算、结果的输出等工作。

主程序首先是对系统环境初始化,设置定时器T0工作模式为16位定时计数器模式。置位总中断允许位EA并给显示端口P0和P1清0。然后调用超声波发生子程序送出一个超声波脉冲,为了避免超声波从发射器直接传送到接收器引起的直射波触发,需要延时约0.1ms(这也就是超声波测距仪会有一个最小可测距离的原因)后,才打开外中断1接收返回的超声波信号.

图4-1主程序流程

由于采用的是12MHz的晶振,计数器每计一个数就是1μs,当主程序检测到接收成功的标志位后,将计数器T0中的数(即超声波来回所用的时间)按式(4-1)计算,即可得被测物体与测距仪之间的距离,设计时取20℃时的声速为344m/s则有:

d=(c

t)/2=172T0/10000cm                     (4-1)

其中,T0为计数器T0的计算值。

测出距离后结果将传给LCD数码显示约5s,同时测量距离送语音模块播报。然后再发超声波脉冲重复测量过程。为了有利于程序结构化和容易计算出距离,主程序采用C语言编写。

4.2 超声波发生子程序和超声波接收中断程序

超声波发生子程序的作用是通过P1.1端口发送2个左右超声波脉冲信号(频率约40kHz的方波),脉冲宽度为20μs左右,同时把计数器T0打开进行计时。超声波发生子程序较简单,但要求程序运行准确。

图4-2 定时中断服务子程序

图4-3 外部中断服务子程序

超声波测距仪主程序利用外中断1检测返回超声波信号,一旦接收到返回超声波信号(即INT1引脚出现低电平),立即进入中断程序。进入中断后就立即关闭计时器T0停止计时,并将测距成功标志字赋值1。如果当计时器溢出时还未检测到超声波返回信号,蚨ㄊ逼鱐0溢出中断将外中断1关闭,并将测距成功标志字赋值2以表示此次测距不成功。

1




 

1



 

第五章超声波测距接收

5.1 HC-SR04模块

HC-SR04超声波测距模块可提供2cm-400cm的非接触式距离感测功能,其结构简单,使用单片机控制电路简单容易,而且价格便宜。该模块包括超声波发射、接收与控制电路。实物如图5-1。

图5-1  HC-SR04模块实物图

基本工作原理

①采用IO口TRIG触发测距,给至少10us的高电平信号;

②模块自动发送8个40khz的方波,自动检测是否有信号返回;

③有信号返回,通过IO口ECHO输出一个高电平,高电平持续时间就是超

声波从发射到返回的时间。

电气参数

HC-SR04模块参数如下表5-1所示。


表5-1模块参数
电气参数
HC-SR04超声波模块
工作电压
DC 5V
工作电流
15mA
工作频率
40khz
最远射程
4m
最近射程
2cm
测量角度
15°
输入触发信号
10us的TTL脉冲
输入回响信号
输出TTL电平信号,与射程成比例
规格尺寸
45*20*15cm

超声波时序图
超声波时序图如图5-2所示

图5-2超声波时序图

以上时序图表明只需要提供一个10us以上脉冲信号,该模块内部将发出8个40khz周期电平并检测回波。一旦检测到有回波信号则输出回响信号。回响信号的脉冲宽度与测量的距离成正比。由此通过发射信号到收到的回响信号时间间隔可以计算得到距离:

距离=高电平时间*声速(340m/s)/2。

为防止发射信号对回响信号的影响,测量周期一般要60ms以上。

模块主要由Em78p153单片机、MAX232、TL074、超声波传感器:T40-16、R40-16组成。

Em78p153单片机

①概况描述

Em78p153是采用高速CMOS工艺制造的8位单片机。其内部有512*13位一次性ROM(OTPROM)。因此,用户可以方便改进完善程序。程序代码可用EMC编程器写入芯片。有13位选项位可满足用户要求,其中的保护位可用来防止程序被读出。

②功能特点

工作电压范围:2.0V~6.0V;

工作温度范围:0℃~70℃;

工作频率范围:DC~8MHz;

512×13位片内ROM;32×8位片内寄存器(SDRAM);

片内有4MHz校准RC振荡器;

2个双向I/O端口;

8位实时定时/计数器(TCC),信号源、触发沿可编程选择,溢出产生中断;

掉电模式(SLEEP模式);

3个中断源:TCC溢出中断、输入引脚状态变化中断、外部中断;

EM78P153为14脚封装;封装形式:SOP、SSOP和DIP。

③引脚分配

Em78p153单片机引脚分配如图5-3。

图5-3 Em78p153引脚图

MAX232

MAX232芯片是美信公司专门为电脑的RS-232标准串口设计的单电源电平转换芯片,使用+5v单电源供电。MAX232多用于串口通信,起到电平转换的作用,而本设计只用到其电平转换,将40kHz的方波由5V转换成20V,提高发射功率。超声波发射头采用共振频率为40kHz的TCT40-16探头,接收头采用RCT40-16。

①MAX232引脚图

芯片引脚如图5-4。

图5-4 MAX232引脚图

②引脚介绍
第一部分是电荷泵电路。由1、2、3、4、5、6脚和4只电容构成。功能是产生+12v和-12v两个电源,提供给RS-232串口电平的需要。
第二部分是数据转换通道。由7、8、9、10、11、12、13、14脚构成两个数据通道。其中13脚(R1IN)、12脚(R1OUT)、11脚(T1IN)、14脚(T1OUT)为第一数据通道;8脚(R2IN)、9脚(R2OUT)、10脚(T2IN)、7脚(T2OUT)为第二数据通道。
第三部分是供电。15脚GND、16脚VCC(+5v)。
TL074
常用的低噪声JFET输入运算放大器,引脚如图5-5。

图5-5 TL074引脚图

1、2、3脚是通道1的输出端、反相输入端、同相输入端,5、6、7脚是通道2的同相输入端、反相输入端、输出端,8、9、10脚是通道3的输出端、反相输入端、同相输入端,12、13、14脚是通道4的同相输入端、反相输入端、输出端,4脚是正电源,11脚是负电源。TL074内部组件数量如下表5-2所示

表5-2 TL074组件
电阻
44
晶体管
56
JFET
6
二极管
4
电容
4
epi-FET
4

T40-16与R40-16

为了研究和利用超声波,人们已经设计和制成了许多超声波发生器。总体上讲,超声波发生器可以分为两大类:

电气方式产生超声波, 主要包括压电型、磁致伸缩型和电动型等;

机械方式产生超声波,主要包括加尔统笛、液哨和气流旋笛等。

    它们所产生的超声波的频率、功率和声波特性各不相同,因而用途也各不相同。目前较为常用的是压电式超声波发生器。

压电式超声波发生器实际上是利用压电晶体的谐振来工作的。其内部有两个压电晶片和一个共振板。当它的两极外加脉冲信号,其频率等于压电晶片的固有振荡频率时,压电晶片发生共振,带动共振板振动,便产生超声波。反之,如果两电极间未外加电压,当共振板接收到超声波时,将压迫压电晶片作振动,将机械能转换为电信号,这时它就成为超声波接收器了。模块使用T40-16T/R超声波换能器即为压电型。

①器件说明

名 称:压电陶瓷超声波传感器;

型 号:T40-16T/R;

类 别:通用型;

中心频率:40KHZ;

外 径:16mm;

使用方式:T为发射头,R为接收头,TR为收发兼用;

适用范围:家用电器及其它电子设备的超声波遥控装置;超声波测距及汽车倒车防撞装置;液面探测;超声波接近开关及其它应用的超声波发射与接收。

②器件性能

1.标称频率(KHz):40KHz;

2.发射电压at10V(0dB=0.02mPa):≥110dB;

3.接收灵敏度at40KHz(0dB=V/ubar):≥-70dB;

4.静电容量at1KHz,<1V(PF):2000±30%;

5.探测距离(m):0.02-10。

传感器实物如图5-5 所示。

图5-6 传感器实物图

HC-SR04模块集成了发射和接受电路,硬件上不必再自行设计繁复的发射及接收电路,软件上也无需再通过定时器产生40Khz的方波引起压电陶瓷共振从而产生超声波。使用时,只要在控制端‘Trig’发一个大于10us宽度的高电平,就可以在接收端‘Echo’等待高电平输出。单片机一旦检测到有输出就打开定时器开始计时。当此口变为低电平时就停止计时并读出定时器的值,此值就为此次测距的时间,再根据传播速度方可算出障碍物的距离。

5.2 T40、R40超声波传感器简介

5-7 元件内部结构
5-8 元件外部结构

5.2.1 超声波传感器的基本介绍

超声波测距换能器是利用超声波的特性研制而成的换能器。超声波是一种振动频率高于声波的机械波,由换能晶片在电压的激励下发生振动产生的,它具有频率高、波长短、绕射现象小,特别是方向性好、能够成为射线而定向传播等特点。超声波对液体、固体的穿透本领很大,尤其是在阳光不透明的固体中,它可穿透几十米的深度。超声波碰到杂质或分界面会产生显著反射形成反射成回波,碰到活动物体能产生多普勒效应。因此超声波检测广泛应用在工业、国防、生物医学等方面。

以超声波作为检测手段,必须产生超声波和接收超声波。完成这种功能的装置就是超声波换能器,或者探头。

超声波换能器主要由压电晶片组成,既可以发射超声波,也可以接收超声波。小功率超声探头多作探测作用。它有许多不同的结构,可分直探头(纵波)、斜探头(横波)、表面波探头(表面波)、兰姆波探头(兰姆波)、双探头(一个探头反射、一个探头接收)等。

5.2.2 超声波传感器的主要应用

超声波传感技术应用在生产实践的不同方面,而医学应用是其最主要的应用之一,下面以医学为例子说明超声波传感技术的应用。超声波在医学上的应用主要是诊断疾病,它已经成为了临床医学中不可缺少的诊断方法。超声波诊断的优点是:对受检者无痛苦、无损害、方法简便、显像清晰、诊断的准确率高等。因而推广容易,受到医务工作者和患者的欢迎。超声波诊断可以基于不同的医学原理,我们来看看其中有代表性的一种所谓的A型方法。这个方法是利用超声波的反射。当超声波在人体组织中传播遇到两层声阻抗不同的介质界面是,在该界面就产生反射回声。每遇到一个反射面时,回声在示波器的屏幕上显示出来,而两个界面的阻抗差值也决定了回声的振幅的高低。

在工业方面,超声波的典型应用是对金属的无损探伤和超声波测厚两种。过去,许多技术因为无法探测到物体组织内部而受到阻碍,超声波传感技术的出现改变了这种状况。当然更多的超声波传感器是固定地安装在不同的装置上,“悄无声息”地探测人们所需要的信号。在未来的应用中,超声波将与信息技术、新材料技术结合起来,将出现更多的智能化、高灵敏度的超声波传感器。

超声波距离传感器技术应用

超声波对液体、固体的穿透本领很大,尤其是在阳光不透明的固体中,它可穿透几十米的深度。

超声波碰到杂质或分界面会产生显著反射形成反射成回波,碰到活动物体能产生多普勒效应。因此超声波检测广泛应用在工业、国防、生物医学等方面。超声波距离传感器可以广泛应用在物位(液位)监测,机器人防撞,各种超声波接近开关,以及防盗报警等相关领域,工作可靠,安装方便, 防水型,发射夹角较小,灵敏度高,方便与工业显示仪表连接,也提供发射夹角较大的探头。

5.2.3 超声波传感器的工作原理

超声波是一种在弹性介质中的机械振荡,有两种形式:横向振荡(横波)及纵向振荡(纵波)。在工业中应用主要采用纵向振荡。超声波可以在气体、液体及固体中传播,其传播速度不同。另外,它也有折射和反射现象,并且在传播过程中有衰减。在空气中传播超声波,其频率较低,一般为几十KHZ,而在固体、液体中则频率可用得较高。在空气中衰减较快,而在液体及固体中传播,衰减较小,传播较远。利用超声波的特性,可做成各种超声传感器,配上不同的电路,制成各种超声测量仪器及装置,并在通迅,医疗家电等各方面得到广泛应用。

超声波传感器主要材料有压电晶体(电致伸缩)及镍铁铝合金(磁致伸缩)两类。电致伸缩的材料有锆钛酸铅(PZT)等。压电晶体组成的超声波传感器是一种可逆传感器,它可以将电能转变成机械振荡而产生超声波,同时它接收到超声波时,也能转变成电能,所以它可以分成发送器或接收器。有的超声波传感器既作发送,也能作接收。这里仅介绍小型超声波传感器,发送与接收略有差别,它适用于在空气中传播,工作频率一般为23-25KHZ及40-45KHZ。这类传感器适用于测距、遥控、防盗等用途。该种有T/R-40-60,T/R-40-12等(其中T表示发送,R表示接收,40表示频率为40KHZ,16及12表示其外径尺寸,以毫米计)。另有一种密封式超声波传感器(MA40EI型)。它的特点是具有防水作用(但不能放入水中),可以作料位及接近开关用,它的性能较好。超声波应用有三种基本类型,透射型用于遥控器,防盗报警器、自动门、接近开关等;分离式反射型用于测距、液位或料位;反射型用于材料探伤、测厚等。

由发送传感器(或称波发送器)、接收传感器(或称波接收器)、控制部分与电源部分组成。发送器传感器由发送器与使用直径为15mm左右的陶瓷振子换能器组成,换能器作用是将陶瓷振子的电振动能量转换成超能量并向空中辐射;而接收传感器由陶瓷振子换能器与放大电路组成,换能器接收波产生机械振动,将其变换成电能量,作为传感器接收器的输出,从而对发送的超进行检测.而实际使用中,用发送传感器的陶瓷振子的也可以用做接收器传感器社的陶瓷振子。控制部分主要对发送器发出的脉冲链频率、占空比及稀疏调制和计数及探测距离等进行控制

5.3 超声波发射电路

HC-SR04模块内部超声波发射电路如图5-6所示,主要由Em78p153单片机、MAX232及超声波发射换能器T40组成。

图5-9 超声波发射电路

5.4 超声波接收电路
HC-SR04模块内部超声波接收电路如图5-3所示,主要由TL074运算放大器及超声波接换能器R40组成。

图5-10 超声波接收电路


 

5.5 超声波接收过程

    单片机初始化,HC-SR04内部ECHO接口与单片机P1.1的引脚相连,发射接口TRIG与单片机的P1.2引脚相接。

单片机开启中断,单片机P1.1给“Trig”接口一个约为20us的高电平,经过HC-SR04模块内EM78P153发送8个连续的40KHz脉冲的信号,经过MAX232电平转换,提高发射功率。换能器将电脉冲信号转换为超声波发射。

    当单片机的给一个20us的触发信号时,TRIG由低电平转换为高电平,TRIG=1,

单片机开时计时,开启中断,并记录时间为T1,接收换能器等待接收回波,ECHO持续为高电平的时间为发射时间。换能器接收回波将超声波转换为电信号,送至单片机,记录时间为T2。超声波发射的时间为:T2-T1,

计算发射距离为:

L = (T2-T1)xC/2

如果等待回波时间超过65ms时,则无法接收到回波,单片机初始化,重新发射接收下一次回波。

5.6 接收数据处理

单片机初始化函数

5-11程序流程图

接收过程:上电后先进行初始化,主要是对各变量即定时器0进行初始化,然后单片机给‘Trig’端一个约为20us的高电平,此后在‘Echo’端等待一个高电平,一旦检测到高电平,则立即打开定时器,开始计时。此后只要定时器0中的值不超过约为65ms(65.5536ms)的计时上限,则认为仍处在有效测量范围内,并未进入盲区,则在‘Echo’等待低电平的产生,一旦检测到低电平,立即读出此时的TH0和TL0,并关闭定时器0。则超声波从发射到返回总共所用时间为:time=TH0*256+TL0(us),再根据超声波常温下(27℃)在空气中的传播速度,(约为344m/s)计算出障碍物的距离,在数码管上进行动态的实时显示即可。

接收数据处理子程序如下:

              c_send = 1;                                       //10us的高电平触发
              delay();
              c_send = 0;            
              TH0 = 0;                                      //给定时器0清零
              TL0 = 0;
              TR0 = 0;                                                          //关定时器0定时
              flag_hc_value = 0;
              while(!c_recive);                              //当c_recive为零时等待
              TR0=1;
              while(c_recive)                                  //当c_recive为1计数并等待
              {
                            flag_time0 = TH0 * 256 + TL0;
                            if((flag_hc_value > 1) || (flag_time0 > 65000))     //当超声波超过测量范围时,显示3个888
                            {
                                          TR0 = 0;
                                          flag_csb_juli = 2;
                                          distance = 888;
                                          flag_hc_value = 0;
                                          break ;                           
                            }
                            else
                            {
                                          flag_csb_juli = 1;            
                            }
              }
              if(flag_csb_juli == 1)
              {            
                            TR0=0;                                                                                                 //关定时器0定时
                            distance = TH0;                                                             //读出定时器0的时间
                            distance = distance * 256 + TL0;
                            distance +=( flag_hc_value * 65536);//算出超声波测距的时间              得到单位是ms
                            distance *= 0.017;               // 0.017 = 340M / 2 = 170M = 0.017M 算出来是米
                            if(distance > 350)                                                        //距离 = 速度 * 时间
                            {            
                                          distance = 888;                                                        //如果大于3.8m就超出超声波的量程
                            }
              }  
第六章总结

本次设计介绍了一种基于单片机的超声波测距系统的设计,给出了相应的软件和硬件的设计方案。

超声波测距的原理与雷达测距原理相似,通过超声波发射装置发出超声波,根据接收器接到超声波时的时间差就可以知道距离,也就是说超声波发射器向某一方向发射超声波,在发射时刻的同时单片机开始计时,超声波在空气中传播,途中碰到障碍物就立即返回来,超声波接收器收到反射波单片机就立即停止计时,再利用对应的计算公式就可以求出物体间的间距,这是根据反射原理利用了超声波指向性强,在介质中传播距离较远的特性。

超声波测距仪硬件电路的设计主要包括单片机的基本电路、超声波发射接收模块控制电路、显示电路、语音模块,温度补偿五部分部分组成。单片机采用了STC89C52,晶振为12MHz,单片机P1.3端口输出10us的触发信号,由定时器T0计得时间间隔,显示电路采用1602,语音芯片WTD588D。

本次设计的超声波测距系统满足倒车测距等所需的测量精度,而且反映速度快、控制简单、成本低廉等,测距范围为2cm到350cm。但由于经验不足还有些地方有待完善。在要求精度较高的地方时,由于超声波在空气中的传播速度受温度影响有点大,则需考虑到不同温度时超声波的传播速度变换。

总体来说,经过本次设计让我学到了很多,从中受益匪浅。了解了超声波测距的原理,并对单片机的开发和电路设计有了更进一步的了解。



 

附录1原理图

单片机源程序如下:
  1. #include <reg52.h>                       //调用单片机头文件
  2. #define uchar unsigned char  //无符号字符型 宏定义              变量范围0~255
  3. #define uint  unsigned int              //无符号整型 宏定义              变量范围0~65535
  4. #include <intrins.h>
  5. //数码管段选定义      0     1    2    3    4    5              6              7                8                 9            
  6. uchar code smg_du[]={0x25,0xee,0x37,0xa2,0xe2,0xa1,0x21,0xea,0x20,0xa0,
  7.                                                                         0x60,0x25,0x39,0x26,0x31,0x71,0xff};              //断码
  8. //数码管位选定义
  9. uchar code smg_we[]={0xe0,0xb0,0xd0,0x70};
  10. uchar dis_smg[4]   ={0};
  11. sbit smg_we1 = P3^4;                  //数码管位选定义
  12. sbit smg_we2 = P3^5;
  13. sbit smg_we3 = P3^6;
  14. sbit smg_we4 = P3^7;
  15. sbit c_send   = P3^2;                            //超声波发射
  16. sbit c_recive = P3^3;                            //超声波接收
  17. sbit beep = P3^1;   //蜂鸣器IO口定义
  18. uchar smg_i = 3;    //显示数码管的个位数
  19. bit flag_300ms ;
  20. long distance;                      //距离
  21. uint set_d;                          //距离
  22. uchar flag_csb_juli;    //超声波超出量程
  23. uint  flag_time0;       //用来保存定时器0的时候的
  24. uchar menu_1;           //菜单设计的变量
  25. /***********************语音模块控制IO口的定义************************/
  26. sbit  VRST = P2^3;
  27. sbit  VBUSY= P2^7;            
  28. sbit  VSDA = P2^6;
  29. sbit  VCS  = P2^5;
  30. sbit  VSCL = P2^4;
  31. uchar yujing[3];
  32. /***************************
  33.                  语音地址的安排
  34. 0 - 9 :  对应数字0到9
  35. 0b    : 点
  36. 0c    : 米
  37. 0d    : 已超出量程
  38.                                                                                                                               
  39. **************************/
  40. /***********************1ms延时函数*****************************/
  41. void delay_1ms(uint q)
  42. {
  43.               uint i,j;
  44.               for(i=0;i<q;i++)
  45.                             for(j=0;j<120;j++);
  46. }
  47. /********************独立按键程序*****************/
  48. uchar key_can;              //按键值
  49. void key()              //独立按键程序
  50. {
  51.               static uchar key_new;
  52.               key_can = 20;                   //按键值还原
  53.               P2 |= 0x07;
  54.               if((P2 & 0x07) != 0x06)                            //按键按下
  55.               {
  56.                             delay_1ms(1);                                 //按键消抖动
  57.                             if(((P2 & 0x07) != 0x07) && (key_new == 1))
  58.                             {                                                                                    //确认是按键按下
  59.                                           key_new = 0;
  60.                                           switch(P2 & 0x07)
  61.                                           {
  62.                                                         case 0x05: key_can = 1; break;                 //得到k2键值
  63.                                                         case 0x04: key_can = 2; break;                 //得到k3键值
  64.                                                         case 0x02: key_can = 3; break;                 //得到k4键值
  65.                                           }
  66.                             }                                         
  67.               }
  68.               else
  69.                             key_new = 1;            
  70. }
  71. /****************按键处理显示函数***************/
  72. void key_with()
  73. {
  74.               if(key_can == 1)                            //设置键
  75.               {
  76.                             menu_1 ++;
  77.                             if(menu_1 >= 2)
  78.                             {
  79.                                           menu_1 = 0;
  80.                                           smg_i = 3;                            //只显示3位数码管
  81.                             }
  82.                             if(menu_1 == 1)
  83.                             {
  84.                                           smg_i = 4;                  //只显示4位数码管
  85.                             }
  86.               }
  87.               if(menu_1 == 1)                                          //设置报警
  88.               {
  89.                             if(key_can == 2)
  90.                             {
  91.                                           set_d ++ ;                            //加1
  92.                                           if(set_d > 400)
  93.                                                         set_d = 400;
  94.                             }
  95.                             if(key_can == 3)
  96.                             {
  97.                                           set_d -- ;                            //减1
  98.                                           if(set_d <= 1)
  99.                                                         set_d = 1;
  100.                             }
  101.                             dis_smg[0] = smg_du[set_d % 10];                         //取小数显示
  102.                             dis_smg[1] = smg_du[set_d / 10 % 10] ;         //取个位显示
  103.                             dis_smg[2] = smg_du[set_d / 100 % 10] & 0xdf ; //取十位显示
  104.                             dis_smg[3] = smg_du[10];                      //a
  105.               }            
  106. }
  107. /***********************语音子程序************************/
  108. void Send_threelines(unsigned char addr)
  109. {
  110.    unsigned char i;
  111.               VRST=0;
  112.               delay_1ms(5);
  113.               VRST=1;
  114.               delay_1ms(10); /* 复位拉高10ms*/
  115.               VCS=0;
  116.               delay_1ms(5);  /* 片选拉低5ms */
  117.     for(i=0;i<8;i++)
  118.               {
  119.                             VSCL=1;
  120.                             if(addr&0x01 == 0x01)
  121.                             {
  122.                                           VSDA=1;
  123.                             }
  124.                             else
  125.                                           VSDA=0;
  126.                             addr<<=1;
  127.                             VSCL=0;
  128.               }
  129.               VCS=1;
  130.               while(VBUSY == 0);                //忙等待
  131. }
  132. /***********************数码位选函数*****************************/
  133. void smg_we_switch(uchar i)
  134. {
  135.               switch(i)
  136.               {
  137.                             case 0: smg_we1 = 0;  smg_we2 = 1; smg_we3 = 1;  smg_we4 = 1; break;
  138.                             case 1: smg_we1 = 1;  smg_we2 = 0; smg_we3 = 1;  smg_we4 = 1; break;
  139.                             case 2: smg_we1 = 1;  smg_we2 = 1; smg_we3 = 0;  smg_we4 = 1; break;
  140.                             case 3: smg_we1 = 1;  smg_we2 = 1; smg_we3 = 1;  smg_we4 = 0; break;
  141.               }            
  142. }
  143. /****************报警函数***************/
  144. void clock_h_l()
  145. {
  146.               static uchar value;
  147.               if(distance <= set_d)
  148.               {
  149.                             value ++;  //消除实际距离在设定距离左右变化时的干扰
  150.                             if(value >= 2)
  151.                             {
  152.                                           beep = ~beep;                 //蜂鸣器报警            
  153.                             }
  154.               }
  155.               else
  156.               {
  157.                             value = 0;
  158.                             beep = 1;                            //取消报警
  159.               }            
  160. }
  161. /***********************数码显示函数*****************************/
  162. void display()
  163. {
  164.               static uchar i;  
  165.               i++;
  166.               if(i >= smg_i)
  167.                             i = 0;            
  168.               smg_we_switch(i);                            //位选
  169.               P1 = dis_smg[i];                            //段选                     
  170. }
  171. /******************小延时函数*****************/
  172. void delay()
  173. {
  174.               _nop_();                                        //执行一条_nop_()指令就是1us
  175.               _nop_();
  176.               _nop_();
  177.               _nop_();
  178.               _nop_();
  179.               _nop_();
  180.               _nop_();
  181.               _nop_();
  182.               _nop_();
  183.               _nop_();
  184. }
  185. /*********************超声波测距程序*****************************/
  186. void send_wave()
  187. {
  188.               c_send = 1;                                       //10us的高电平触发
  189.               delay();
  190.               c_send = 0;            
  191.               TH0 = 0;                                      //给定时器0清零
  192.               TL0 = 0;
  193.               TR0 = 0;                                                          //关定时器0定时
  194.               while(!c_recive);                              //当c_recive为零时等待
  195.               TR0=1;
  196.               while(c_recive)                                  //当c_recive为1计数并等待
  197.               {
  198.                             flag_time0 = TH0 * 256 + TL0;
  199.                             if((flag_time0 > 40000))      //当超声波超过测量范围时,显示3个888
  200.                             {
  201.                                           TR0 = 0;
  202.                                           flag_csb_juli = 2;
  203.                                           distance = 888;
  204.                                           break ;                           
  205.                             }
  206.                             else
  207.                             {
  208.                                           flag_csb_juli = 1;            
  209.                             }
  210.               }
  211.               if(flag_csb_juli == 1)
  212.               {            
  213.                             TR0=0;                                                                                                  //关定时器0定时
  214.                             distance =flag_time0;                                          //读出定时器0的时间
  215.                             distance *= 0.017;               // 0.017 = 340M / 2 = 170M = 0.017M 算出来是米
  216.                             if((distance > 500))                                                        //距离 = 速度 * 时间
  217.                             {            
  218.                                           distance = 888;                                                        //如果大于3.8m就超出超声波的量程
  219.                             }
  220.               }
  221. }
  222. /***********************处理距离函数****************************/
  223. void smg_display()
  224. {
  225.               dis_smg[0] = smg_du[distance % 10];                            //距离取出来放在缓冲区了
  226.               dis_smg[1] = smg_du[distance / 10 % 10];
  227.               dis_smg[2] = smg_du[distance / 100 % 10] & 0xdf;
  228.               yujing[0] = distance % 10;                                            //距离放到语音的变量里
  229.               yujing[1] = distance / 10 % 10;            
  230.               yujing[2] = distance / 100 % 10;            
  231. }
  232. /*********************定时器0、定时器1初始化******************/
  233. void time_init()               
  234. {
  235.               EA  = 1;                              //开总中断
  236.               TMOD = 0X11;                //定时器0、定时器1工作方式1
  237.               ET0 = 0;                              //关定时器0中断
  238.               TR0 = 1;                              //允许定时器0定时
  239.               ET1 = 1;                              //开定时器1中断
  240.               TR1 = 1;                              //允许定时器1定时            
  241. }
  242. /***************主函数*****************/
  243. void main()
  244. {
  245.               static uchar value = 5;
  246.               send_wave();              //测距离函数
  247.               smg_display();              //处理距离显示函数
  248.               time_init();              //定时器初始化程序
  249.               while(1)
  250.               {                             
  251.                             key();                                                                      //按键函数
  252.                             if(key_can < 10)
  253.                             {
  254.                                           key_with();                                          //按键处理函数
  255.                             }
  256.                             if(flag_300ms == 1)
  257.                             {                           
  258.                                           flag_300ms = 0;
  259.                                           send_wave();              //测距离函数
  260.                                           if(menu_1 == 0)
  261.                                           {            
  262.                                                         smg_display();              //处理距离显示函数
  263.                                                         value ++;
  264.                                                         if(value > 10)                            //3秒钟自动播放一次
  265.                                                         {
  266.                                                                       value = 0;
  267.                                                                       if(distance == 888)
  268.                                                                       {
  269.                                                                                     Send_threelines(0x0d);                //可安全倒车
  270.                                                                       }
  271.                                                                       else
  272.                                                                       {
  273.                                                                                     Send_threelines(yujing[2]);                 //语音播放
  274.                                                                                     Send_threelines(0x0b);
  275.                                                                                     Send_threelines(yujing[1]);
  276.                                                                                     Send_threelines(yujing[0]);
  277.                                                                                     Send_threelines(0x0c);
  278.                                                                       }
  279.                                                         }
  280.                                           }            
  281.                             }
  282.               }
  283. }
  284. /*********************定时器1中断服务程序************************/
  285. void time1_int() interrupt 3
  286. {            
  287.               static uchar value;                                          //定时2ms中断一次
  288.               TH1 = 0xf8;
  289.               TL1 = 0x30;     //2ms
  290.               display();                            //数码管显示函数
  291.               value++;
  292.               if(value >= 150)
  293.               {
  294.                             value = 0;
  295.                             flag_300ms = 1;
  296.                             clock_h_l();    //报警函数
  297.               }
  298. }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/20557.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【通信专题】I2C通信硬件概述

通信协议在组织设备之间通信时扮演着重要角色。它基于系统要求而以不同方式进行设计。此类协议具有明确的、为实现成功通信而协商一致的规则。 I2C历史 I2C,即Inter-Integrated Circuit,是一种常用的串行通信协议。I2C总线创建于1982年,由飞利浦公司设计,旨在利用简单、稳…

【Python打包成exe】

Python打包成exe 前言一、理论知识打底二、实操开始----pyinstaller【Base环境下】【这是一个失败案例】规规矩矩 总结 前言 先放点参考 这个字多&#xff0c;写得很详细⇨用 Pyinstaller 模块将 Python 程序打包成 exe 文件&#xff08;全网最全面最详细&#xff0c;万字详述…

Neural Filters:风景混合器

Ps菜单&#xff1a;滤镜/Neural Filters/创意/风景混合器 Neural Filters/CREATIVE/Landscape Mixer 风景混合器 Landscape Mixer滤镜通过与另一个图像混合或改变诸如时间和季节等属性&#xff0c;神奇地改变景观。 “风景混合器”滤镜利用人工智能和机器学习技术&#xff0c;首…

【LeetCode算法】第111题:二叉树的最小深度

目录 一、题目描述 二、初次解答 三、官方解法 四、总结 一、题目描述 二、初次解答 1. 思路&#xff1a;二叉树的先序遍历。求出左子树的最小高度&#xff0c;求出右子树的最小高度&#xff0c;最终返回左子树和右子树的最小高度1。关键&#xff1a;若左子树的高度为0&…

【Linux】命名管道

一、命名管道的原理 在前面的博客中&#xff0c;我们学习了匿名管道&#xff0c;了解到了两个具有血缘关系的进程之间是如何进行通信的&#xff1f;那么在没有血缘关系&#xff08;毫不相关&#xff09;的进程之间是如何进行通信的&#xff1f; 大致思路是一样的&#xff0c;我…

JavaScript倍速播放视频

F12打开开发者工具&#xff0c;打开控制台&#xff0c;输入这行代码&#xff0c;视频即可加速播放&#xff0c; 可以调整倍速&#xff08;2&#xff0c;4&#xff0c;8&#xff0c;16&#xff09; document. getElementsByTagName("video")[0]. playbackRate16

实现JDBC编程

JDBC编程 JDBC —> java database connectivity 即java数据连接, 是执行sql语句的javaAPI(application programming interface),所谓的数据库是一类软件,就会提供对应的API,数据库有很多种,不同的数据库提供对应的API是不一样的,而这个API有java.sql.* 和 javax.sql.*包中的…

【数据挖掘】3σ原则识别数据中的异常值(附代码)

写在前面&#xff1a; 首先感谢兄弟们的订阅&#xff0c;让我有创作的动力&#xff0c;在创作过程我会尽最大能力&#xff0c;保证作品的质量&#xff0c;如果有问题&#xff0c;可以私信我&#xff0c;让我们携手共进&#xff0c;共创辉煌。 路虽远&#xff0c;行则将至&#…

机关——用钥匙开对应的门

代码展示 玩家背包代码&#xff08;挂载到玩家身上&#xff09; using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary> /// 玩家背包脚本&#xff0c;用来记录玩家道具 /// </summary> public class MyBag : MonoBeha…

pytorch学习笔记4

开启tensorboard 在terminal中输入tensorboard --logdir文件名 文件名中不能含有空格 tensorboard --logdirlogs --port6007#将端口调整为6007tensorboard --logdirlogs --port 0 自动分配一个端口&#xff0c;成功访问打开的时候如果发现没数据可以把logs换成文件夹的绝对路径…

【儿童节特辑】用AI创造音乐,变身小小音乐家!

在儿童节这个充满欢笑的日子里&#xff0c;让我们一起探索如何用AI技术为孩子们准备一份特别的礼物——一张由AI生成的音乐专辑。&#x1f3b5;✨ &#x1f3bc; 文字变旋律&#xff1a;开启音乐创作之旅 想象一下&#xff0c;只需一段文字&#xff0c;就能编织出一曲悠扬悦耳…

Python自动实时查询预约网站的剩余名额并在有余额时发邮件提示

本文介绍基于Python语言&#xff0c;自动、定时监测某体检预约网站中指定日期的体检余额&#xff0c;并在有体检余额时自动给自己发送邮件提醒的方法。 来到春招末期&#xff0c;很多单位进入了体检流程。其中&#xff0c;银行&#xff08;尤其是四大行&#xff09;喜欢“海检”…

Day44 动态规划part04

背包问题 01背包问题&#xff1a;每件物品只能用一次完全背包问题&#xff1a;每件物品可以使用无数次 01背包问题 暴力解法&#xff1a;每一件物品其实只有两个状态&#xff0c;取或者不取&#xff0c;所以可以使用回溯法搜索出所有的情况&#xff0c;那么时间复杂度就是 o…

Transformer从0到1的学习【还有2-10,别想太多】

1.高纬度介绍Transformer 1.分为编码Encoders和解码器Decoders&#xff1a;“我爱你”作为编码器Encoders的输入进行编码得到序列码后&#xff0c;作为解码器的输入得到输出即为&#xff0c;“I Love you”。 2.编码器和译码器的具体拆分&#xff1a; 左边的编码器Encoders的…

【常见的六大排序算法】插入排序、希尔排序、选择排序、冒泡排序、堆排序、快速排序

个人主页 创作不易&#xff0c;感谢大家的关注&#xff01; 文章目录 前言 &#x1f3a1;一、插入排序&#x1f332;二、希尔排序&#x1f389;三、选择排序&#x1f380;四、冒泡排序&#x1f698;五、堆排序&#x1f6f5;六、快速排序1. Hoare版本2. 挖坑法3. 前后指针法4. 非…

大佬推荐的好用网盘工具

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 前段时间有大佬推荐了一款网盘工具seafile&#xff0c;自己搭建起来试用了一下&#xff0c;发现还挺好用的&#xff0c;这款工具…

【C++】C++11新特性:新的类功能、可变参数模板、STL容器中的empalce相关接口函数、lambda表达式、包装器(function、bind)

目录 一、新的类功能 1.1 移动构造函数和移动赋值运算符重载 1.2 强制生成默认函数的关键字default 1.3 禁止生成默认函数的关键字delete 1.4 其它的类功能 二、可变参数模板 三、STL容器中的empalce相关接口函数 四、lambda表达式 4.1 lambda的引入 4.2 lambda表达式…

openVPN+SmartDNS=openDNS or smartVPN?

正文共&#xff1a;777 字 11 图&#xff0c;预估阅读时间&#xff1a;1 分钟 我们现在已经熟练的掌握了openVPN的部署方式和配置方法&#xff08;带认证的openVPN连接/断开操作指南&#xff09;&#xff0c;还掌握了在CentOS系统部署SmartDNS的方法&#xff08;基于CentOS部署…

【网络安全】Web安全基础 - 第二节:前置基础知识- HTTP协议,握手协议,Cookie及Session

本章节主要介绍一些基础知识 d(^_^o) HTTP协议 什么是HTTP 超文本传输协议&#xff08;HyperText Transfer Protocol&#xff09;是一种用于分布式、协作式和超媒体信息系统的应用层协议。 HTTP是一个基于请求与响应&#xff0c;无状态的&#xff0c;应用层协议&#xff0c;…

100.网络游戏逆向分析与漏洞攻防-ui界面的设计-聊天功能的界面与设计

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果 现在的代码都是依据数据包来写的&#xff0c;如果看不懂代码&#xff0c;就说明没看懂数据包…