这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 资深工程师单片机实战项目精讲(连载),由易到难连续分享

共31条 2/4 1 2 3 4 跳转至
助工
2015-01-11 21:51:43     打赏
11楼

9、吴鉴鹰单片机项目详细解析系列(连载)如何提高单片机的抗干扰能力(一)

 

 

(一)、抗干扰方法综述

(二)、钟信号也会产生干扰

(三)、设备与设备之间如何抗干扰

(四)、引脚抗干扰的方法

(五)、上下电干扰

 

 

(一)、抗干扰方法综述:

    在工业控制 智能仪表都采用了单片机,单片机干扰措施提到重要议事日程上来单片机抗干扰措施
不解决,其它工作也是白费劲要解决单片机抗干扰措施,必须先找出干扰源,然后采用单片机软硬件技术
来解决
干扰源:主要来自外部电源内部电源,印制板自制干扰,空中周围电磁场干扰,外部干扰通过I/O 口输
入等为叙述方便,我们分硬件软件抗干扰措施来讲:
(一) 硬件抗干扰措施
1. 交流程稳压:使电网电压稳定
2. 交流端用电感电容滤波:去掉高频低频干扰脉冲
3. 变压器双隔离措施:变压器初级输入端串接电容,初次级线圈间屏蔽层与初级间电容中心接点接大
地,次级外屏蔽层接印板地,这是硬件抗干扰的关键手段
4. 次级加低通滤波器:吸收变压器产生的浪涌电压
5. 采用集成式直流稳压电源:因为有过流过压过热等保护
6. I/O 口光电磁电继电器隔离:去掉公共地
7. 通讯线用双绞线:排除平行互感
8. 防雷电用光纤隔离最为有效
9. A/D 转换,用隔离放大器或采用现场转换:减少误差
10. 外壳接大地:解决人身安全及防外界电磁场干扰
11. 加复位电压检测电路:仿止复位不充份,CPU 就工作,尤其有EEPROM 的器件,复位不充份会改变EEPROM 的内容

12. MCU能够适应的电压范围一般在3V-5.5V,但电源的波动对MCU而言却很敏感,比如说MCU可以在3.3V电压下稳定工作,但却不能在电压在3V-5.5V波动的情况下稳定工作。
13.通常是用电源稳压块,做好电源的滤波等工作,提示:一定要在电源旁路并上0.1UF的瓷片电容来滤除高频干扰,因为电解电容对超过几十KHZ的高频干扰不起作用。这就是为什么经常在电源并上电容的原因

14.确实很重要,比如涉及模拟信号处理的,滤波电容一定要加足,宁大勿小,保证电源的纯净,信号不受干扰;电流大的线路,铜线必须得足够粗。

15.一般单片机项目我们都是在电源端口处一个10uf电解电容和一个104瓷介电容,作双重保证

16.通常隔离有:电源隔离,输入输出口隔离,空间隔离

(二)、钟信号也会产生干扰

    在MCU中时钟信号也会产生干扰,时钟信号不仅是受噪声干扰最敏感的部位,同时也是CPU 对外发射辐射干扰和引起内部干扰的噪声源。
    辐射干扰的产生主要与时钟信号的上升和下降时间有关,即门电路的跳变时间Tr 。时钟频率越高,信息传输线上信息变换频率也就越高,致使干扰加剧,故在满足系统功能要求的前提下,要尽量降低时钟频率。这样有助于提高系统的抗干扰性能。为了避免时钟信号被干扰,可以采取以下措施:
(1) 时钟脉冲电路配置时应注意靠近CPU ,引线要短而粗。
(2) 外部时钟源用的芯片VCC与GND之间可接1μF 左右的去耦电容。
(3) 在可能的情况下,用地线包围振荡电路,晶体外壳接地。
(4) 若时钟还做其它芯片的脉冲源,要注意隔离和驱动措施。

(三)、设备与设备之间如何抗干扰

    设备与设备之间这个就比较复杂了,涉及到电磁干扰,这个可能更需要整个系统的抗干扰处理,比如屏蔽线或者隔离器等

    屏蔽线对静电干扰有较强的抑制作用,而双胶线有抵消电磁感应干扰的作用.
开关信号检测线和模拟信号检测线可以使用屏蔽双胶线,来抵御静电和电磁感应干扰;特殊的干扰源也可以用屏蔽线连接,屏蔽了干扰源向外施加干扰。

离这块,隔离目的之一是从电路上把干扰源和易干扰的部分隔离出来,使监控装置与现场仅保持信号联系,但不直接发生电的联系。
    隔离的实质是把引进的干扰通道切断。从而达到隔离现场干扰的目的。一般单片机应用系统既有弱电控制系统又有强电控制系统,通常实行弱电和强电隔离,是保证系统工作稳定、设备与操作人员安全的重要措施。

(四)、引脚抗干扰的方法

看到这个我又想起之前,我们做的一个产品上,蜂鸣器的鸣叫响声达不到标准要求,就特意把蜂鸣器驱动部分做了实验,研究改变参数对蜂鸣器的鸣叫影响。蜂鸣器是感性器件,在通断电时候会产生反向电动势能,这个可能导致损坏元件,而且会干扰其它电路,通过电源直接进入到MCU中。

有些芯片由于内部电路的关系确实这样子的,因为如果引脚输入悬空,在感应电的情况下,输出有可能是高,也有可能是低,还可能在振荡,就有可能对其他引脚造成影响了

    另外说道这个加电容,记得以前做产品时,看到MCU datasheet上有这么一说,某个引脚没有被用到,不能直接NC,要通过一个电容连接到地GND

(五)、上下电干扰

   上下电干扰:但每个MCU 系统在上电时候都要经过这样一个过程,所以要尤其注意。
    MCU 虽然可以在3V 电压下稳定工作,但并不是说它不能在3V 以下的电压下工作,当然在如此低的电压下MCU 是超不稳定状态的。
    在系统加电时候,系统电源电压是从0V 上升到额定电压的,比如当电压到2V 时候,MCU 开始工作了,但这时是超不稳定的工作,极容易跑飞。


助工
2015-01-11 22:11:30     打赏
12楼

10、吴鉴鹰单片机项目详细解析系列(连载)如何提高单片机的抗干扰能力(二)

 

完整文档下载:

吴鉴鹰如何提高单片机抗干扰的能力总结.pdf

 

(六)、隔离法抗干扰

(七)、软件干扰

(八)、印制板工艺抗干扰

(九)、地线的处理

 

(六)、隔离法抗干扰

如果把电源电压变化持续时间定为Δt,那么,根据Δt的大小可以把电源干扰分为四种情况:
1)过压、欠压、停电: 当Δt>1s时产生的干扰,解决办法是使用各种稳压器、电源调节器,对短时停电可用不间断电源(UPS)供电。
2)浪涌、下陷、半周降出:当1s>Δt> 10ms时产生
     的干扰,可使用快速响应的交流电源调压器克服。

(3)尖峰电压:当Δt为μs量级时产生的干扰,
  解决办法是使用具有噪声抑制能力的交流电源
调节器、参数稳压器或超隔离变压器。
  
(4)射频干扰:当Δt为ns量级时产生的干扰,可加2~3节低通滤波器消除干扰。
在单片机系统中,为了提高供电系统的质量,防止窜入干扰,建议采用如下措施:
(1)单片机输入电源与强电设备动力电源分开。
(2)采用具有静电屏蔽和抗电磁干扰的隔离电源变压器。
隔离变压器的初级和次级之间均采用隔离屏蔽层(可用漆包线或铜等非导磁材料在初级和次级绕一层,但电气上不能与初级、次级线圈短路,而后引出一个头接地)。各初级、次级间的静电屏蔽与初级间的零电位线相接,再用电容耦合接地。如图所示:

图片1

过程通道是系统输入、输出以及单片机之间进行信息传输的路径。由于输入输出对象与单片机之间的连接线长,容易串入干扰,必须采用隔离技术、双绞线传输、阻抗匹配等措施抑制。

2、开关量隔离

     有一种就是接光耦,我们做电机类项目的时候,MCU与大功率电机控制区之间是要用光耦进行隔离的,防止大电流烧坏MCU引脚,常用的开关量隔离器有光电隔离器、继电器、光电隔离固态继电器(SSR)。

(1)光电隔离器
      光电耦合器是把一个发光二极管和一个光敏三极管封装在一个外壳里的器件,光电耦合器的电路符号如图8—3所示。输入信号使发光二极管发光,其光线又使光敏三极管产生电信号输出,从而既完成了信号的传递,又实现了电气上的隔离,如图8—4所示。对启动或停止负荷不太大的设备,常采用光电耦合器来抑制输出通道的干扰。图片2

图片3 

如果输出开关量是用于控制大负荷设备时,就需采用继电器隔离输出。因为继电器触点的负载能力远远大于光电隔离的负载能力,它能直接控制动力回路。在采用继电器做开关量隔离输出时,要在单片机输出端的锁存器74LS273与继电器间设置一个

图片4 

OC门驱动器。用以提供较高的驱动电流。 

平时的干扰一般是信号高低跳变是产生的尖峰,一般在芯片旁边加上一个旁路电容,而且是尽可能靠近芯片的旁路电容就能解决,但是在工业应用或者室外,久不久还是会出现干扰的情况,你的加上拉方法试过,有改善,但是貌似改善的算是一半多点,还是有一半的情况出现误动作,也不确定是不是程序不够完善,反正还是有很多地方要注意检查

   

(七)、软件干扰

   看了上面的,都是在讲硬件干扰,我来说说软件干扰吧
软件抗干扰主要有亮点: 一是消除模拟输入信号的嗓声(如数字滤波技术);二是程序运行混乱时使程序重入正轨的方法。

看门狗抗干扰:失控的程序进入“死循环”,通常都是采用“看门狗”技术使程序脱离“死循环”。通过不断检测程序循环运行时间,若发现程序循环时间超过最大循环运行时间,则认为系统陷入“死循环”,需进行出错处理。

    “看门狗”技术可由硬件实现,也可由软件实现。 在工业应用中,严重的干扰有时会破坏中断方式控制字,关闭中断。系统无法定时“喂狗”,硬件看门狗电路失效。而软件看门狗可有效地解决这个问题


(八)、印制板工艺抗干扰:
. 电源线加粗,合理走线接地,三总线分开: 减少互感振荡
. CPU RAM ROM等主芯片,VCC 和GND间接电解电容及瓷片电容:去掉高低频干扰脉冲
. 独立系统结构,减少接插件与连线:提高可靠性,减少构障率
. 集成块与插座接触可靠,用双簧插座,最好集成块直接焊在印制板上:防止器件接触不良故障
. 有条件采用四层以上印制板,中间两层为电源及地
(二). 软件抗干扰措施:
1. 多用查询代替中断,把中断源减到最少:中断信号连线不大于0.1 米,防止误触发感应触发
2. A/D 转换采用数字滤波:平均法,比较平均法等:防止突发性干扰
3. MCS-51 单片机空单元写上00H,最后放跳转指令到ORG 0000H:因干扰程序走飞,可能抓回去
4. 多次重复输出,输出信号保持在RAM 中:止因干扰信止输出
5. 开机自检 自诊断,RAM 中重要内容要分区存放,经常进行比较检查,机器不能带病工作
6. 表格参数放在 EPROM 中,检验和存于最后单元,防止EPROM
7. 加看门狗,软件走飞可从头开始
8. 开关信号延时去抖动
9. I/O 口正确操作,必须检查口执行命令情况防止外部故障不执行控制命令
10. 通讯应加奇偶校验或查询 表决比较等措施,防止通讯出错

(三).这个滤波电容主要是在PCB layout时,要注意位置,基本上所有小电容都要靠近引脚

(九)、地线的处理 

MCU的抗干扰,那就不得不说地线的处理 

1、选择单点接地与多点接地。当信号频率小于1MHz时,应尽量采用单点并联接地,实际布线有困难时,可以部分串联后再并联接地;当频率大于10MHz时,适合采用多点串联接地;当信号频率在1~10MHz之间时,若地线长度不超过波长的1/20,可用单点接地

 

图片1

2、数字地、模拟地、电源地等分开走线,在一个点上可靠连接

 

图片2

MCU的抗干扰,那就不得不说地线的处理 

1、选择单点接地与多点接地。当信号频率小于1MHz时,应尽量采用单点并联接地,实际布线有困难时,可以部分串联后再并联接地;当频率大于10MHz时,适合采用多点串联接地;当信号频率在1~10MHz之间时,若地线长度不超过波长的1/20,可用单点接地

 

图片1

2、数字地、模拟地、电源地等分开走线,在一个点上可靠连接

 

图片 

3、接地线应尽量加粗,使它能通过三倍于印制板上的允许电流。一般接地线宽度应在2~3mm以上。地线、电源线与信号线的关系是:地线>电源线>信号线

4、 使数字电路的接地线形成闭环路。

5、高频部分尽量采用大面积包围式地线

以上若有不当之处,还请各位大侠指教

3、接地线应尽量加粗,使它能通过三倍于印制板上的允许电流。一般接地线宽度应在2~3mm以上。地线、电源线与信号线的关系是:地线>电源线>信号线

4、 使数字电路的接地线形成闭环路。

5、高频部分尽量采用大面积包围式地线


助工
2015-01-12 09:17:45     打赏
13楼
谢谢支持!会持续分享更多的原创内容,有错误,请客观指出。

助工
2015-01-12 13:39:56     打赏
14楼

11、吴鉴鹰单片机项目详细解析系列(连载)之基于单片机的超声波测距仪设计(一)——硬件设计一

 


图1

1、超声波测距原理

发射器发出的超声波以速度v在空气中传播,在到达被测物体是被反射返回,由接受器接受,其往返时间为t,有s=vt/2即可算出被测物体的距离。由于超声波也是一种声波,其声速v与温度有关,下表列出了几种不同温度下的声速。在使用时,如果温度变化不大,则可认为声速是基本不变的。如果测距精度要求很高,则应该通过温度补偿的方法加以校正。


1超声波测距仪原理框图单片机发出40khz的信号,经放大后通过超声波发射器输出;超声波接受器将接受到得超声波信号经放大器放大,用锁相环电路进行检波处理后,启动单片机中断程序,测得时间为t,再由软件进行辨别、计算,得出距离数并送LCD显示并送语音播报模块播报。

2、吴鉴鹰的项目成品具有的功能

1) 具有超声波测距功能,测量距离0.20m~5.00m测距精度±1㎝。2) 具有测量距离数值无线传输功能。3) 实时显示测量的距离,显示格式为:X.XXm。4) 汉字提醒显示:距离在0.40m~1.00m,显示“危险距离”并用红色LED灯指示;距离在1.00m~2.00m,显示“保持距离”,并用黄书LED灯指示;距离在2.00m以上,显示“安全距离”并用绿色LED灯指示。5) 具有实时语音播报功能,实时播报测量距离数值,格式:X.XXm,实时播报时间间隔≤10s,实时播报声音清晰明亮、无明显失真,在1m距离处人耳能准确分辨。语音播报要与显示同步。


图2

3、超声波测距方法的选择

      超声波测距的原理一般采用渡越时间法TOF(time of flight)。首先测出超声波从发射到遇到障碍物返回所经历的时间,再乘以超声波的速度就得到二倍的声源与障碍物之间的距离。测量距离的方法有很多种,短距离的可以用尺,远距离的有激光测距等,超声波测距适用于高精度的中长距离测量。因为超声波在标准空气中的传播速度为331.45米/秒,由单片机负责计时,单片机使用12.0MHZ晶振,所以此系统的测量精度理论上可以达到毫米级。由于超声波指向性强,能量消耗缓慢,在介质中传播距离远,因而超声波可以用于距离的测量。利用超声波检测距离,设计比较方便,计算处理也较简单,并且在测量精度方面也能达到要求。根据设计任务、控制对象和现有条件本系统硬件电路采用由单片机最小系统、温度补偿电路、超声波发射电路、超声波接收电路、显示电路无线通信电路以及语音播报电路构成。本超声波测距仪的具体工作过程如下,单片机控制的振荡源产生40kHz的频率信号来驱动超声传感器。每次发射包含6个脉冲左右,当第一个超声波脉冲发射后,计数器开始计数,在检测到第一个回波脉冲的瞬间,计数器停止计数,得到从发射到接收的时间t 后,单片机读取温度值补偿声速,利用测距公式可计算出被测距离,同时由无线通信模块将测量数据传到下位机进行显示和语音播报。系统总体框图如图所示。

 


图3 发射模块

 


图 4   图4 接收模块

4、超声波发生器选择

超声波发生器可以分为两类:一类是用电气方式产生超声波,一类是用机械方式产生超声波。本课题属于近距离测量,可以采用常用的压电式超声波换能器来实现。超声波测距的原理是利用超声波的发射和接受,根据超声波传播的时间来计算出传播距离。实用的测距方法有两种,一种是在被测距离的两端,一端发射,另一端接收的直接波方式,适用于身高计;一种是发射波被物体反射回来后接收的反射波方式,适用于测距仪。此次设计采用反射波方式。测距仪的分辨率取决于对超声波传感器的选择。超声波传感器是一种采用压电效应的传感器,常用材料是压电式陶瓷。由于超声波在空气传播时会有相当的衰减,衰减的程度与频率的高低成正比;而频率高分辨率也高,故短距离测量时应选择高频率的传感器,而长距离测量时应用低频率的传感器。

5、超声波接受传感器

超声探头的核心是其塑料外套或者金属外套中的一块压电晶片。构成晶片的材料可以有许多种。晶片的大小,如直径和厚度也各不相同,因此每个探头的性能是不同的,我们使用前必须预先了解它的性能。超声波传感器的主要性能指标包括:工作频率。工作频率就是压电晶片的共振频率。当加到它两端的交流电压的频率和晶片的共振频率相等时,输出的能量最大,灵敏度也最高。工作温度。由于压电材料的居里点一般比较高,特别时诊断用超声波探头使用功率较小,所以工作温度比较低,可以长时间地工作而不失效。医疗用的超声探头的温度比较高,需要单独的制冷设备。灵敏度。主要取决于制造晶片本身。机电耦合系数大,灵敏度高;反之,灵敏度低。因此超声波接受传感器应该应用集成电路CX20106A,CX20106A是一款红外线检波接收的专用芯片,常用于电视机红外遥控接收器。考虑到红外遥控常用的载波频率38kHz与测距的超声波频率40kHz较为接近,可以利用它制作超声波检测接收电路(如图2-3)。实验证明用CX20106A接收超声波(无信号时输出高电平),具有很好的灵敏度和较强的抗干扰能力。适当更改电容CS的大小,可以改变接收电路的灵敏度和抗干扰能力。此部分电路在集成芯片上2.5显示单元选择显示单元是计算机系统开发时使用的主要设备之一,它可将计算机的运算结果、中间结果、存储器地址以及存储器、寄存器中的内容显示出来,从而实现人机对话。可以做显示器的有:LED,LCD,CRT等。CRT就是常见的显像管式的显示器。优点是颜色视觉效果好,视角宽,可靠性高,便宜;缺点是体积大耗电多,有微量的X射线辐射。LED就是发光二极管。LED一般适合做大屏幕的显示设备,最突出的有点那就是屏幕尺寸可以不受限制,亮度可以做的很高,其他的如显色性、对比度等都不如CRT显示器。但是考虑到本设计需要显示测量距离,补偿温度以及危险,保持 ,安全等警告信号。所以选择采用128*64液晶模块。2.6语音播报电路选择语音播报语音芯片有很多种,例如WT1380、WT588D等。WT1380具有多种报警功能,定时器功能,时钟输出功能,中断输出功能以及语音播报功能。它的语音功能和万年历功能可以同时工作,主频采用RC振荡,副频采用32.768K晶振精确分频。可以计算年、月、日、时、分、秒等信息,并可以将时间信息反馈给主控单片机。因而,WT1380是一款性价比极高的语音时钟芯片。但是本设计不要求芯片有可以计算年、月、日、时、分、秒等信息的复杂功能。所以播报电路采用WT588D系列的集单片机和语音电路于一体的可编辑语音芯片。WT588D系列语音单片机是广州唯创科技有限公司联合台湾华邦共同研发出来的集单片机和语音电路于一体的可编辑语音芯片。功能多音质好应用范围广性能稳定是WT588D系列语音单片机的特长,弥补了以往各类语音芯片应用领域狭小的缺陷,MP3控制模式、按键控制模式、按键组合控制模式、并口控制模式、一线串口控制模式、三线串口控制模式以及三线串口控制I/O口扩展输出模式,让应用人员能将产品投放在几乎可以想象得到的场所。WT588D是一款功能强大的可重复擦除烧写的语音单片机芯片。WT588D让语音芯片不再为控制方式而寻找合适的外围单片机电路,高度集成的单片机技术足于取代复杂的外围控制电路。配套WT-APP上位机操作软件可随意更换WT588D语音单片机芯片的任何一种控制模式,把信息下载到SPI-Flash上即可。软件操作方式简洁易懂,撮合了语音组合技术,大大减少了语音编辑的时间。2.7温度传感器的选择大家知道,声音在不同温度的空气中传播速度是不同的,所以这里要考虑到温度补偿的问题。温度传感器有很多种,例如温度传感器AD590。AD590是美国模拟器件公司生产的单片集成两端感温电流源。流过器件的电流(mA)等于器件所处环境的热力学温度(开尔文)度数。AD590的测温范围为-55℃~+150℃。AD590的电源电压范围为4V~30V。电源电压可在4V-6V范围变化,电流变化1mA,相当于温度变化1K。AD590可以承受44V正向电压和20V反向电压,因而器件反接也不会被损坏。输出电阻为710WM。它的精度高。AD590共有I、J、K、L、M五档,其中M档精度最高,在-55℃~+150℃范围内,非线性误差为±0.3℃。但是考虑到成本问题我选用TS-18B20数字温度传感器。该产品采用美国DALLAS公司生产的DS18B20可组网数字温度传感器芯片封装而成,具有耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温和控制领域。独特的一线接口,只需要一条口线通信多点能力,简化了分布式温度传感应用无需外部元件可用数据总线供电,电压范围为3.0V至5.5V无需备用电源测量。温度范围为-55°C至+125℃ 。-10°C至+85°C范围内精度为±0.5°C

温度传感器可编程的分辨率为9~12位温度转换为12位数字格式最大值为750毫秒用户可定义的非易失性温度报警设置应用范围包括恒温控制,工业系统,消费电子产品温度计,或任何热敏感系统。

 


助工
2015-01-12 13:49:16     打赏
15楼

12、吴鉴鹰单片机项目详细解析系列(连载)之基于单片机的超声波测距仪设计(二)——硬件设计二


6、硬件电路的设计


硬件电路的设计主要包括单片机系统及显示电路、语音播报电路、温度补偿电路、无线传输、超声波发射电路和超声波检测接受电路五部分。单片机采用AT89C51或其兼容系列。采用12MHz高精度的晶振,以获得较稳定的时钟频率,减小测量误差。单片机用P3.6端口输出超声波换能器所需的40KHz的方波信号,利用外部中断1口检测超声波接受电路输出的返回信号。显示单元部分采用12864液晶模块。3.1 AT89S51单片机的功能及特点AT89S51是美国ATMEL公司生产的低电压,高性能CMOS8位单片机,片内含有4K bytes的课反复擦写的只读程序存储器(PEROM)和128bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度。非易失性存储技术生产,兼容标准MCS51指令系统,片内置通用8位中央处理器(CPU)和Flash存储单元,功能强大AT89S51单片机可以为您提供许多高性价比的应用场合,可灵活应用于各种控制领域。3.1.1主要性能参数Ø 与MCS51产品指令系统完全兼容。Ø 4K字节可以重复擦写Flash闪速存储器。Ø 1000吃擦写周期。Ø 全静态操作:0Hz24Hz。Ø 三级加密程序存储器。Ø 128*8字节内部RAM。Ø 32个可编程I/O口线。Ø 6个中断源。Ø 可编程串行UART通道。Ø 低功耗空闲和掉电模式。3.1.2功能特性概述AT89S51提供以下功能:Ø 4k字节Flash闪速存储器;Ø 128字节内部RAM;Ø 32I/O口线;Ø 两个16位定时器/计时器;Ø 一个5向量两级中断结构;Ø 一个双工串行口通信;Ø 片内振荡器及时钟电路。同时,AT89S51可以降至0Hz的静态逻辑操作,并支持两种软件可选的节点工作模式。空闲方式停止CPU的工作,当允许RAM,定时/计数器,串行口及中断系统继续工作。掉电式保存RAM中的内容,但振荡器停止工作并禁止其他左右部件工作直到下一个硬件复位。

5

5AT89S51单片机 3.2单片机最小系统其作用主要是为了保证单片机系统能正常工作。如图3-2所示,单片机最小系统主要由AT89S51单片机、外部振荡电路、复位电路和+5V电源组成。在外部振荡电路中,单片机的XTAL1XTAL2管脚分别接至由12MHZ晶振和两个30PF电容构成的振荡电路两侧,为电路提供正常的时钟脉冲。在复位电路中,单片机RESET管脚一方面经20 F的电容接至电源正极,实现上电自动复位,另一方面经开关s接电源。其主要功能是把PC初始化为0000H,是单片机从0000H单元开始执行程序,除了进入系统的初始化之外,当由于程序出错或者操作错误使系统处于死锁状态时,为了摆脱困境,也需要按复位键重新启动。因此,复位电路是单片机系统中不可缺少的一部分。 

6

6,单片机最小系统,单片机测距原理单片机发出超声波测距是通过不断检测超声波发射后遇到障碍物所反射的回波,从而测出发射和接收回波的时间差tr,然后求出距离SCt÷2  式中的C为超声波波速。限制该系统的最大可测距离存在4个因素:超声波的幅度、反射的质地、反射和入射声波之间的夹角以及接收换能器的灵敏度。接收换能器对声波脉冲的直接接收能力将决定最小的可测距离。为了增加所测量的覆盖范围、减小测量误差,可采用多个超声波换能器分别作为多路超声波发射/接收的设计方法,限于实际需要,本电路只采用单路超声波发射接收。由于超声波属于声波范围,其波速C与温度有关。

7、超声波发射电路

超声波发射电路压电式超声波换能器是利用压电晶体的谐振来工作的。超声波换能器内部有两个压电晶片和一个换能板。当它的两极外加脉冲信号,其频率等于压电晶片的固有振荡频率时,压电晶片会发生共振,并带动共振板振动产生超声波,这时它就是一个超声波发生器;反之,如果两电极问未外加电压,当共振板接收到超声波时,将压迫压电晶片作振动,将机械能转换为电信号,这时它就成为超声波接收换能器。超声波发射换能器与接收换能器在结构上稍有不同,使用时应分清器件上的标志。

7

发射电路主要由反相器74LS04和超声波发射换能器T构成,如图所示,单片机P2.7端口输出的40kHz的方波信号一路经一级反向器后送到超声波换能器的一个电极,另一路经两级反向器后送到超声波换能器的另一个电极,用这种推换形式将方波信号加到超声波换能器的两端,可以提高超声波的发射强度。输出端采两个反向器并联,用以提高驱动能力。上位电阻R2R3一方面可以提高反向器74LS04输出高电平的驱动能力,另一方面可以增加超声波换能器的阻尼效果,缩短其自由振荡时间。

8、超声波检测接收电路

超声波接收电路CX20106A是一款红外线检波接收的专用芯片,常用于电视机红外遥控接收器。考虑到红外遥控常用的载波频率38kHz与测距的超声波频率40kHz较为接近,可以利用它制作超声波检测接收电路。实验证明用CX20106A接收超声波(无信号时输出高电平),具有很好的灵敏度和较强的抗干扰能力。适当更改电容C16

的大小,可以改变接收电路的灵敏度和抗干扰能力。其电路由图所示。

8


CX20106A的引脚注释:1IN:超声波信号输入端,该脚的输入阻抗约为40kΩ。2AGC:该脚与GND之间连接RC串联网络,它们是负反馈串联网络的一个组成部分,改变它们的数值能改变前置放大器的增益和频率特性。增大电阻R或减小C,将使负反馈量增大,放大倍数下降,反之则放大倍数增大。但C的改变会影响到频率特性,一般在实际使用中不必改动,推荐选用参数为R=4.7Ω,C=3.3μF3C0:该脚与GND之间连接检波电容,电容量大为平均值检波,瞬间相应灵敏度低;若容量小,则为峰值检波,瞬间相应灵敏度高,但检波输出的脉冲宽度变动大,易造成误动作,推荐参数为3.3μF4GND:接地端。5RC0:该脚与电源端VCC接入一个电阻,用以设置带通滤波器的中心频率f0,阻值越大,中心频率越低。例如,取R=200kΩ时,fn42kHz,若取R=220kΩ,则中心频率f038kHz6C:该脚与GND之间接入一个积分电容,标准值为330pF,如果该电容取得太大,会使探测距离变短。7OUT:遥控命令输出端,它是集电极开路的输出方式,因此该引脚必须接上一个上拉电阻到电源端,该电阻推荐阻值为22kΩ,没有接收信号时该端输出为高电平,有信号时则会下降。8RC1:电源正极,4.5V5V9、温度补偿电路

DS18B20温度传感器是美国DALLAS半导体公司推出的一种改进型智能温度传感器,测温范围为-55125℃,最大分辨率可达0.0625℃。DS18B20可以直接读出被测温度值,而且采用了一线制与单片机相连,减少了外部的硬件电路,具有低成本和易使用的特点。测温电路图3-5所示。DS18B20温度传感器:(1):技术性能描述独特的单线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯。Ø 测温范围-55℃~+125℃,固有测温分辨率0.5℃。Ø 工作电源:3~5V/DC。Ø 在使用中不需要任何外围元件。Ø 测量结果以9~12位数字量方式串行传送。Ø 不锈钢保护管直径Φ6。Ø 适用于DN15~25DN40~DN250各种介质工业管道和狭小空间设备测温。Ø 标准安装螺纹M10X1M12X1.5G1/2任选。Ø PVC电缆直接出线或德式球型接线盒出线,便于与其它电器设备连接。

10、显示模块

带中文字库的128X64是一种具有4/8位并行、2线或3线串行多种接口方式,内部含有国标一级、二级简体中文字库的点阵图形液晶显示模块;其显示分辨率为128×64。内置819216*16点汉字,和12816*8ASCII字符集。利用该模块灵活的接口方式和简单、方便的操作指令,可构成全中文人机交互图形界面。可以显示8×416×16点阵的汉字。12864液晶模块可完成图形显示。低电压低功耗是其又一显著特点。由该模块构成的液晶显示方案与同类型的图形点阵液晶显示模块相比,不论硬件电路结构或显示程序都要简洁得多,且该模块的价格也略低于相同点阵的图形液晶模块。

9

11、语音播报电路

语音播报电路采用WT588D系列的集单片机和语音电路于一体的可编辑语音芯片。功能多音质好应用范围广性能稳定是WT588D系列语音单片机的特长,同时具有MP3控制模式、按键控制模式、按键组合控制模式、并口控制模式、一线串口控制模式、三线串口控制模式以及三线串口控制I/O口扩展输出模式。可控制的语音地址位能达到220个!每个地址位里能加载可组合语音为128段语音。只需通过适当的访问地址就可以实现语音播报,使用方便,语音播报电路设计如图所示。

  10

11、 APC240无线通信模块

无线发射与接收电路采用APC240无线通信模块。它是新一代的多通道嵌入式无线数传模块,其可设置众多的频道,发射功率高,而仍然具有较低的功耗。它可以在工业等强干扰的恶劣环境中使用。在任何状态下都可以1次传输256bytes的数据,当设置空中波特率大于串口波特率时,可1次传输无限长度的数据。同时它还提供标准的UART/TTLRS485RS232三种接口1200/2400/4800/9600bps四速率,和三种接口校验方式.采用串口设置模块参数。具有丰富便洁的软件编程设置选项。无线发射与接收电路见

 11 

12


Ø 接口方式:232/485/TTL串口,格式有8N1/8E1/8O1可选;Ø 接受灵敏度高,视距可靠传输距离可达1200m;Ø 采用FSK的方式调制,支持OOK/ASK/MSK调制;Ø 载频433MHz,可定制315M/868M/915M等其他ISM频段;Ø 提供PC机配置软件,可以灵活设置模块的各种参数;Ø 串口速率:4800/9600/19200/38400/57600/115200bps;Ø 空中速率:5K/10K/20K/30K/40K/50K/77K/100K/150K/200K/250Kbps;Ø 功耗和休眠省电模式:功率<100 mw,接收电流<35mA,发射电流<100mA,休眠时电流<12uA;Ø 支持多个字网组群工作模式,网络地址配置相同的模块间才可以相互通讯;Ø 具有中继功能,可选择中继节点进行传输,有效扩大传输距离;Ø 支持透明传输方式和地址传输方式,可以组成点对点、点对多点、对点对多点等无线通信网络;Ø 5V直流供电(可以选择3.3V);3.9.2APC240无线通信模块主要技术指标工作频率:433M        调制方式:FSK发射功率:<20dBm(100mW)接收灵敏度:-119dB发射电流:<35mA接收电流:<100mA休眠电流:<12uA工作信道:32个频段选择数据接口:232/485/TTL串口数据格式:8N1/8E1/8O1串口速率:4800/9600/19200/38400/57600/115200bps空中速率:5K/10K/20K/30K/40K/50K/77K/100K/150K/200K/250Kbps硬件接口:2.0插针/插座通讯距离:0-700米(10dbm,10kbps,可视距离)天线阻抗:50Ω工作温度:-40-85℃供电方式:DC3.3V/5V尺寸:32.3x54.0mm(不包括天线)




助工
2015-01-13 13:29:12     打赏
16楼
这位兄弟你好,我的连载帖子分享是由易到难,让初学者有个适应的过程,所以帖子有什么不妥之处,还请指出,不胜感激!

助工
2015-01-13 17:22:58     打赏
17楼
谢谢支持!后续会更新更多的原创帖子,共同学习,共同进步!

助工
2015-01-14 09:14:31     打赏
18楼

 13、吴鉴鹰单片机项目详细解析系列(连载)之基于单片机的超声波测距仪设计(三)——软件设计(一

 

/***********************************************************************************************************************
吴鉴鹰程序风格简简单介绍:① 每个子程序的开头都会有一个简介,介绍程序的功能,输入、输出变量,以及程序的作者,修改日期,
                             还有程序的难点、重点简单介绍,为了增强程序的可读性。
                          ② IO口定义的格式为:A_B_C 其中A为该口对应的器件,B为功能,C为输入输出方向。
                 ③ 输入输出方向定义原则:输入:_IN  输出:_OUT 输入输出:_IO
************************************************************************************************************************/
** 函数名称:  主机程序
** 功能描述:  超声波的发送和接收,将测得的数据发给从机
** 输 入:         
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
#include
#include
#include
#include #define uchar unsigned char
#define uint   unsigned int
#define ufloat unsigned float
#define ulong  unsigned long
#define NOP _nop_();_nop_();_nop_()
#define nop _nop_() sbit DS18B20_DQ_OUT = P2^6;  //定义DS18B20端口DS18B20_DQ   A_B_C分别对应为DS18B20_DQ_OUT
uchar presence ;
uchar Send[5];
uchar  temp_data[2]={0x00,0x00};
uchar  display[5]={0x00,0x00,0x00,0x00,0x00};
uchar code  ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,
                       0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
bit  flash=0;                          //显示开关标记
//*位定义/*//
sbit LS2_csb_OUT=P3^6;
bit flag_1=0;
uint speed=340;
uint temp2;
uint temp;
uint count=0;
uchar high_time,low_time,flag=0,tc=2;
uchar flag_2=0;
uchar tc_say=0;
uint dis,dis_4[9];  /**********************************************************************************
** 函数名称:  void delay(int ms)
** 功能描述:  延时n毫秒
** 输 入:        
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void delay(int ms)
{
    while(ms--)
 {
      uchar i;
   for(i=0;i<246;i++)
    {
     _nop_();
  _nop_();  
  _nop_();
  _nop_();
    }
 }
}
/**********************************************************************************
** 函数名称:  void delay_tms(uint t)
** 功能描述:  延时n毫秒
** 输 入:        
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void delay_tms(uint t)
{
   uchar k;
   while(t--)
   {
     for(k=0; k<125; k++)
     { }
   }
}

/**********************************************************************************
** 函数名称:  void delay_lcd(int ms)
** 功能描述:  延时函数200us
** 输 入:        
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void delay_lcd(int ms)
{
  uchar t;
  while(ms--)
  {
    for(t=0; t<20; t++) ;
  }
}

/**********************************************************************************
** 函数名称:  void delay_nms(uint ms)
** 功能描述:  延时n个ms函数
** 输 入:        
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void delay_nms(uint ms)   //delay ms function
{
    uchar i;
 while(ms--)
    {
     for(i = 0; i < 123; i++);
    }
}
/**********************************************************************************
** 函数名称:  void delay100us()
** 功能描述:  延时100us函数
** 输 入:        
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void delay100us()
{
 uchar  j;
 for(j=50;j>0;j--);
}

void Delay_1(uint num)    //延时函数
{
while( --num );
}
//*函数名:Init_DS18B20
//功能:DS18B20初始化*//

/**********************************************************************************
** 函数名称:  Init_DS18B20(void)
** 功能描述:  DS18B20初始化
** 输 入:         
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
uchar Init_DS18B20(void)//初始化ds1820
{
     DS18B20_DQ_OUT = 1;      //DS18B20_DQ复位
     Delay_1(8);              //稍做延时
     DS18B20_DQ_OUT = 0;      //单片机将DS18B20_DQ拉低
     Delay_1(90);             //精确延时 大于 480us
     DS18B20_DQ_OUT = 1;      //拉高总线
     Delay_1(8);
     presence = DS18B20_DQ_OUT;   //如果=0则初始化成功 =1则初始化失败
     Delay_1(100);
     DS18B20_DQ_OUT = 1;
     return(presence);        //返回信号,0=presence,1= no presence
}
/**********************************************************************************
** 函数名称:  ReadOneChar(void)
** 功能描述:  从18B20中读一个字节数据
** 输 入:         
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
 ReadOneChar(void)//读一个字节
{
unsigned char i = 0;
 unsigned char LCD_RW_OUT = 0;
 for (i = 8; i > 0; i--)
    {
     DS18B20_DQ_OUT = 0; // 给脉冲信号
     LCD_RW_OUT >>= 1;
     DS18B20_DQ_OUT = 1; // 给脉冲信号
     if(DS18B20_DQ_OUT)
       LCD_RW_OUT |= 0x80;
     Delay_1(4);
   }
    return (LCD_RW_OUT);
}
/**********************************************************************************
** 函数名称:  WriteOneChar(uchar DAT)
** 功能描述:  写入一个字节数据
** 输 入:    DAT(送入的数字)     
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void WriteOneChar(uchar DAT)//写一个字节
{
unsigned char i = 0;
   for (i = 8; i > 0; i--)
   {
     DS18B20_DQ_OUT = 0;
     DS18B20_DQ_OUT = DAT&0x01;
     Delay_1(5);
     DS18B20_DQ_OUT = 1;
     DAT>>=1;
   }
}
/**********************************************************************************
** 函数名称:  Read_Temperature(void)
** 功能描述:  读取温度
** 输 入:         
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void Read_Temperature(void)             //读取温度
{
Init_DS18B20();
   if(presence==1)
    {
  flash=1;                        //DS18B20不正常
}      
    else
    {
     flash=0;
      WriteOneChar(0xCC);             // 跳过读序号列号的操作
      WriteOneChar(0x44);             // 启动温度转换
      Init_DS18B20();
      WriteOneChar(0xCC);             //跳过读序号列号的操作
      WriteOneChar(0xBE);             //读取温度寄存器
      temp_data[0] = ReadOneChar();   //温度低8位
      temp_data[1] = ReadOneChar();   //温度高8位
}
}
/**********************************************************************************
** 函数名称:  void temp_all(void)
** 功能描述:  进行温度补偿
** 输 入:         
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void temp_all()
{
   Read_Temperature();
 display[4]=temp_data[0]&0x0f;
 display[0]=ditab[display[4]];          //查表得小数位的值
display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);//温度整数值
display[3]=display[4]/100;
 display[1]=display[4]%100;
 display[2]=display[1]/10;
 display[1]=display[1]%10;
 if(display[4]>50)         //温度高于50度,则不修正
{
  flash=1;                //表示测试的温度不正常
}
 //*if((flash==0)&&(flag_1 == 0))
 //{
 // Disp_Temperature();
 //}*/
 if(flash==0)                         //温度传感器正常检测到温度并温度小于50度
{
  speed=(uint)(331+(display[4]*61+display[0]*6+45)/100);//声音的速度加上温度因素
}
}
/**********************************************************************************
** 函数名称:  uint Distance_count()
** 功能描述:  距离计算函数
** 输 入:         
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void Distance_count()
{
         float temp1;
         ulong  tt;
         temp2 = high_time*256+low_time;
         temp = high_time*256+low_time;
      tt = (ulong)temp*344 ;
         temp1 = (float)(tt/2000.0);
         temp = (uint)(temp1);
         temp = (uint)(temp1+0.5);
         // return temp;
}
/**********************************************************************************
** 函数名称:  uint do_s(uint dis_1)
** 功能描述:  距离补偿函数
** 输 入:    uint dis_1      
** 输 出:    uint dis_1       
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
uint do_s(uint dis_1)
{
 uchar n;
 if((dis_1>70)&(dis_1<100))
 {
  n = dis_1/10;
  switch(n)
  {
   case 7:dis_1-=40;break;
   case 8:dis_1-=22;break;
   case 9:dis_1-=26;break;
  }
  return(dis_1);
 }
 else
 {
  n = dis_1/100;
  switch(n)
  {
   case 1:dis_1-=43;break;
   case 2:dis_1-=42;break;
   case 3:dis_1-=34;break;
   case 4:dis_1-=30;break;
   case 5:dis_1-=32;break;
   case 6:dis_1-=31;break;
   case 7:dis_1-=28;break;
   case 8:dis_1-=29;break;
   case 9:dis_1-=34;break;
   case 10:dis_1-=34;break;
   case 11:dis_1-=34;break;
   case 12:dis_1-=35;break;
   case 13:dis_1-=30;break;
   case 14:dis_1-=35;break;    
   case 15:dis_1-=46;break;
   case 16:dis_1-=46;break;
   case 17:dis_1-=39;break;
   case 18:dis_1-=36;break;
   case 19:dis_1-=37;break;
   case 20:dis_1-=32;break;
   case 21:dis_1-=33;break;
   case 22:dis_1-=34;break;
   case 23:dis_1-=38;break;
   case 24:dis_1-=40;break;
   case 25:dis_1-=35;break;
   case 26:dis_1-=35;break;
   case 27:dis_1-=37;break;
   case 28:dis_1-=62;break;
   case 29:dis_1-=64;break;
   case 30:dis_1-=68;break;
   case 31:dis_1-=64;break;
   case 32:dis_1-=256;break;
   case 33:dis_1-=262;break;
   case 34:dis_1-=268;break;
   case 35:dis_1-=271;break;
   case 36:dis_1-=282;break;
   case 37:dis_1-=290;break;
   case 38:dis_1-=302;break;
   case 39:dis_1-=332;break;
   case 40:dis_1-=352;break;
   case 41:dis_1-=350;break;
   case 42:dis_1-=367;break;
   case 43:dis_1-=285;break;
   case 44:dis_1-=350;break;
   case 45:dis_1-=290;break;
   case 46:dis_1-=295;break;
            case 47:dis_1-=295;break;
            case 48:dis_1-=374;break;
   case 49:dis_1-=395;break;
   case 50:dis_1-=395;break;
            case 51:dis_1-=405;break;
            case 52:dis_1-=425;break;
            case 53:dis_1-=394;break;
   case 54:dis_1-=395;break;
   case 55:dis_1-=495;break;
  }
 return(dis_1);
 }
}
/**********************************************************************************
** 函数名称:  void tran(),void tran1(),void tran2()
** 功能描述:  超声波的发射
** 输 入:         
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void tran()
{
 uchar i;
 TH0=0;
 TL0=0;
 TR0=1;
 for(i=4;i>0;i--)
 {
  LS2_csb_OUT=!LS2_csb_OUT;
  nop;
  nop;
  nop;
  nop;
  nop;
  nop;
  nop;
  nop;
  nop;
 }
 LS2_csb_OUT=1;
 delay_ms(1);
 EX1=1;
 delay_ms(30);
 if(flag==1)
 {
  Distance_count();
        dis=temp;
  flag=0;
 }
 else dis=0;
}
/**********************************************************************************
** 函数名称:  void tran(),void tran1(),void tran2()
** 功能描述:  超声波的发射
** 输 入:         
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void tran1()
{
 uchar i;
 TH0=0;
 TL0=0;
 TR0=1;
 for(i=20;i>0;i--)
 {
  LS2_csb_OUT=!LS2_csb_OUT;
  nop;
  nop;
  nop;
  nop;
  nop;
  nop;
  nop;
  nop;
  nop;
 }
 LS2_csb_OUT=1;
 delay_ms(2);
 EX1=1;
 delay_ms(50);
 if(flag==1)
 {  
     Distance_count();
  dis = temp;
  flag=0;
    }
 else dis=0;
}
/**********************************************************************************
** 函数名称:  void tran(),void tran1(),void tran2()
** 功能描述:  超声波的发射
** 输 入:         
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
 void tran2()
{
 uchar i;
 TH0=0;
 TL0=0;
 TR0=1;
 for(i=16;i>0;i--)
 {
  LS2_csb_OUT=!LS2_csb_OUT;
  nop;
  nop;
  nop;
  nop;
  nop;
  nop;
  nop;
  nop;
  nop;
 }
 LS2_csb_OUT=1;
 delay_ms(20);
 EX1=1;
 delay_ms(150);
 if(flag==1)
 {
  Distance_count();
     dis=temp;
  flag=0;
 }
 else 
 {
  dis=0;
 }
}

/**********************************************************************************
** 函数名称:  void fit_1(void)
** 功能描述:  取最大值
** 输 入:         
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void fit_1(void)
{
 uint h;
 uchar m,k,p;
 for(m=0;m<7;m++)       //以下语句为冒泡法排序
{
     for(k=0;k<=8-m;k++)
  {
   if(dis_4[k]>dis_4[k+1])
   {
    h=dis_4[k];
    dis_4[k]=dis_4[k+1];
    dis_4[k+1]=h;
   }
  }
 }
 dis =(dis_4[3]+dis_4[4]+dis_4[5])/3;
 p=0;
}
/**********************************************************************************
** 函数名称:  void send( char B )
** 功能描述:  串口发送程序
** 输 入:         
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void send( char B ) //发送一个字节
{ 
SBUF=B;
    while(!TI);
 TI=0;
}
/**********************************************************************************
** 函数名称:  void USART_init(void)
** 功能描述:  播放“测量距离"
** 输 入:    uint dis_say(测得的距离)    
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void USART_init(void) //串口的初始化
{
TH1=0xfd;
 TL1=0xfd;
 TR1=1;
 SM0=0;
 SM1=1;
 REN=1;
}
/**********************************************************************************
** 函数名称:  void main(void)
** 功能描述:  主函数
** 输 入:         
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void main(void)
{
 unsigned char i,j,TEST;
 P0 = 0xff;
 P1 = 0xff;
 P2 = 0xff;
  TMOD=0x01;
 TH0=0;
 TL0=0;
 EA=1;
 IE=0x80;
    IT1=0;
 USART_init();
 while(1)
 {
        if(tc_say==4)
  {
             temp_all();
    tc_say=0;
  }
  tc_say++;
  for(i=0;i<9;i++)
  {
    IE=0x80;
    tran1(); 
    dis= do_s(dis);
             dis_4=dis;
  }
  fit_1();
  Send[2] = dis>>8;
  Send[3] = dis;
  
  if( flag == 1 )
  {   
   ES=0;
   i=0;
   Send[0] = temp_data[0];
   Send[1] = temp_data[1];
   
   TEST = Send[0];
   for(i = 1; i < 4;i ++)
   {
      TEST = TEST&Send;  //这是发送的数据取&得到的数据作为第八位,也就是吴鉴鹰定义的检验位
   }
   Send[4] = TEST;
   for(i=0;i<4;i++)
   { 
     send(Send);        //发送数据
   } 
   //Num=0;
   flag=0; 
   ES=1; 
  }
     /*if(dis4000)  time=time-1000;
  else
  {
  if((time-dis)<2500) time=dis;
  else        time=time-100;
  }
  }
  else*/
  /*dis_all(dis);
  dis=0;
  lcd_pos(1,6);
  for(j=0;j<4;j++)
  write(1,space4[j]);
  lcd_pos(1,6);
  for(j=0;j<4;j++)
  {
  write(1,point4[j]);
  delay(100);
  }*/
 }
}
/**********************************************************************************
** 函数名称:  void TT() interrupt 2
** 功能描述:  中断,产生脉冲
** 输 入:         
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void TT() interrupt 2
{
 TR0=0;
    ET1=0;
 flag=1;
 high_time = TH0;
 low_time = TL0;
    TR0=0;
}

         
/**********************************************************************************
** 函数名称:  从机程序
** 功能描述:  LCD12864的显示,语音播报模块的启动
** 输 入:         
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
//*包含头文件*//
#include
#include
#include
#include
#define uchar unsigned char
#define uint   unsigned int
#define ufloat unsigned float
#define ulong  unsigned long
#define NOP _nop_();_nop_();_nop_()
#define nop _nop_()
//*常量定义*//
#define KEY_circle_IN  0xf2//循环播放
#define KEY_stopplay_IN  0xfe//停止播放
#define adjust_volice_0  0xe0//调节音量1
#define adjust_volice_1  0xe1//调节音量2
#define adjust_volice_2  0xe2//调节音量3
#define adjust_volice_3  0xe3//调节音量4
#define adjust_volice_4  0xe4//调节音量5
#define adjust_volice_5  0xe5//调节音量6
#define adjust_volice_6  0xe6//调节音量7
#define adjust_volice_7  0xe7//调节音量8
uchar vo_vo=0xe7;
uchar Num;
uchar flag_2;
uchar flag;
//*程序功能:ST7920控制芯片(汉字库),串口模式。12864 图片与文字显示*//
uchar code  DIS1[] = {"超声波测距中...."};
uchar code  DIS3[] = {"距障碍物:  .   m"};
uchar code  DIS4[] = {"测距情况: 安全  "};
uchar code  DIS5[] = {"测距情况: 请保持"};
uchar code  DIS6[] = {"测距情况: 危险!!"};
uchar code  DIS8[] = {"                "};
uchar code  DIS9[] = {"超声波倒车测距仪"};
uchar code  DIS10[]= {" V1.0 2008.12.4 "};
uchar   point4[];
uchar   space4[];
unsigned int dis;
unsigned char  DIS_receive_data[3];
unsigned char  display_TEMP_DATA[5]={0x00,0x00,0x00,0x00,0x00};
unsigned char  dist_test_DATA[5]={0x00,0x00,0x00,0x00,0x00};

//*位定义*//
sbit LCD_RST_OUT = P1^4;    //LCDLCD_RST_OUT
sbit LCD_RS_OUT = P1^1;//片选端  RS
sbit LCD_CLK_OUT = P1^2;//时钟   SLCD_CLK_OUT
sbit LCD_RW_OUT = P1^3;//数据位  RW
sbit WT_busy_OUT = P1^0;//忙信号
sbit LED_green_OUT=P2^4;
sbit LED_yellow_OUT=P2^5;
sbit LED_red_OUT=P2^5;

/**********************************************************************************
** 函数名称:  void delay_nms(uint ms)
** 功能描述:  延时n个ms函数
** 输 入:        
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void delay_nms(uint ms)   //delay ms function
{
    uchar i;
 while(ms--)
    {
     for(i = 0; i < 123; i++);
    }
}
/**********************************************************************************
** 函数名称:  void delay(int ms)
** 功能描述:  延时函数n毫秒
** 输 入:        
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
 void delay(int ms)
{
    while(ms--)
 {
      uchar i;
   for(i=0;i<246;i++)
    {
     _nop_();
  _nop_();  _nop_();
  _nop_();
    }
 }
}
/**********************************************************************************
** 函数名称:  void delay_lcd(int ms)
** 功能描述:  延时函数200us
** 输 入:        
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void delay_lcd(int ms)
{
  uchar t;
  while(ms--)
  {
    for(t=0; t<20; t++) ;
  }
}
/**********************************************************************************
** 函数名称:  void sendbyte(uchar bbyte)
** 功能描述:  向LCD12864液晶数据位发送一个字节
** 输 入:         
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void sendbyte(uchar bbyte)
{
  uchar i;
  for(i=0;i<8;i++)
  {
   LCD_RW_OUT = bbyte&0x80; //取出最高位
   LCD_CLK_OUT = 1;
   _nop_();
   _nop_();
   LCD_CLK_OUT=0;
   bbyte<<=1; //左移
  }
}
/**********************************************************************************
** 函数名称:  void write(bit start, uchar ddata)
** 功能描述:  向LCD12864液晶写指令或数据函数
** 输 入:         
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void write(bit start, uchar ddata)
 {
      uchar start_data,Hdata,Ldata;
   if(start==0)                  //11111,(0),(0),0
   {
      start_data=0xf8;         //写指令
   }
   else                          //11111,(0),(1),0
   {
      start_data=0xfa;           //写数据
   }                             //
//  //Hdata = ddata & 0xf0;         //取高四位 Hdata = ddata&0xf0;
   Ldata = (ddata<<4)&0xf0;      //取低四位
   sendbyte(start_data);         //发送起始信号
   delay_lcd(1);                 //延时
   sendbyte(Hdata);             //发送高四位
   delay_lcd(1);                 //延时
   sendbyte(Ldata);          //发送低四位
   delay_lcd(1);                 //延时
}

 

 


助工
2015-01-14 09:15:08     打赏
19楼

14、吴鉴鹰单片机项目详细解析系列(连载)之基于单片机的超声波测距仪设计(四)——软件设计(二) 

/**********************************************************************************
** 函数名称:  void lcd_pos(uchar X,uchar Y)
** 功能描述:  设定显示位置
** 输 入:    uchar X,uchar Y     
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void lcd_pos(uchar X,uchar Y)
{
    uchar  pos;
    if (X==1)
    {
  X=0x80;
    }
    else
 if (X==2)
 {
  X=0x90;
 }
 else
 if (X==3)
 {
  X=0x88;
 }
 else
 if (X==4)
 {
  X=0x98;
 }
   pos = X+Y ;
   write(0,pos); //lcd_wcmd(pos);        //写位置命令
}
/**********************************************************************************
** 函数名称:  show(uint ss)
** 功能描述:  显示测试数据
** 输 入:    uint ss    
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void  show(uint ss)
{
  uchar data_s[2],i;
  data_s[0]=ss/10000;           //数据的处理
  if(data_s[0]==0)   //测量数据的十米位为0
  {
   data_s[0]=0x20;
  }
  else
  {
   data_s[0]=data_s+0x30; //
  }
  data_s[1]=ss%10000/1000+0x30;
     lcd_pos(3,5);        //第三行,第七个(2*n+1)字节位置显示
     write(1,data_s[1]);       //for(i=0;i<2;i++)
            //{
            // write(1,data_s);  //lcd_wdat(data_s);       //显示米位数据
              //delay(1);
        // }
  data_s[0]=ss%1000/100+0x30;
  data_s[1]=ss%100/10+0x30;
  lcd_pos(3,6);
     for(i=0;i<2;i++)
     {
      write(1,data_s);  //lcd_wdat(data_s);      //显示分米和厘米位数据
        delay(1);
  }
  write(1,ss%10+0x30);  //lcd_wdat(ss%10+0x30);     //显示毫米位数据
  delay(1);
}
/**********************************************************************************
** 函数名称:  void lcd_init()
** 功能描述:  初始化LCD
** 输 入:       
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void lcd_init()
{
  delay_lcd(10);     //延时等待LCM进入工作状态
  LCD_RS_OUT=1;  //片选 高电平有效
  write(0,0x30);     //基本指令操作
  write(0,0x0c);     //显示打开,光标关,反白关
  write(0,0x01);     //清屏,将DDRAM的地址计数器归零
  write(0,0x06);
}
/**********************************************************************************
** 函数名称:  void photodisplay(uchar *bmp)
** 功能描述:  uchar *bmp
** 输 入:       
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void photodisplay(uchar *bmp)
{
  uchar i,j;
  write(0,0x34);        //写数据时,关闭图形显示
  for(i=0;i<32;i++)
  {
    write(0,0x80+i);    //先写入水平坐标值
    write(0,0x80);      //写入垂直坐标值
    for(j=0;j<16;j++)   //再写入两个8位元的数据
    write(1,*bmp++);
    delay_lcd(1);
  }
  for(i=0;i<32;i++)
  {
    write(0,0x80+i);
    write(0,0x88);
    for(j=0;j<16;j++)
 write(1,*bmp++);
 delay_lcd(1);
  }
  write(0,0x36);       //写完数据,开图形显示
}
/**********************************************************************************
** 函数名称:  void  clr_screen()
** 功能描述:  LCD清屏函数
** 输 入:       
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void  clr_screen()
{
    write(0,0x34); //lcd_wcmd(0x34);      //扩充指令操作
    delay(5);
    write(0,0x30); //lcd_wcmd(0x30);      //基本指令操作
    delay(5);
    write(0,0x01); //lcd_wcmd(0x01);      //清屏
    delay(5);
}
/**********************************************************************************
** 函数名称:  void displayall()
** 功能描述:  主显示函数
** 输 入:       
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void displayall()
{
    uchar i;
    delay(2);
    lcd_init();               //初始化LCD
    lcd_pos(2,0);             //设置显示位置为第二行
    for(i=0;i<16;i++)
    {
     write(1,DIS9); //lcd_wLCD_RW_OUT(DIS9);
        delay(30);
    }
    lcd_pos(3,0);             //设置显示位置为第三行
    for(i=0;i<16;i++)
    {
     write(1,DIS10); //lcd_wLCD_RW_OUT(DIS10);
        delay(30);
    }
    delay(1000);
    clr_screen();               //清屏
       delay(500);
    clr_screen();               //上电,等待稳定
    lcd_pos(1,0);              //设置显示位置为第一行
    for(i=0;i<16;i++)
    {
     write(1,DIS1);      //lcd_wLCD_RW_OUT(DIS1);
        delay(2);
    }
    lcd_pos(3,0);             //设置显示位置为第三行
    for(i=0;i<16;i++)
    {
     write(1,DIS3); //lcd_wLCD_RW_OUT(DIS3);
        delay(2);
    }
    lcd_pos(4,0);           //设置显示位置为第四行
    for(i=0;i<16;i++)
    {
       write(1,DIS8); //lcd_wLCD_RW_OUT(DIS8);
       delay(2);
    }
    delay(1000);
}
/**********************************************************************************
** 函数名称:  void show_one(uchar DIS[8],uchar hh)
** 功能描述:  设置行显示
** 输 入:    uchar DIS[16],uchar hh   
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void show_one(uchar DIS[16],uchar hh)
{
 uchar i;
    lcd_pos(hh,0);             //设置显示位置行
    for(i=0;i<16;i++)
    {
     write(1,DIS); //lcd_wLCD_RW_OUT(DIS);
        delay(1);
    }
}
/**********************************************************************************
** 函数名称:  void send_com(uchar add)
** 功能描述:  发码播放,add为语音地址
** 输 入:    uchar add 
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void send_com(uchar add)
{
 uchar  i;
 LCD_RST_OUT=1;
 LCD_RST_OUT=0;
 delay_nms(3);
 LCD_RST_OUT=1;
 delay_nms(20);
 LCD_RS_OUT=0;
 delay_nms(5);
 for(i=0;i<8;i++)
 {
   LCD_CLK_OUT=0;
  if(add&1) LCD_RW_OUT=1;
  else LCD_RW_OUT=0;
  delay100us();
  LCD_CLK_OUT=1;
  delay100us();
  add=add>>1;
 }
 LCD_RS_OUT=1;
}
/**********************************************************************************
** 函数名称:  void sound(uint soud)
** 功能描述:  播报测距距离
** 输 入:  soud
**         
**        
** 输 出: 
**         
** 全局变量: 
** 调用模块: 
**
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void sound(uint soud)
{
 uchar i,j,k,l;
 send_com(vo_vo);
 while(!WT_busy_OUT);
 i=soud/1000;
 j=soud%1000/100;
 k=soud%100/10;
 l=soud%10;
 send_com(i);
 delay_nms(30);
 while(!WT_busy_OUT);
 send_com(10);         //播放“点”
delay_nms(30);
 while(!WT_busy_OUT);
 send_com(j);
 delay_nms(30);
 while(!WT_busy_OUT);
 send_com(k);
 delay_nms(30);
 while(!WT_busy_OUT);
 if(l!=0)
 {
  send_com(l);
  delay_nms(30);
  while(!WT_busy_OUT);
 }
 send_com(11);         //播放"米"
delay_nms(30);
 while(!WT_busy_OUT);
}
/**********************************************************************************
** 函数名称:  void dis_all(uint dis_s)
** 功能描述:  控制LED指示灯和语音播报
** 输 入:    uint dis_s     
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void dis_all(uint  dis_s)
{
 show(dis_s);
  if(dis_s>2000)
 {
   show_one(DIS4,2);
   LED_green_OUT=0;LED_red_OUT=1;LED_yellow_OUT=1;
   if(flag_2!=1)
   {
    }
    flag_2=1;
    }
 else
 {
   if((dis_s>500)&(dis_s<1000))
   {
     show_one(DIS5,2);
    LED_green_OUT=1;LED_red_OUT=1;LED_yellow_OUT=0;
    if(flag_2!=2)
    {
    }
    flag_2=2;
    }
   else
   {
    if((dis_s>100)&(dis_s<500))
    {
       show_one(DIS6,2);
      LED_green_OUT=1;LED_red_OUT=0;LED_yellow_OUT=1;
      if(flag_2!=3)
      {
       }
          flag_2=3;
     }
     else
     {
        show_one(DIS8,2);
      LED_yellow_OUT=1;
      if(dis_s<100)
        { LED_red_OUT=!LED_red_OUT;LED_green_OUT=1;}
          else
        {LED_green_OUT=!LED_green_OUT;LED_red_OUT=1;}
     }
     }
  }
}
/**********************************************************************************
** 函数名称:  void Disp_Temperature()
** 功能描述:  显示温度
** 输 入:        
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void Disp_Temperature()//显示温度
{
unsigned char n=0, word[16]={"环境温度:     ℃"};
 show_one(word,4);
 for(n=0;n<16;n++)
 write(1,word[n]);  
    lcd_pos(4,5);             //设置显示位置为第三行
if(display_TEMP_DATA[3] != 0)
       write(1,display_TEMP_DATA[3]+0x30); //lcd_wdat(display_TEMP_DATA[3]+0x30);   //温度值百位不显示
else   
  write(1,0x20);  //lcd_wdat(0x20); */
    delay(1);
 if((display_TEMP_DATA[3]==0)&&(display_TEMP_DATA[2]==0))
 {
      write(1,0x20); //lcd_wdat(0x20);
 }
 else
 {
   write(1,display_TEMP_DATA[2]+0x30); //lcd_wdat(display_TEMP_DATA[2]+0x30);
 }
    delay(1);
 write(1,display_TEMP_DATA[1]+0x30); //lcd_wdat(display_TEMP_DATA[1]+0x30);
 delay(1);
 write(1,'.'); //lcd_wdat('.');
 delay(1);
 write(1,display_TEMP_DATA[0]+0x30); //lcd_wdat(display_TEMP_DATA[0]+0x30);
 delay(1);
}
/**********************************************************************************
** 函数名称:  void  soundplay(uint dis_say)
** 功能描述:  播放“测量距离"
** 输 入:    uint dis_say(测得的距离)    
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void  soundplay(uint dis_say)
{
 if(WT_busy_OUT != 0) 
 {
      sound(dis_say);//播放“测量距离”
}
}
/**********************************************************************************
** 函数名称:  void USART_init(void)
** 功能描述:  播放“测量距离"
** 输 入:    uint dis_say(测得的距离)    
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void USART_init(void) //串口的初始化
{
TH1=0xfd;
 TL1=0xfd;
 TR1=1;
 SM0=0;
 SM1=1;
 REN=1;
}
/**********************************************************************************
** 函数名称:  void dists_data_mov(uchar dat)
** 功能描述:  将受到的数值转换成LCD12864能显示的数据,存放到相应的数组中,dist_test_DATA为距离的
              display_TEMP_DATA为温度数组
** 输 入:    uint dat   
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void dists_data_mov(uchar dat)
{
   if(dat == 1)
   {
  point4[0] = ((uint)(dist_test_DATA[0]<<8 + dist_test_DATA[1]))/10000;
  point4[1] = ((uint)(dist_test_DATA[0]<<8+ dist_test_DATA[1]))/1000%10;
  point4[2] = ((uint)(dist_test_DATA[0]<<8+ dist_test_DATA[1]))/100%10;
  point4[3] = ((uint)(dist_test_DATA[0]<<8+ dist_test_DATA[1]))/10%10;
  point4[4] = ((uint)(dist_test_DATA[0]<<8+ dist_test_DATA[1]))%10;
 }
 else
 {
     space4[0] = ((uint)display_TEMP_DATA[2]<<8+ display_TEMP_DATA[3])/10000;
  space4[1] = ((uint)display_TEMP_DATA[2]<<8+ display_TEMP_DATA[3])/1000%10;
  space4[2] = ((uint)display_TEMP_DATA[2]<<8+ display_TEMP_DATA[3])/100%10;
  space4[3] = ((uint)display_TEMP_DATA[2]<<8+ display_TEMP_DATA[3])/10%10;
  space4[4] = ((uint)display_TEMP_DATA[2]<<8+ display_TEMP_DATA[3])%10;
 }
}

/**********************************************************************************
** 函数名称:  void  soundplay(uint dis_say)
** 功能描述:  播放“测量距离"
** 输 入:    uint dis_say(测得的距离)    
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void main(void)
{
 uchar i,j;
 P0 = 0xff;
 P1 = 0xff;
 P2 = 0xff;
  TMOD=0x21;
 TH0=0;
 TL0=0;
 EA=1;
 IE=0x90;
    IT1=0;
 USART_init();  //串口的初始化
Num = 0;
 while(1)
 {
        //* if(tc_say==4)
  //{
        //temp_all();  温度补偿
  //tc_say=0;
  //}*/
  /*tc_say++;
  //for(i=0;i<9;i++)
  //{
        //         IE=0x80;
  //  tran1(); 
  //  dis = do_s(dis);
        //               dis_4 = dis;
  //}
  //fit_1();*/
     //*if(dis4000)  time=time-1000;
  //else
  //{
  // if((time-dis)<2500) time=dis;
  // else        time=time-100;
  //}
  //}
  //else*/
  
  Disp_Temperature();//温度显示
  dists_data_mov(0); //温度示数转换
  dists_data_mov(1); //距离示数转换
  dis_all(dis);      //语音播报
  dis=0;
  lcd_pos(1,6);      //设定显示位置
  for(j=0;j<4;j++)
  write(1,space4[j]);
  lcd_pos(1,6);      //设定显示位置
  for(j=0;j<4;j++)
  {
   write(1,point4[j]);
   delay(100);
  }
 }
}
/**********************************************************************************
** 函数名称:  void ser() interrupt 4 
** 功能描述:  串口中断接收数据
** 输 入:        
** 输 出:          
** 全局变量: 
** 调用模块: 
** 作 者:     吴鉴鹰
** 日 期:     14.03.5
************************************************************************************/
void ser() interrupt 4  //中断接收数据
{ 
     unsigned char receive[10];
  unsigned char a,i;
     if(RI==1) 
     {  
      DIS_receive_data[Num] = SBUF;
  if(Num < 5)
  {
           Num++;
        }
        else
        {
    a = receive[0];
    for(i = 1;i < 4;i ++)
    {
    a = a&receive;
    }
    if(a = receive[4])
    {
       for(i = 0; i < 2;i++)
    {
       display_TEMP_DATA = receive;
    }
    for(i = 2;i < 4;i++)
    {
       dist_test_DATA = receive;
    }
    }
    /*if(DIS_receive_data[0]&DIS_receive_data[1] == DIS_receive_data[2])
    {    
    }*/
    Num = 0;    
     }  
        flag=1;
        RI=0;
     }  
}

 

 


助工
2015-01-14 13:09:13     打赏
20楼
Thank you, I will share more Projects!

共31条 2/4 1 2 3 4 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]