社区导航

 

搜索
楼主: 吴鉴鹰.

[原创] 资深工程师单片机实战项目精讲(连载),由易到难连续分享

  [复制链接]

364

TA的帖子

0

TA的资源

纯净的硅(初级)

Rank: 4

 楼主| 发表于 2014-6-13 22:12 | 显示全部楼层
      8、吴鉴鹰单片机实战项目精讲(连载)微机键盘的运用——程序设计


  1. 3、相关的程序编写

  2.     吴鉴鹰在本例中使用时一种标准的通讯程序,各位烧友可以参考参考一下Atmel公司发布的单片机在键盘中的应用笔记,这个程序我也是参考该应用笔记
  3. 给各位烧友分享的。
  4.    除了有关的字符库外,吴鉴鹰的这个程序主要为4个部分:①、初始化 ②、串口通讯 ③、键盘 ④、数据处理
  5.    1.程序功能
  6.    该程序的主要功能是处理外接的微机键盘和单片机的数据通讯,这里吴鉴鹰就分为4个部分进行介绍
  7.    ①Main.C:主程序,主要处理单片机和键盘通讯的初始化
  8.    ②Low_level_init:键盘的初始化和通信协议的初始化
  9.    ③Serial.c:串行通讯程序,处理数据的传输和收发
  10.    ④Kb.C:键盘的按键处理程序,控制按键的谁和发送
  11.    2、主要器件很函数的说明
  12.    ⑴.Low_level_init.c:   初始化键盘和单片机的通信方式
  13.    ⑵.Main():             主程序,初始化参数并等待中断产生
  14.    ⑶.init_uart():        初始化串口的寄存器
  15.    ⑷.init_kb():          初始化键盘的收发
  16.    ⑸.getchar():          读取字符函数
  17.    ⑹.putchar():          发送字符函数
  18.    ⑺.delay():            延时函数
  19.    ⑻.init_uart(void):    初始化串口
  20.    ⑼.clr(void):          定义清屏函数
  21.    ⑽.init_kb(void):      初始化键盘
  22.    ⑾.decode(unsigned sc):键盘按键码解码函数
  23.    ⑿.put_kbbuff(uchar):  键盘的输入字符函数
  24.    /*键盘的初始化*/
  25. /*************************************************************************
  26. ** 函数名称:   _Low_level_init  
  27. ** 功能描述:   这个函数的主要功能是对单片机的端口和串行通讯的波特率、通信方式等作一系列的规定很处理  
  28.                                                          
  29. ** 输 入:
  30. **         
  31. **         
  32. ** 输 出:
  33. ** 全局变量:
  34. ** 调用模块:
  35. **
  36. ** 作 者:    吴鉴鹰
  37. ** 日 期:    14.03.2
  38. *******************************************************************************/
  39. //Low_level_init.c
  40. #include<ina90.h>
  41. #include<io8585.h>
  42. int  _Low_level_init(void)
  43. {
  44.    UBRR = 12;
  45.    UCR = 0X08;
  46.    GIMSK = 0X40;
  47.    _SEI();
  48.    return 1;
  49. }
  50.    
  51.    
  52. /*主函数*/  
  53. #include<pgmspace.h>
  54. #include<stdio.h>
  55. #include<stdlib.h>
  56. #include "io8515.h"
  57. #include "serial.h"
  58. #include "gpr.h"
  59. #include "kb.h"
  60. /***************************************************************************************
  61. ** 函数名称:   main  
  62. ** 功能描述:   串口的初始化、初始化键盘的收发  
  63.                                                          
  64. ** 输 入:
  65. **         
  66. **         
  67. ** 输 出:
  68. ** 全局变量:
  69. ** 调用模块:
  70. **
  71. ** 作 者:    吴鉴鹰
  72. ** 日 期:    14.03.2
  73. *****************************************************************************************/
  74. void main()
  75. {
  76.    unsigned char key;
  77.    init_usart();                    //串口的初始化程序
  78.    init_kb();                       //初始化键盘的收发
  79.    while(1)
  80.    {
  81.       key = getchar();
  82.    putchar(key);
  83.    delay(100);                   //延时子程序
  84.    }
  85. }

  86. /*键盘处理子程序*/
  87. #include<pgmspace.h>
  88. #include "kb.h"
  89. #include "serial.h"
  90. #include "qpr.h"
  91. #include "scancodes.h"
  92. #define BUFF_SIZE 64
  93. unsigned char dege,bitcount;        //0 :符号,1 :正号
  94. unsigned char kb_buffer[BUFFER_SIZE];
  95. unsigned char *inpt,*outpt;
  96. unsigned char buffercnt;
  97. /******************************************************************************
  98. ** 函数名称:   init_kb  
  99. ** 功能描述:   初始化键盘  
  100.                                                          
  101. ** 输 入:
  102. **         
  103. **         
  104. ** 输 出:
  105. ** 全局变量:
  106. ** 调用模块:
  107. **
  108. ** 作 者:    吴鉴鹰
  109. ** 日 期:    14.03.2
  110. **********************************************************************************/
  111. void init_kb(void)
  112. {
  113.     inpt = kb_buffer;                 //初始化缓冲区        
  114. outpt = kb_buffer;
  115. buffcnt = 0;
  116. MCUCR = 2;                       //INT0中断,下降沿触发
  117. edge = 0;                        //0:下降沿,1 :上升沿
  118. bitcount = 11;
  119. }
  120. /**********************************************************************************
  121. ** 函数名称:   INT0_interrupt  
  122. ** 功能描述:   按键接收中断函数  
  123.                                                          
  124. ** 输 入:
  125. **         
  126. **         
  127. ** 输 出:
  128. ** 全局变量:
  129. ** 调用模块:
  130. **
  131. ** 作 者:    吴鉴鹰
  132. ** 日 期:    14.03.2
  133. **************************************************************************************/
  134. interrupt  [INT0_vect]  void INT0_interrupt(void)
  135. {
  136.    static unsigned char data;            //保持接收扫描码的状态
  137.    if(!edge)                             //下降沿触发中断服务程序
  138.    {
  139.       if(bitcount < 11 && bitcount > 2)  //3~10位是数据
  140.    {                                  //删除起始位和停止位
  141.      data = (data >> 1);            
  142.   if(PIND & 8)
  143.   data = data | 0x80;             //如果为“1”则存储         
  144.    }
  145.    MCUCR = 3;                         //设置该寄存器是为了用上升沿触发中断
  146.    edge = 1;
  147.    }
  148.    else
  149.    {
  150.      MCUCR = 2;
  151.   edge = 0;
  152.   if(--bitcount == 0)               //该判断是接收到所有的中断的时候
  153.   {
  154.     decode(data);
  155.     bitcount = 11;
  156.   }
  157.    }
  158. }
  159. /*********************************************************************************
  160. ** 函数名称:   decode  
  161. ** 功能描述:   键盘按键码解码函数
  162.                                                          
  163. ** 输 入:
  164. **         
  165. **         
  166. ** 输 出:
  167. ** 全局变量:
  168. ** 调用模块:
  169. **
  170. ** 作 者:    吴鉴鹰
  171. ** 日 期:    14.03.2
  172. ************************************************************************************/
  173. void decode(unsigned char sc)
  174. {
  175.    static unsigned char is_up = 0,shift = 0,mode = 0;
  176.    unsigned char i;
  177.    if(!is_up)                          //最后一位数据的接收
  178.    {
  179.       switch(sc)
  180.    {
  181.      case 0xf0: is_up = 1;break;    //确定完成了的按键
  182.   case 0x12: shift = 1;break;    //左边的shift键
  183.   case 0x59: shift = 1;break;    //右边的shift键
  184.   case 0x05:                     //F1键
  185.   if(mode == 0)
  186.   {
  187.     mode = 1;                    //进入按键扫描模式
  188.   }
  189.   if(mode == 2)                  //离开按键扫描模式
  190.   {
  191.     mode = 3;
  192.   }
  193.   break;
  194.   default:
  195.   if(mode == 0 || mode == 3)     //ASCΙΙ模式
  196.   {
  197.     if(!shift)                   //如果没有shift键被按下
  198.     {                            //查表
  199.       for(i=0;unshifted[0] != sc && unshifted[0];i++);
  200.    if(unshifted[0] == sc)
  201.    {
  202.       put_kbuffer(unshifted[1]);
  203.    }
  204.     }
  205.     else
  206.     {                           //如果shift键被按下
  207.          for(i = 0;shifted[0] != sc && shifted[0];i ++);
  208.       if(shifted[0] == sc)
  209.       {
  210.          put_kbbuffer(shifted[1]);
  211.       }
  212.     }
  213.   }
  214.   else
  215.   {
  216.     print_hexbyte(sc);          //扫描键盘吗模式
  217.     put_kbbuffer(' ');          //显示模式
  218.     put_kbbuffer(' ');
  219.   }
  220.   break;
  221.    }
  222.    }
  223.    else
  224.    {
  225.       is_up = 0;                      //2个0xf0在一列中不允许的
  226.    switch(sc)
  227.    {
  228.        case 0x12:shift = 0;break;  //左shift
  229.     case 0x59:shift = 0;break;  //右shift
  230.     case 0x05:                  //F1
  231.     {
  232.       if(mode == 1)
  233.    {
  234.      mode = 2;
  235.    }
  236.    if(mode == 3)
  237.    {
  238.      mode = 0;
  239.    }
  240.    break;
  241.    case 0x06:                //F2
  242.    clr();
  243.    break;
  244.     }
  245.    }
  246.    }
  247. }
  248. /****************************************************************************************
  249. ** 函数名称:   put_kbbuff  
  250. ** 功能描述:   键盘输入字符的函数
  251.                                                          
  252. ** 输 入:
  253. **         
  254. **         
  255. ** 输 出:
  256. ** 全局变量:
  257. ** 调用模块:
  258. **
  259. ** 作 者:    吴鉴鹰
  260. ** 日 期:    14.03.2
  261. ****************************************************************************************/
  262. void put_kbbuff(unsigned char c)
  263. {
  264.      if(buffcnt < BUFF_SIZE)                  //若缓冲区为空
  265.      {
  266.        *inpt = C;                          //在缓冲区中输入一个字符            
  267.     inpt++;                             //指针加1
  268.     buffcnt ++;
  269.     if(inpt >= kb_buffer + BUFF_SIZE)   //指针判断
  270.     {
  271.        inpt = kb_buffer;
  272.     }
  273.   }   
  274. }
  275. /*****************************************************************************************
  276. ** 函数名称:   getchar  
  277. ** 功能描述:   读取键盘输入字符的函数
  278.                                                          
  279. ** 输 入:
  280. **         
  281. **         
  282. ** 输 出:
  283. ** 全局变量:
  284. ** 调用模块:
  285. **
  286. ** 作 者:    吴鉴鹰
  287. ** 日 期:    14.03.2
  288. ****************************************************************************************/
  289. int  getchar(void)
  290. {
  291.    int byte;
  292.    while(buffcnt == 0);                     //等待数据
  293.    byte = *outpt;                           //取数据
  294.    outpt++;                                 //指针加1
  295.    if(outpt >= kb_buffer + BUFFER_SIZE)     //指针比较
  296.    outpt = kb_buffer;
  297.    buffcnt--;                               //缓冲区减去1
  298.    return byte;
  299. }
复制代码



为了方便大家交流,建了两个QQ群:QQ群3号:198387118  【1000人群】QQ群5号: 239316959【2000人群】群内已有成员3000余人!
更多内容关注微信公众号:单片机精讲吴鉴鹰

回复

使用道具 举报

4

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2014-6-14 11:44 | 显示全部楼层
好东西,支持!!

点评

感觉有什么问题的地方欢迎指出!!!!  详情 回复 发表于 2014-6-19 09:07

回复

使用道具 举报

25

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2014-6-14 16:33 | 显示全部楼层
看到鹰哥的文章,我顿时有一种想哭的感觉。想想以后我应该也要这样奋斗才行,才能够对得起我吃的那么多饭!

点评

谢谢你的鼓励!加油!兄弟!  详情 回复 发表于 2014-6-14 18:03

回复

使用道具 举报

364

TA的帖子

0

TA的资源

纯净的硅(初级)

Rank: 4

 楼主| 发表于 2014-6-14 18:03 | 显示全部楼层
孤星寒 发表于 2014-6-14 16:33
看到鹰哥的文章,我顿时有一种想哭的感觉。想想以后我应该也要这样奋斗才行,才能够对得起我吃的那么多饭!

谢谢你的鼓励!加油!兄弟!
为了方便大家交流,建了两个QQ群:QQ群3号:198387118  【1000人群】QQ群5号: 239316959【2000人群】群内已有成员3000余人!
更多内容关注微信公众号:单片机精讲吴鉴鹰

回复

使用道具 举报

364

TA的帖子

0

TA的资源

纯净的硅(初级)

Rank: 4

 楼主| 发表于 2014-6-15 13:45 | 显示全部楼层
本帖最后由 吴鉴鹰. 于 2014-6-17 11:06 编辑

9、吴鉴鹰单片机实战项目精讲(连载)之如何提高单片机的抗干扰能力

相关资料下载请点击下载: 吴鉴鹰如何提高单片机抗干扰的能力总结.pdf (388.94 KB, 下载次数: 213)
为了方便大家交流,建了两个QQ群:QQ群3号:198387118  【1000人群】QQ群5号: 239316959【2000人群】群内已有成员3000余人!
更多内容关注微信公众号:单片机精讲吴鉴鹰

回复

使用道具 举报

364

TA的帖子

0

TA的资源

纯净的硅(初级)

Rank: 4

 楼主| 发表于 2014-6-17 10:53 | 显示全部楼层

10、吴鉴鹰单片机实战项目精讲(连载)之基于单片机的超声波测距仪设计

本帖最后由 吴鉴鹰. 于 2014-6-17 11:11 编辑

10、吴鉴鹰单片机实战项目精讲(连载)之超声波测距仪设计(一)——原理图
相关资料请点击下载:
吴鉴鹰基于单片机的超声波测距设计原理图.pdf (542.16 KB, 下载次数: 662)




图片1.png

图1

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

1超声波测距仪原理框图单片机发出40khz的信号,经放大后通过超声波发射器输出;超声波接受器将接受到得超声波信号经放大器放大,用锁相环电路进行检波处理后,启动单片机中断程序,测得时间为t,再由软件进行辨别、计算,得出距离数并送LCD显示并送语音播报模块播报。
2、吴鉴鹰的项目成品具有的功能
1) 具有超声波测距功能,测量距离0.20m~5.00m测距精度±1㎝。2) 具有测量距离数值无线传输功能。3) 实时显示测量的距离,显示格式为:X.XXm4) 汉字提醒显示:距离在0.40m~1.00m,显示“危险距离”并用红色LED灯指示;距离在1.00m~2.00m,显示“保持距离”,并用黄书LED灯指示;距离在2.00m以上,显示“安全距离”并用绿色LED灯指示。5) 具有实时语音播报功能,实时播报测量距离数值,格式:X.XXm,实时播报时间间隔≤10s,实时播报声音清晰明亮、无明显失真,在1m距离处人耳能准确分辨。语音播报要与显示同步。
图片2.png

图2

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

3 发射模块

图片4.png

图 4

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


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.png

图5

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


图6

图6,单片机最小系统,单片机测距原理单片机发出超声波测距是通过不断检测超声波发射后遇到障碍物所反射的回波,从而测出发射和接收回波的时间差tr,然后求出距离SCt÷2  式中的C为超声波波速。限制该系统的最大可测距离存在4个因素:超声波的幅度、反射的质地、反射和入射声波之间的夹角以及接收换能器的灵敏度。接收换能器对声波脉冲的直接接收能力将决定最小的可测距离。为了增加所测量的覆盖范围、减小测量误差,可采用多个超声波换能器分别作为多路超声波发射/接收的设计方法,限于实际需要,本电路只采用单路超声波发射接收。由于超声波属于声波范围,其波速C与温度有关。
7、超声波发射电路
超声波发射电路压电式超声波换能器是利用压电晶体的谐振来工作的。超声波换能器内部有两个压电晶片和一个换能板。当它的两极外加脉冲信号,其频率等于压电晶片的固有振荡频率时,压电晶片会发生共振,并带动共振板振动产生超声波,这时它就是一个超声波发生器;反之,如果两电极问未外加电压,当共振板接收到超声波时,将压迫压电晶片作振动,将机械能转换为电信号,这时它就成为超声波接收换能器。超声波发射换能器与接收换能器在结构上稍有不同,使用时应分清器件上的标志。
图片7.png

7

发射电路主要由反相器74LS04和超声波发射换能器T构成,如图所示,单片机P2.7端口输出的40kHz的方波信号一路经一级反向器后送到超声波换能器的一个电极,另一路经两级反向器后送到超声波换能器的另一个电极,用这种推换形式将方波信号加到超声波换能器的两端,可以提高超声波的发射强度。输出端采两个反向器并联,用以提高驱动能力。上位电阻R2R3一方面可以提高反向器74LS04输出高电平的驱动能力,另一方面可以增加超声波换能器的阻尼效果,缩短其自由振荡时间。
8、超声波检测接收电路
超声波接收电路CX20106A是一款红外线检波接收的专用芯片,常用于电视机红外遥控接收器。考虑到红外遥控常用的载波频率38kHz与测距的超声波频率40kHz较为接近,可以利用它制作超声波检测接收电路。实验证明用CX20106A接收超声波(无信号时输出高电平),具有很好的灵敏度和较强的抗干扰能力。适当更改电容C16
的大小,可以改变接收电路的灵敏度和抗干扰能力。其电路由图所示。
图片8.png

图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.png


图9

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


图  10

11APC240无线通信模块

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

图 11

图片12.png

图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(不包括天线)



点评

硬件很彪!!!!!  详情 回复 发表于 2014-12-12 13:39
为了方便大家交流,建了两个QQ群:QQ群3号:198387118  【1000人群】QQ群5号: 239316959【2000人群】群内已有成员3000余人!
更多内容关注微信公众号:单片机精讲吴鉴鹰

回复

使用道具 举报

364

TA的帖子

0

TA的资源

纯净的硅(初级)

Rank: 4

 楼主| 发表于 2014-6-17 20:20 | 显示全部楼层
本帖最后由 吴鉴鹰. 于 2014-6-17 20:21 编辑

                                                  11、吴鉴鹰单片机实战项目精讲(连载)之超声波测距仪设计(二)——主机程序
  1. /*****************************************************************************************************
  2. /***********************************************************************************************************************
  3. 吴鉴鹰程序风格简简单介绍:① 每个子程序的开头都会有一个简介,介绍程序的功能,输入、输出变量,以及程序的作者,修改日期,
  4.                              还有程序的难点、重点简单介绍,为了增强程序的可读性。
  5.                           ② IO口定义的格式为:A_B_C 其中A为该口对应的器件,B为功能,C为输入输出方向。
  6.                  ③ 输入输出方向定义原则:输入:_IN  输出:_OUT 输入输出:_IO
  7. ************************************************************************************************************************/</font></font>
  8. <font size="2"><font color="#000000">/**********************************************************************************
  9. ** 函数名称:  主机程序
  10. ** 功能描述:  超声波的发送和接收,将测得的数据发给从机
  11. ** 输 入:         
  12. ** 输 出:         
  13. ** 全局变量:
  14. ** 调用模块:
  15. ** 作 者:     吴鉴鹰
  16. ** 日 期:     14.03.5
  17. ************************************************************************************/
  18. #include<reg52.h>
  19. #include<stdio.h>
  20. #include<math.h>
  21. #include<intrins.h></font></font>
  22. <font size="2"><font color="#000000">#define uchar unsigned char
  23. #define uint   unsigned int
  24. #define ufloat unsigned float
  25. #define ulong  unsigned long
  26. #define NOP _nop_();_nop_();_nop_()
  27. #define nop _nop_()</font></font>
  28. <font size="2"><font color="#000000">sbit DS18B20_DQ_OUT = P2^6;  //定义DS18B20端口DS18B20_DQ   A_B_C分别对应为DS18B20_DQ_OUT
  29. uchar presence ;
  30. uchar Send[5];
  31. uchar  temp_data[2]={0x00,0x00};
  32. uchar  display[5]={0x00,0x00,0x00,0x00,0x00};
  33. uchar code  ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,
  34.                        0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
  35. bit  flash=0;                          //显示开关标记
  36. //*位定义/*//
  37. sbit LS2_csb_OUT=P3^6;
  38. bit flag_1=0;
  39. uint speed=340;
  40. uint temp2;
  41. uint temp;
  42. uint count=0;
  43. uchar high_time,low_time,flag=0,tc=2;
  44. uchar flag_2=0;
  45. uchar tc_say=0;
  46. uint dis,dis_4[9];</font></font>
  47. <font size="2"><font color="#000000">
  48. /**********************************************************************************
  49. ** 函数名称:  void delay(int ms)
  50. ** 功能描述:  延时n毫秒
  51. ** 输 入:        
  52. ** 输 出:         
  53. ** 全局变量:
  54. ** 调用模块:
  55. ** 作 者:     吴鉴鹰
  56. ** 日 期:     14.03.5
  57. ************************************************************************************/
  58. void delay(int ms)
  59. {
  60.     while(ms--)
  61. {
  62.       uchar i;
  63.    for(i=0;i<246;i++)
  64.     {
  65.      _nop_();
  66.   _nop_();  
  67.   _nop_();
  68.   _nop_();
  69.     }
  70. }
  71. }
  72. /**********************************************************************************
  73. ** 函数名称:  void delay_tms(uint t)
  74. ** 功能描述:  延时n毫秒
  75. ** 输 入:        
  76. ** 输 出:         
  77. ** 全局变量:
  78. ** 调用模块:
  79. ** 作 者:     吴鉴鹰
  80. ** 日 期:     14.03.5
  81. ************************************************************************************/
  82. void delay_tms(uint t)
  83. {
  84.    uchar k;
  85.    while(t--)
  86.    {
  87.      for(k=0; k<125; k++)
  88.      { }
  89.    }
  90. }

  91. /**********************************************************************************
  92. ** 函数名称:  void delay_lcd(int ms)
  93. ** 功能描述:  延时函数200us
  94. ** 输 入:        
  95. ** 输 出:         
  96. ** 全局变量:
  97. ** 调用模块:
  98. ** 作 者:     吴鉴鹰
  99. ** 日 期:     14.03.5
  100. ************************************************************************************/
  101. void delay_lcd(int ms)
  102. {
  103.   uchar t;
  104.   while(ms--)
  105.   {
  106.     for(t=0; t<20; t++) ;
  107.   }
  108. }

  109. /**********************************************************************************
  110. ** 函数名称:  void delay_nms(uint ms)
  111. ** 功能描述:  延时n个ms函数
  112. ** 输 入:        
  113. ** 输 出:         
  114. ** 全局变量:
  115. ** 调用模块:
  116. ** 作 者:     吴鉴鹰
  117. ** 日 期:     14.03.5
  118. ************************************************************************************/
  119. void delay_nms(uint ms)   //delay ms function
  120. {
  121.     uchar i;
  122. while(ms--)
  123.     {
  124.      for(i = 0; i < 123; i++);
  125.     }
  126. }
  127. /**********************************************************************************
  128. ** 函数名称:  void delay100us()
  129. ** 功能描述:  延时100us函数
  130. ** 输 入:        
  131. ** 输 出:         
  132. ** 全局变量:
  133. ** 调用模块:
  134. ** 作 者:     吴鉴鹰
  135. ** 日 期:     14.03.5
  136. ************************************************************************************/
  137. void delay100us()
  138. {
  139. uchar  j;
  140. for(j=50;j>0;j--);
  141. }

  142. void Delay_1(uint num)    //延时函数
  143. {
  144. while( --num );
  145. }
  146. //*函数名:Init_DS18B20
  147. //功能:DS18B20初始化*//

  148. /**********************************************************************************
  149. ** 函数名称:  Init_DS18B20(void)
  150. ** 功能描述:  DS18B20初始化
  151. ** 输 入:         
  152. ** 输 出:         
  153. ** 全局变量:
  154. ** 调用模块:
  155. ** 作 者:     吴鉴鹰
  156. ** 日 期:     14.03.5
  157. ************************************************************************************/
  158. uchar Init_DS18B20(void)//初始化ds1820
  159. {
  160.      DS18B20_DQ_OUT = 1;      //DS18B20_DQ复位
  161.      Delay_1(8);              //稍做延时
  162.      DS18B20_DQ_OUT = 0;      //单片机将DS18B20_DQ拉低
  163.      Delay_1(90);             //精确延时 大于 480us
  164.      DS18B20_DQ_OUT = 1;      //拉高总线
  165.      Delay_1(8);
  166.      presence = DS18B20_DQ_OUT;   //如果=0则初始化成功 =1则初始化失败
  167.      Delay_1(100);
  168.      DS18B20_DQ_OUT = 1;
  169.      return(presence);        //返回信号,0=presence,1= no presence
  170. }
  171. /**********************************************************************************
  172. ** 函数名称:  ReadOneChar(void)
  173. ** 功能描述:  从18B20中读一个字节数据
  174. ** 输 入:         
  175. ** 输 出:         
  176. ** 全局变量:
  177. ** 调用模块:
  178. ** 作 者:     吴鉴鹰
  179. ** 日 期:     14.03.5
  180. ************************************************************************************/
  181. ReadOneChar(void)//读一个字节
  182. {
  183. unsigned char i = 0;
  184. unsigned char LCD_RW_OUT = 0;
  185. for (i = 8; i > 0; i--)
  186.     {
  187.      DS18B20_DQ_OUT = 0; // 给脉冲信号
  188.      LCD_RW_OUT >>= 1;
  189.      DS18B20_DQ_OUT = 1; // 给脉冲信号
  190.      if(DS18B20_DQ_OUT)
  191.        LCD_RW_OUT |= 0x80;
  192.      Delay_1(4);
  193.    }
  194.     return (LCD_RW_OUT);
  195. }
  196. /**********************************************************************************
  197. ** 函数名称:  WriteOneChar(uchar DAT)
  198. ** 功能描述:  写入一个字节数据
  199. ** 输 入:    DAT(送入的数字)     
  200. ** 输 出:         
  201. ** 全局变量:
  202. ** 调用模块:
  203. ** 作 者:     吴鉴鹰
  204. ** 日 期:     14.03.5
  205. ************************************************************************************/
  206. void WriteOneChar(uchar DAT)//写一个字节
  207. {
  208. unsigned char i = 0;
  209.    for (i = 8; i > 0; i--)
  210.    {
  211.      DS18B20_DQ_OUT = 0;
  212.      DS18B20_DQ_OUT = DAT&0x01;
  213.      Delay_1(5);
  214.      DS18B20_DQ_OUT = 1;
  215.      DAT>>=1;
  216.    }
  217. }
  218. /**********************************************************************************
  219. ** 函数名称:  Read_Temperature(void)
  220. ** 功能描述:  读取温度
  221. ** 输 入:         
  222. ** 输 出:         
  223. ** 全局变量:
  224. ** 调用模块:
  225. ** 作 者:     吴鉴鹰
  226. ** 日 期:     14.03.5
  227. ************************************************************************************/
  228. void Read_Temperature(void)             //读取温度
  229. {
  230. Init_DS18B20();
  231.    if(presence==1)
  232.     {
  233.   flash=1;                        //DS18B20不正常
  234. }      
  235.     else
  236.     {
  237.      flash=0;
  238.       WriteOneChar(0xCC);             // 跳过读序号列号的操作
  239.       WriteOneChar(0x44);             // 启动温度转换
  240.       Init_DS18B20();
  241.       WriteOneChar(0xCC);             //跳过读序号列号的操作
  242.       WriteOneChar(0xBE);             //读取温度寄存器
  243.       temp_data[0] = ReadOneChar();   //温度低8位
  244.       temp_data[1] = ReadOneChar();   //温度高8位
  245. }
  246. }
  247. /**********************************************************************************
  248. ** 函数名称:  void temp_all(void)
  249. ** 功能描述:  进行温度补偿
  250. ** 输 入:         
  251. ** 输 出:         
  252. ** 全局变量:
  253. ** 调用模块:
  254. ** 作 者:     吴鉴鹰
  255. ** 日 期:     14.03.5
  256. ************************************************************************************/
  257. void temp_all()
  258. {
  259.    Read_Temperature();
  260. display[4]=temp_data[0]&0x0f;
  261. display[0]=ditab[display[4]];          //查表得小数位的值
  262. display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);//温度整数值
  263. display[3]=display[4]/100;
  264. display[1]=display[4]%100;
  265. display[2]=display[1]/10;
  266. display[1]=display[1]%10;
  267. if(display[4]>50)         //温度高于50度,则不修正
  268. {
  269.   flash=1;                //表示测试的温度不正常
  270. }
  271. //*if((flash==0)&&(flag_1 == 0))
  272. //{
  273. // Disp_Temperature();
  274. //}*/
  275. if(flash==0)                         //温度传感器正常检测到温度并温度小于50度
  276. {
  277.   speed=(uint)(331+(display[4]*61+display[0]*6+45)/100);//声音的速度加上温度因素
  278. }
  279. }
  280. /**********************************************************************************
  281. ** 函数名称:  uint Distance_count()
  282. ** 功能描述:  距离计算函数
  283. ** 输 入:         
  284. ** 输 出:         
  285. ** 全局变量:
  286. ** 调用模块:
  287. ** 作 者:     吴鉴鹰
  288. ** 日 期:     14.03.5
  289. ************************************************************************************/
  290. void Distance_count()
  291. {
  292.          float temp1;
  293.          ulong  tt;
  294.          temp2 = high_time*256+low_time;
  295.          temp = high_time*256+low_time;
  296.       tt = (ulong)temp*344 ;
  297.          temp1 = (float)(tt/2000.0);
  298.          temp = (uint)(temp1);
  299.          temp = (uint)(temp1+0.5);
  300.          // return temp;
  301. }
  302. /**********************************************************************************
  303. ** 函数名称:  uint do_s(uint dis_1)
  304. ** 功能描述:  距离补偿函数
  305. ** 输 入:    uint dis_1      
  306. ** 输 出:    uint dis_1      
  307. ** 全局变量:
  308. ** 调用模块:
  309. ** 作 者:     吴鉴鹰
  310. ** 日 期:     14.03.5
  311. ************************************************************************************/
  312. uint do_s(uint dis_1)
  313. {
  314. uchar n;
  315. if((dis_1>70)&(dis_1<100))
  316. {
  317.   n = dis_1/10;
  318.   switch(n)
  319.   {
  320.    case 7:dis_1-=40;break;
  321.    case 8:dis_1-=22;break;
  322.    case 9:dis_1-=26;break;
  323.   }
  324.   return(dis_1);
  325. }
  326. else
  327. {
  328.   n = dis_1/100;
  329.   switch(n)
  330.   {
  331.    case 1:dis_1-=43;break;
  332.    case 2:dis_1-=42;break;
  333.    case 3:dis_1-=34;break;
  334.    case 4:dis_1-=30;break;
  335.    case 5:dis_1-=32;break;
  336.    case 6:dis_1-=31;break;
  337.    case 7:dis_1-=28;break;
  338.    case 8:dis_1-=29;break;
  339.    case 9:dis_1-=34;break;
  340.    case 10:dis_1-=34;break;
  341.    case 11:dis_1-=34;break;
  342.    case 12:dis_1-=35;break;
  343.    case 13:dis_1-=30;break;
  344.    case 14:dis_1-=35;break;   
  345.    case 15:dis_1-=46;break;
  346.    case 16:dis_1-=46;break;
  347.    case 17:dis_1-=39;break;
  348.    case 18:dis_1-=36;break;
  349.    case 19:dis_1-=37;break;
  350.    case 20:dis_1-=32;break;
  351.    case 21:dis_1-=33;break;
  352.    case 22:dis_1-=34;break;
  353.    case 23:dis_1-=38;break;
  354.    case 24:dis_1-=40;break;
  355.    case 25:dis_1-=35;break;
  356.    case 26:dis_1-=35;break;
  357.    case 27:dis_1-=37;break;
  358.    case 28:dis_1-=62;break;
  359.    case 29:dis_1-=64;break;
  360.    case 30:dis_1-=68;break;
  361.    case 31:dis_1-=64;break;
  362.    case 32:dis_1-=256;break;
  363.    case 33:dis_1-=262;break;
  364.    case 34:dis_1-=268;break;
  365.    case 35:dis_1-=271;break;
  366.    case 36:dis_1-=282;break;
  367.    case 37:dis_1-=290;break;
  368.    case 38:dis_1-=302;break;
  369.    case 39:dis_1-=332;break;
  370.    case 40:dis_1-=352;break;
  371.    case 41:dis_1-=350;break;
  372.    case 42:dis_1-=367;break;
  373.    case 43:dis_1-=285;break;
  374.    case 44:dis_1-=350;break;
  375.    case 45:dis_1-=290;break;
  376.    case 46:dis_1-=295;break;
  377.             case 47:dis_1-=295;break;
  378.             case 48:dis_1-=374;break;
  379.    case 49:dis_1-=395;break;
  380.    case 50:dis_1-=395;break;
  381.             case 51:dis_1-=405;break;
  382.             case 52:dis_1-=425;break;
  383.             case 53:dis_1-=394;break;
  384.    case 54:dis_1-=395;break;
  385.    case 55:dis_1-=495;break;
  386.   }
  387. return(dis_1);
  388. }
  389. }
  390. /**********************************************************************************
  391. ** 函数名称:  void tran(),void tran1(),void tran2()
  392. ** 功能描述:  超声波的发射
  393. ** 输 入:         
  394. ** 输 出:         
  395. ** 全局变量:
  396. ** 调用模块:
  397. ** 作 者:     吴鉴鹰
  398. ** 日 期:     14.03.5
  399. ************************************************************************************/
  400. void tran()
  401. {
  402. uchar i;
  403. TH0=0;
  404. TL0=0;
  405. TR0=1;
  406. for(i=4;i>0;i--)
  407. {
  408.   LS2_csb_OUT=!LS2_csb_OUT;
  409.   nop;
  410.   nop;
  411.   nop;
  412.   nop;
  413.   nop;
  414.   nop;
  415.   nop;
  416.   nop;
  417.   nop;
  418. }
  419. LS2_csb_OUT=1;
  420. delay_ms(1);
  421. EX1=1;
  422. delay_ms(30);
  423. if(flag==1)
  424. {
  425.   Distance_count();
  426.         dis=temp;
  427.   flag=0;
  428. }
  429. else dis=0;
  430. }
  431. /**********************************************************************************
  432. ** 函数名称:  void tran(),void tran1(),void tran2()
  433. ** 功能描述:  超声波的发射
  434. ** 输 入:         
  435. ** 输 出:         
  436. ** 全局变量:
  437. ** 调用模块:
  438. ** 作 者:     吴鉴鹰
  439. ** 日 期:     14.03.5
  440. ************************************************************************************/
  441. void tran1()
  442. {
  443. uchar i;
  444. TH0=0;
  445. TL0=0;
  446. TR0=1;
  447. for(i=20;i>0;i--)
  448. {
  449.   LS2_csb_OUT=!LS2_csb_OUT;
  450.   nop;
  451.   nop;
  452.   nop;
  453.   nop;
  454.   nop;
  455.   nop;
  456.   nop;
  457.   nop;
  458.   nop;
  459. }
  460. LS2_csb_OUT=1;
  461. delay_ms(2);
  462. EX1=1;
  463. delay_ms(50);
  464. if(flag==1)
  465. {  
  466.      Distance_count();
  467.   dis = temp;
  468.   flag=0;
  469.     }
  470. else dis=0;
  471. }
  472. /**********************************************************************************
  473. ** 函数名称:  void tran(),void tran1(),void tran2()
  474. ** 功能描述:  超声波的发射
  475. ** 输 入:         
  476. ** 输 出:         
  477. ** 全局变量:
  478. ** 调用模块:
  479. ** 作 者:     吴鉴鹰
  480. ** 日 期:     14.03.5
  481. ************************************************************************************/
  482. void tran2()
  483. {
  484. uchar i;
  485. TH0=0;
  486. TL0=0;
  487. TR0=1;
  488. for(i=16;i>0;i--)
  489. {
  490.   LS2_csb_OUT=!LS2_csb_OUT;
  491.   nop;
  492.   nop;
  493.   nop;
  494.   nop;
  495.   nop;
  496.   nop;
  497.   nop;
  498.   nop;
  499.   nop;
  500. }
  501. LS2_csb_OUT=1;
  502. delay_ms(20);
  503. EX1=1;
  504. delay_ms(150);
  505. if(flag==1)
  506. {
  507.   Distance_count();
  508.      dis=temp;
  509.   flag=0;
  510. }
  511. else
  512. {
  513.   dis=0;
  514. }
  515. }

  516. /**********************************************************************************
  517. ** 函数名称:  void fit_1(void)
  518. ** 功能描述:  取最大值
  519. ** 输 入:         
  520. ** 输 出:         
  521. ** 全局变量:
  522. ** 调用模块:
  523. ** 作 者:     吴鉴鹰
  524. ** 日 期:     14.03.5
  525. ************************************************************************************/
  526. void fit_1(void)
  527. {
  528. uint h;
  529. uchar m,k,p;
  530. for(m=0;m<7;m++)       //以下语句为冒泡法排序
  531. {
  532.      for(k=0;k<=8-m;k++)
  533.   {
  534.    if(dis_4[k]>dis_4[k+1])
  535.    {
  536.     h=dis_4[k];
  537.     dis_4[k]=dis_4[k+1];
  538.     dis_4[k+1]=h;
  539.    }
  540.   }
  541. }
  542. dis =(dis_4[3]+dis_4[4]+dis_4[5])/3;
  543. p=0;
  544. }
  545. /**********************************************************************************
  546. ** 函数名称:  void send( char B )
  547. ** 功能描述:  串口发送程序
  548. ** 输 入:         
  549. ** 输 出:         
  550. ** 全局变量:
  551. ** 调用模块:
  552. ** 作 者:     吴鉴鹰
  553. ** 日 期:     14.03.5
  554. ************************************************************************************/
  555. void send( char B ) //发送一个字节
  556. {
  557. SBUF=B;
  558.     while(!TI);
  559. TI=0;
  560. }
  561. /**********************************************************************************
  562. ** 函数名称:  void USART_init(void)
  563. ** 功能描述:  播放“测量距离"
  564. ** 输 入:    uint dis_say(测得的距离)   
  565. ** 输 出:         
  566. ** 全局变量:
  567. ** 调用模块:
  568. ** 作 者:     吴鉴鹰
  569. ** 日 期:     14.03.5
  570. ************************************************************************************/
  571. void USART_init(void) //串口的初始化
  572. {
  573. TH1=0xfd;
  574. TL1=0xfd;
  575. TR1=1;
  576. SM0=0;
  577. SM1=1;
  578. REN=1;
  579. }
  580. /**********************************************************************************
  581. ** 函数名称:  void main(void)
  582. ** 功能描述:  主函数
  583. ** 输 入:         
  584. ** 输 出:         
  585. ** 全局变量:
  586. ** 调用模块:
  587. ** 作 者:     吴鉴鹰
  588. ** 日 期:     14.03.5
  589. ************************************************************************************/
  590. void main(void)
  591. {
  592. unsigned char i,j,TEST;
  593. P0 = 0xff;
  594. P1 = 0xff;
  595. P2 = 0xff;
  596.   TMOD=0x01;
  597. TH0=0;
  598. TL0=0;
  599. EA=1;
  600. IE=0x80;
  601.     IT1=0;
  602. USART_init();
  603. while(1)
  604. {
  605.         if(tc_say==4)
  606.   {
  607.              temp_all();
  608.     tc_say=0;
  609.   }
  610.   tc_say++;
  611.   for(i=0;i<9;i++)
  612.   {
  613.     IE=0x80;
  614.     tran1();
  615.     dis= do_s(dis);
  616.              dis_4=dis;
  617.   }
  618.   fit_1();
  619.   Send[2] = dis>>8;
  620.   Send[3] = dis;
  621.   
  622.   if( flag == 1 )
  623.   {   
  624.    ES=0;
  625.    i=0;
  626.    Send[0] = temp_data[0];
  627.    Send[1] = temp_data[1];
  628.    
  629.    TEST = Send[0];
  630.    for(i = 1; i < 4;i ++)
  631.    {
  632.       TEST = TEST&Send;  //这是发送的数据取&得到的数据作为第八位,也就是吴鉴鹰定义的检验位
  633.    }
  634.    Send[4] = TEST;
  635.    for(i=0;i<4;i++)
  636.    {
  637.      send(Send);        //发送数据
  638.    }
  639.    //Num=0;
  640.    flag=0;
  641.    ES=1;
  642.   }
  643.      /*if(dis<time)
  644.   {
  645.   if((time-dis)>4000)  time=time-1000;
  646.   else
  647.   {
  648.   if((time-dis)<2500) time=dis;
  649.   else        time=time-100;
  650.   }
  651.   }
  652.   else*/
  653.   /*dis_all(dis);
  654.   dis=0;
  655.   lcd_pos(1,6);
  656.   for(j=0;j<4;j++)
  657.   write(1,space4[j]);
  658.   lcd_pos(1,6);
  659.   for(j=0;j<4;j++)
  660.   {
  661.   write(1,point4[j]);
  662.   delay(100);
  663.   }*/
  664. }
  665. }
  666. /**********************************************************************************
  667. ** 函数名称:  void TT() interrupt 2
  668. ** 功能描述:  中断,产生脉冲
  669. ** 输 入:         
  670. ** 输 出:         
  671. ** 全局变量:
  672. ** 调用模块:
  673. ** 作 者:     吴鉴鹰
  674. ** 日 期:     14.03.5
  675. ************************************************************************************/
  676. void TT() interrupt 2
  677. {
  678. TR0=0;
  679.     ET1=0;
  680. flag=1;
  681. high_time = TH0;
  682. low_time = TL0;
  683.     TR0=0;
  684. }

  685.          


复制代码



为了方便大家交流,建了两个QQ群:QQ群3号:198387118  【1000人群】QQ群5号: 239316959【2000人群】群内已有成员3000余人!
更多内容关注微信公众号:单片机精讲吴鉴鹰

回复

使用道具 举报

364

TA的帖子

0

TA的资源

纯净的硅(初级)

Rank: 4

 楼主| 发表于 2014-6-17 20:20 | 显示全部楼层
本帖最后由 吴鉴鹰. 于 2014-6-17 20:22 编辑

                                      12、吴鉴鹰单片机实战项目精讲(连载)之超声波测距仪设计(三)——从机程序

  1. /**********************************************************************************
  2. ** 函数名称: 从机程序
  3. ** 功能描述: LCD12864的显示,语音播报模块的启动
  4. ** 输 入:
  5. ** 输 出:
  6. ** 全局变量:
  7. ** 调用模块:
  8. ** 作 者: 吴鉴鹰
  9. ** 日 期: 14.03.5
  10. ************************************************************************************/
  11. //*包含头文件*//
  12. #include<reg52.h>
  13. #include<stdio.h>
  14. #include<math.h>
  15. #include<intrins.h>
  16. #define uchar unsigned char
  17. #define uint unsigned int
  18. #define ufloat unsigned float
  19. #define ulong unsigned long
  20. #define NOP _nop_();_nop_();_nop_()
  21. #define nop _nop_()
  22. //*常量定义*//
  23. #define KEY_circle_IN 0xf2//循环播放
  24. #define KEY_stopplay_IN 0xfe//停止播放
  25. #define adjust_volice_0 0xe0//调节音量1
  26. #define adjust_volice_1 0xe1//调节音量2
  27. #define adjust_volice_2 0xe2//调节音量3
  28. #define adjust_volice_3 0xe3//调节音量4
  29. #define adjust_volice_4 0xe4//调节音量5
  30. #define adjust_volice_5 0xe5//调节音量6
  31. #define adjust_volice_6 0xe6//调节音量7
  32. #define adjust_volice_7 0xe7//调节音量8
  33. uchar vo_vo=0xe7;
  34. uchar Num;
  35. uchar flag_2;
  36. uchar flag;
  37. //*程序功能:ST7920控制芯片(汉字库),串口模式。12864 图片与文字显示*//
  38. uchar code DIS1[] = {"超声波测距中...."};
  39. uchar code DIS3[] = {"距障碍物: . m"};
  40. uchar code DIS4[] = {"测距情况: 安全 "};
  41. uchar code DIS5[] = {"测距情况: 请保持"};
  42. uchar code DIS6[] = {"测距情况: 危险!!"};
  43. uchar code DIS8[] = {" "};
  44. uchar code DIS9[] = {"超声波倒车测距仪"};
  45. uchar code DIS10[]= {" V1.0 2008.12.4 "};
  46. uchar point4[];
  47. uchar space4[];
  48. unsigned int dis;
  49. unsigned char DIS_receive_data[3];
  50. unsigned char display_TEMP_DATA[5]={0x00,0x00,0x00,0x00,0x00};
  51. unsigned char dist_test_DATA[5]={0x00,0x00,0x00,0x00,0x00};

  52. //*位定义*//
  53. sbit LCD_RST_OUT = P1^4; //LCDLCD_RST_OUT
  54. sbit LCD_RS_OUT = P1^1;//片选端 RS
  55. sbit LCD_CLK_OUT = P1^2;//时钟 SLCD_CLK_OUT
  56. sbit LCD_RW_OUT = P1^3;//数据位 RW
  57. sbit WT_busy_OUT = P1^0;//忙信号
  58. sbit LED_green_OUT=P2^4;
  59. sbit LED_yellow_OUT=P2^5;
  60. sbit LED_red_OUT=P2^5;

  61. /**********************************************************************************
  62. ** 函数名称: void delay_nms(uint ms)
  63. ** 功能描述: 延时n个ms函数
  64. ** 输 入:
  65. ** 输 出:
  66. ** 全局变量:
  67. ** 调用模块:
  68. ** 作 者: 吴鉴鹰
  69. ** 日 期: 14.03.5
  70. ************************************************************************************/
  71. void delay_nms(uint ms) //delay ms function
  72. {
  73. uchar i;
  74. while(ms--)
  75. {
  76. for(i = 0; i < 123; i++);
  77. }
  78. }
  79. /**********************************************************************************
  80. ** 函数名称: void delay(int ms)
  81. ** 功能描述: 延时函数n毫秒
  82. ** 输 入:
  83. ** 输 出:
  84. ** 全局变量:
  85. ** 调用模块:
  86. ** 作 者: 吴鉴鹰
  87. ** 日 期: 14.03.5
  88. ************************************************************************************/
  89. void delay(int ms)
  90. {
  91. while(ms--)
  92. {
  93. uchar i;
  94. for(i=0;i<246;i++)
  95. {
  96. _nop_();
  97. _nop_(); _nop_();
  98. _nop_();
  99. }
  100. }
  101. }
  102. /**********************************************************************************
  103. ** 函数名称: void delay_lcd(int ms)
  104. ** 功能描述: 延时函数200us
  105. ** 输 入:
  106. ** 输 出:
  107. ** 全局变量:
  108. ** 调用模块:
  109. ** 作 者: 吴鉴鹰
  110. ** 日 期: 14.03.5
  111. ************************************************************************************/
  112. void delay_lcd(int ms)
  113. {
  114. uchar t;
  115. while(ms--)
  116. {
  117. for(t=0; t<20; t++) ;
  118. }
  119. }
  120. /**********************************************************************************
  121. ** 函数名称: void sendbyte(uchar bbyte)
  122. ** 功能描述: 向LCD12864液晶数据位发送一个字节
  123. ** 输 入:
  124. ** 输 出:
  125. ** 全局变量:
  126. ** 调用模块:
  127. ** 作 者: 吴鉴鹰
  128. ** 日 期: 14.03.5
  129. ************************************************************************************/
  130. void sendbyte(uchar bbyte)
  131. {
  132. uchar i;
  133. for(i=0;i<8;i++)
  134. {
  135. LCD_RW_OUT = bbyte&0x80; //取出最高位
  136. LCD_CLK_OUT = 1;
  137. _nop_();
  138. _nop_();
  139. LCD_CLK_OUT=0;
  140. bbyte<<=1; //左移
  141. }
  142. }
  143. /**********************************************************************************
  144. ** 函数名称: void write(bit start, uchar ddata)
  145. ** 功能描述: 向LCD12864液晶写指令或数据函数
  146. ** 输 入:
  147. ** 输 出:
  148. ** 全局变量:
  149. ** 调用模块:
  150. ** 作 者: 吴鉴鹰
  151. ** 日 期: 14.03.5
  152. ************************************************************************************/
  153. void write(bit start, uchar ddata)
  154. {
  155. uchar start_data,Hdata,Ldata;
  156. if(start==0) //11111,(0),(0),0
  157. {
  158. start_data=0xf8; //写指令
  159. }
  160. else //11111,(0),(1),0
  161. {
  162. start_data=0xfa; //写数据
  163. } //
  164. //  //Hdata = ddata & 0xf0; //取高四位 Hdata = ddata&0xf0;
  165. Ldata = (ddata<<4)&0xf0; //取低四位
  166. sendbyte(start_data); //发送起始信号
  167. delay_lcd(1); //延时
  168. sendbyte(Hdata); //发送高四位
  169. delay_lcd(1); //延时
  170. sendbyte(Ldata); //发送低四位
  171. delay_lcd(1); //延时
  172. }
  173. /**********************************************************************************
  174. ** 函数名称: void lcd_pos(uchar X,uchar Y)
  175. ** 功能描述: 设定显示位置
  176. ** 输 入: uchar X,uchar Y
  177. ** 输 出:
  178. ** 全局变量:
  179. ** 调用模块:
  180. ** 作 者: 吴鉴鹰
  181. ** 日 期: 14.03.5
  182. ************************************************************************************/
  183. void lcd_pos(uchar X,uchar Y)
  184. {
  185. uchar pos;
  186. if (X==1)
  187. {
  188. X=0x80;
  189. }
  190. else
  191. if (X==2)
  192. {
  193. X=0x90;
  194. }
  195. else
  196. if (X==3)
  197. {
  198. X=0x88;
  199. }
  200. else
  201. if (X==4)
  202. {
  203. X=0x98;
  204. }
  205. pos = X+Y ;
  206. write(0,pos); //lcd_wcmd(pos); //写位置命令
  207. }
  208. /**********************************************************************************
  209. ** 函数名称: show(uint ss)
  210. ** 功能描述: 显示测试数据
  211. ** 输 入: uint ss
  212. ** 输 出:
  213. ** 全局变量:
  214. ** 调用模块:
  215. ** 作 者: 吴鉴鹰
  216. ** 日 期: 14.03.5
  217. ************************************************************************************/
  218. void show(uint ss)
  219. {
  220. uchar data_s[2],i;
  221. data_s[0]=ss/10000; //数据的处理
  222. if(data_s[0]==0) //测量数据的十米位为0
  223. {
  224. data_s[0]=0x20;
  225. }
  226. else
  227. {
  228. data_s[0]=data_s+0x30; //
  229. }
  230. data_s[1]=ss%10000/1000+0x30;
  231. lcd_pos(3,5); //第三行,第七个(2*n+1)字节位置显示
  232. write(1,data_s[1]); //for(i=0;i<2;i++)
  233. //{
  234. // write(1,data_s); //lcd_wdat(data_s); //显示米位数据
  235. //delay(1);
  236. // }
  237. data_s[0]=ss%1000/100+0x30;
  238. data_s[1]=ss%100/10+0x30;
  239. lcd_pos(3,6);
  240. for(i=0;i<2;i++)
  241. {
  242. write(1,data_s); //lcd_wdat(data_s); //显示分米和厘米位数据
  243. delay(1);
  244. }
  245. write(1,ss%10+0x30); //lcd_wdat(ss%10+0x30); //显示毫米位数据
  246. delay(1);
  247. }
  248. /**********************************************************************************
  249. ** 函数名称: void lcd_init()
  250. ** 功能描述: 初始化LCD
  251. ** 输 入:
  252. ** 输 出:
  253. ** 全局变量:
  254. ** 调用模块:
  255. ** 作 者: 吴鉴鹰
  256. ** 日 期: 14.03.5
  257. ************************************************************************************/
  258. void lcd_init()
  259. {
  260. delay_lcd(10); //延时等待LCM进入工作状态
  261. LCD_RS_OUT=1; //片选 高电平有效
  262. write(0,0x30); //基本指令操作
  263. write(0,0x0c); //显示打开,光标关,反白关
  264. write(0,0x01); //清屏,将DDRAM的地址计数器归零
  265. write(0,0x06);
  266. }
  267. /**********************************************************************************
  268. ** 函数名称: void photodisplay(uchar *bmp)
  269. ** 功能描述: uchar *bmp
  270. ** 输 入:
  271. ** 输 出:
  272. ** 全局变量:
  273. ** 调用模块:
  274. ** 作 者: 吴鉴鹰
  275. ** 日 期: 14.03.5
  276. ************************************************************************************/
  277. void photodisplay(uchar *bmp)
  278. {
  279. uchar i,j;
  280. write(0,0x34); //写数据时,关闭图形显示
  281. for(i=0;i<32;i++)
  282. {
  283. write(0,0x80+i); //先写入水平坐标值
  284. write(0,0x80); //写入垂直坐标值
  285. for(j=0;j<16;j++) //再写入两个8位元的数据
  286. write(1,*bmp++);
  287. delay_lcd(1);
  288. }
  289. for(i=0;i<32;i++)
  290. {
  291. write(0,0x80+i);
  292. write(0,0x88);
  293. for(j=0;j<16;j++)
  294. write(1,*bmp++);
  295. delay_lcd(1);
  296. }
  297. write(0,0x36); //写完数据,开图形显示
  298. }
  299. /**********************************************************************************
  300. ** 函数名称: void clr_screen()
  301. ** 功能描述: LCD清屏函数
  302. ** 输 入:
  303. ** 输 出:
  304. ** 全局变量:
  305. ** 调用模块:
  306. ** 作 者: 吴鉴鹰
  307. ** 日 期: 14.03.5
  308. ************************************************************************************/
  309. void clr_screen()
  310. {
  311. write(0,0x34); //lcd_wcmd(0x34); //扩充指令操作
  312. delay(5);
  313. write(0,0x30); //lcd_wcmd(0x30); //基本指令操作
  314. delay(5);
  315. write(0,0x01); //lcd_wcmd(0x01); //清屏
  316. delay(5);
  317. }
  318. /**********************************************************************************
  319. ** 函数名称: void displayall()
  320. ** 功能描述: 主显示函数
  321. ** 输 入:
  322. ** 输 出:
  323. ** 全局变量:
  324. ** 调用模块:
  325. ** 作 者: 吴鉴鹰
  326. ** 日 期: 14.03.5
  327. ************************************************************************************/
  328. void displayall()
  329. {
  330. uchar i;
  331. delay(2);
  332. lcd_init(); //初始化LCD
  333. lcd_pos(2,0); //设置显示位置为第二行
  334. for(i=0;i<16;i++)
  335. {
  336. write(1,DIS9); //lcd_wLCD_RW_OUT(DIS9);
  337. delay(30);
  338. }
  339. lcd_pos(3,0); //设置显示位置为第三行
  340. for(i=0;i<16;i++)
  341. {
  342. write(1,DIS10); //lcd_wLCD_RW_OUT(DIS10);
  343. delay(30);
  344. }
  345. delay(1000);
  346. clr_screen(); //清屏
  347. delay(500);
  348. clr_screen(); //上电,等待稳定
  349. lcd_pos(1,0); //设置显示位置为第一行
  350. for(i=0;i<16;i++)
  351. {
  352. write(1,DIS1); //lcd_wLCD_RW_OUT(DIS1);
  353. delay(2);
  354. }
  355. lcd_pos(3,0); //设置显示位置为第三行
  356. for(i=0;i<16;i++)
  357. {
  358. write(1,DIS3); //lcd_wLCD_RW_OUT(DIS3);
  359. delay(2);
  360. }
  361. lcd_pos(4,0); //设置显示位置为第四行
  362. for(i=0;i<16;i++)
  363. {
  364. write(1,DIS8); //lcd_wLCD_RW_OUT(DIS8);
  365. delay(2);
  366. }
  367. delay(1000);
  368. }
  369. /**********************************************************************************
  370. ** 函数名称: void show_one(uchar DIS[8],uchar hh)
  371. ** 功能描述: 设置行显示
  372. ** 输 入: uchar DIS[16],uchar hh
  373. ** 输 出:
  374. ** 全局变量:
  375. ** 调用模块:
  376. ** 作 者: 吴鉴鹰
  377. ** 日 期: 14.03.5
  378. ************************************************************************************/
  379. void show_one(uchar DIS[16],uchar hh)
  380. {
  381. uchar i;
  382. lcd_pos(hh,0); //设置显示位置行
  383. for(i=0;i<16;i++)
  384. {
  385. write(1,DIS); //lcd_wLCD_RW_OUT(DIS);
  386. delay(1);
  387. }
  388. }
  389. /**********************************************************************************
  390. ** 函数名称: void send_com(uchar add)
  391. ** 功能描述: 发码播放,add为语音地址
  392. ** 输 入: uchar add
  393. ** 输 出:
  394. ** 全局变量:
  395. ** 调用模块:
  396. ** 作 者: 吴鉴鹰
  397. ** 日 期: 14.03.5
  398. ************************************************************************************/
  399. void send_com(uchar add)
  400. {
  401. uchar i;
  402. LCD_RST_OUT=1;
  403. LCD_RST_OUT=0;
  404. delay_nms(3);
  405. LCD_RST_OUT=1;
  406. delay_nms(20);
  407. LCD_RS_OUT=0;
  408. delay_nms(5);
  409. for(i=0;i<8;i++)
  410. {
  411. LCD_CLK_OUT=0;
  412. if(add&1) LCD_RW_OUT=1;
  413. else LCD_RW_OUT=0;
  414. delay100us();
  415. LCD_CLK_OUT=1;
  416. delay100us();
  417. add=add>>1;
  418. }
  419. LCD_RS_OUT=1;
  420. }
  421. /**********************************************************************************
  422. ** 函数名称: void sound(uint soud)
  423. ** 功能描述: 播报测距距离
  424. ** 输 入: soud
  425. **
  426. **
  427. ** 输 出:
  428. **
  429. ** 全局变量:
  430. ** 调用模块:
  431. **
  432. ** 作 者: 吴鉴鹰
  433. ** 日 期: 14.03.5
  434. ************************************************************************************/
  435. void sound(uint soud)
  436. {
  437. uchar i,j,k,l;
  438. send_com(vo_vo);
  439. while(!WT_busy_OUT);
  440. i=soud/1000;
  441. j=soud%1000/100;
  442. k=soud%100/10;
  443. l=soud%10;
  444. send_com(i);
  445. delay_nms(30);
  446. while(!WT_busy_OUT);
  447. send_com(10); //播放“点”
  448. delay_nms(30);
  449. while(!WT_busy_OUT);
  450. send_com(j);
  451. delay_nms(30);
  452. while(!WT_busy_OUT);
  453. send_com(k);
  454. delay_nms(30);
  455. while(!WT_busy_OUT);
  456. if(l!=0)
  457. {
  458. send_com(l);
  459. delay_nms(30);
  460. while(!WT_busy_OUT);
  461. }
  462. send_com(11); //播放"米"
  463. delay_nms(30);
  464. while(!WT_busy_OUT);
  465. }
  466. /**********************************************************************************
  467. ** 函数名称: void dis_all(uint dis_s)
  468. ** 功能描述: 控制LED指示灯和语音播报
  469. ** 输 入: uint dis_s
  470. ** 输 出:
  471. ** 全局变量:
  472. ** 调用模块:
  473. ** 作 者: 吴鉴鹰
  474. ** 日 期: 14.03.5
  475. ************************************************************************************/
  476. void dis_all(uint dis_s)
  477. {
  478. show(dis_s);
  479. if(dis_s>2000)
  480. {
  481. show_one(DIS4,2);
  482. LED_green_OUT=0;LED_red_OUT=1;LED_yellow_OUT=1;
  483. if(flag_2!=1)
  484. {
  485. }
  486. flag_2=1;
  487. }
  488. else
  489. {
  490. if((dis_s>500)&(dis_s<1000))
  491. {
  492. show_one(DIS5,2);
  493. LED_green_OUT=1;LED_red_OUT=1;LED_yellow_OUT=0;
  494. if(flag_2!=2)
  495. {
  496. }
  497. flag_2=2;
  498. }
  499. else
  500. {
  501. if((dis_s>100)&(dis_s<500))
  502. {
  503. show_one(DIS6,2);
  504. LED_green_OUT=1;LED_red_OUT=0;LED_yellow_OUT=1;
  505. if(flag_2!=3)
  506. {
  507. }
  508. flag_2=3;
  509. }
  510. else
  511. {
  512. show_one(DIS8,2);
  513. LED_yellow_OUT=1;
  514. if(dis_s<100)
  515. { LED_red_OUT=!LED_red_OUT;LED_green_OUT=1;}
  516. else
  517. {LED_green_OUT=!LED_green_OUT;LED_red_OUT=1;}
  518. }
  519. }
  520. }
  521. }
  522. /**********************************************************************************
  523. ** 函数名称: void Disp_Temperature()
  524. ** 功能描述: 显示温度
  525. ** 输 入:
  526. ** 输 出:
  527. ** 全局变量:
  528. ** 调用模块:
  529. ** 作 者: 吴鉴鹰
  530. ** 日 期: 14.03.5
  531. ************************************************************************************/
  532. void Disp_Temperature()//显示温度
  533. {
  534. unsigned char n=0, word[16]={"环境温度: ℃"};
  535. show_one(word,4);
  536. for(n=0;n<16;n++)
  537. write(1,word[n]);
  538. lcd_pos(4,5); //设置显示位置为第三行
  539. if(display_TEMP_DATA[3] != 0)
  540. write(1,display_TEMP_DATA[3]+0x30); //lcd_wdat(display_TEMP_DATA[3]+0x30); //温度值百位不显示
  541. else
  542. write(1,0x20); //lcd_wdat(0x20); */
  543. delay(1);
  544. if((display_TEMP_DATA[3]==0)&&(display_TEMP_DATA[2]==0))
  545. {
  546. write(1,0x20); //lcd_wdat(0x20);
  547. }
  548. else
  549. {
  550. write(1,display_TEMP_DATA[2]+0x30); //lcd_wdat(display_TEMP_DATA[2]+0x30);
  551. }
  552. delay(1);
  553. write(1,display_TEMP_DATA[1]+0x30); //lcd_wdat(display_TEMP_DATA[1]+0x30);
  554. delay(1);
  555. write(1,'.'); //lcd_wdat('.');
  556. delay(1);
  557. write(1,display_TEMP_DATA[0]+0x30); //lcd_wdat(display_TEMP_DATA[0]+0x30);
  558. delay(1);
  559. }
  560. /**********************************************************************************
  561. ** 函数名称: void soundplay(uint dis_say)
  562. ** 功能描述: 播放“测量距离"
  563. ** 输 入: uint dis_say(测得的距离)
  564. ** 输 出:
  565. ** 全局变量:
  566. ** 调用模块:
  567. ** 作 者: 吴鉴鹰
  568. ** 日 期: 14.03.5
  569. ************************************************************************************/
  570. void soundplay(uint dis_say)
  571. {
  572. if(WT_busy_OUT != 0)
  573. {
  574. sound(dis_say);//播放“测量距离”
  575. }
  576. }
  577. /**********************************************************************************
  578. ** 函数名称: void USART_init(void)
  579. ** 功能描述: 播放“测量距离"
  580. ** 输 入: uint dis_say(测得的距离)
  581. ** 输 出:
  582. ** 全局变量:
  583. ** 调用模块:
  584. ** 作 者: 吴鉴鹰
  585. ** 日 期: 14.03.5
  586. ************************************************************************************/
  587. void USART_init(void) //串口的初始化
  588. {
  589. TH1=0xfd;
  590. TL1=0xfd;
  591. TR1=1;
  592. SM0=0;
  593. SM1=1;
  594. REN=1;
  595. }
  596. /**********************************************************************************
  597. ** 函数名称: void dists_data_mov(uchar dat)
  598. ** 功能描述: 将受到的数值转换成LCD12864能显示的数据,存放到相应的数组中,dist_test_DATA为距离的
  599. display_TEMP_DATA为温度数组
  600. ** 输 入: uint dat
  601. ** 输 出:
  602. ** 全局变量:
  603. ** 调用模块:
  604. ** 作 者: 吴鉴鹰
  605. ** 日 期: 14.03.5
  606. ************************************************************************************/
  607. void dists_data_mov(uchar dat)
  608. {
  609. if(dat == 1)
  610. {
  611. point4[0] = ((uint)(dist_test_DATA[0]<<8 + dist_test_DATA[1]))/10000;
  612. point4[1] = ((uint)(dist_test_DATA[0]<<8+ dist_test_DATA[1]))/1000%10;
  613. point4[2] = ((uint)(dist_test_DATA[0]<<8+ dist_test_DATA[1]))/100%10;
  614. point4[3] = ((uint)(dist_test_DATA[0]<<8+ dist_test_DATA[1]))/10%10;
  615. point4[4] = ((uint)(dist_test_DATA[0]<<8+ dist_test_DATA[1]))%10;
  616. }
  617. else
  618. {
  619. space4[0] = ((uint)display_TEMP_DATA[2]<<8+ display_TEMP_DATA[3])/10000;
  620. space4[1] = ((uint)display_TEMP_DATA[2]<<8+ display_TEMP_DATA[3])/1000%10;
  621. space4[2] = ((uint)display_TEMP_DATA[2]<<8+ display_TEMP_DATA[3])/100%10;
  622. space4[3] = ((uint)display_TEMP_DATA[2]<<8+ display_TEMP_DATA[3])/10%10;
  623. space4[4] = ((uint)display_TEMP_DATA[2]<<8+ display_TEMP_DATA[3])%10;
  624. }
  625. }

  626. /**********************************************************************************
  627. ** 函数名称: void soundplay(uint dis_say)
  628. ** 功能描述: 播放“测量距离"
  629. ** 输 入: uint dis_say(测得的距离)
  630. ** 输 出:
  631. ** 全局变量:
  632. ** 调用模块:
  633. ** 作 者: 吴鉴鹰
  634. ** 日 期: 14.03.5
  635. ************************************************************************************/
  636. void main(void)
  637. {
  638. uchar i,j;
  639. P0 = 0xff;
  640. P1 = 0xff;
  641. P2 = 0xff;
  642. TMOD=0x21;
  643. TH0=0;
  644. TL0=0;
  645. EA=1;
  646. IE=0x90;
  647. IT1=0;
  648. USART_init(); //串口的初始化
  649. Num = 0;
  650. while(1)
  651. {
  652. //* if(tc_say==4)
  653. //{
  654. //temp_all(); 温度补偿
  655. //tc_say=0;
  656. //}*/
  657. /*tc_say++;
  658. //for(i=0;i<9;i++)
  659. //{
  660. // IE=0x80;
  661. // tran1();
  662. // dis = do_s(dis);
  663. // dis_4 = dis;
  664. //}
  665. //fit_1();*/
  666. //*if(dis<time)
  667. //{
  668. //if((time-dis)>4000) time=time-1000;
  669. //else
  670. //{
  671. // if((time-dis)<2500) time=dis;
  672. // else time=time-100;
  673. //}
  674. //}
  675. //else*/

  676. Disp_Temperature();//温度显示
  677. dists_data_mov(0); //温度示数转换
  678. dists_data_mov(1); //距离示数转换
  679. dis_all(dis); //语音播报
  680. dis=0;
  681. lcd_pos(1,6); //设定显示位置
  682. for(j=0;j<4;j++)
  683. write(1,space4[j]);
  684. lcd_pos(1,6); //设定显示位置
  685. for(j=0;j<4;j++)
  686. {
  687. write(1,point4[j]);
  688. delay(100);
  689. }
  690. }
  691. }
  692. /**********************************************************************************
  693. ** 函数名称: void ser() interrupt 4
  694. ** 功能描述: 串口中断接收数据
  695. ** 输 入:
  696. ** 输 出:
  697. ** 全局变量:
  698. ** 调用模块:
  699. ** 作 者: 吴鉴鹰
  700. ** 日 期: 14.03.5
  701. ************************************************************************************/
  702. void ser() interrupt 4 //中断接收数据
  703. {
  704. unsigned char receive[10];
  705. unsigned char a,i;
  706. if(RI==1)
  707. {
  708. DIS_receive_data[Num] = SBUF;
  709. if(Num < 5)
  710. {
  711. Num++;
  712. }
  713. else
  714. {
  715. a = receive[0];
  716. for(i = 1;i < 4;i ++)
  717. {
  718. a = a&receive;
  719. }
  720. if(a = receive[4])
  721. {
  722. for(i = 0; i < 2;i++)
  723. {
  724. display_TEMP_DATA = receive;
  725. }
  726. for(i = 2;i < 4;i++)
  727. {
  728. dist_test_DATA = receive;
  729. }
  730. }
  731. /*if(DIS_receive_data[0]&DIS_receive_data[1] == DIS_receive_data[2])
  732. {
  733. }*/
  734. Num = 0;
  735. }
  736. flag=1;
  737. RI=0;
  738. }
复制代码



为了方便大家交流,建了两个QQ群:QQ群3号:198387118  【1000人群】QQ群5号: 239316959【2000人群】群内已有成员3000余人!
更多内容关注微信公众号:单片机精讲吴鉴鹰

回复

使用道具 举报

364

TA的帖子

0

TA的资源

纯净的硅(初级)

Rank: 4

 楼主| 发表于 2014-6-19 09:07 | 显示全部楼层
flyme 发表于 2014-6-14 11:44
好东西,支持!!

感觉有什么问题的地方欢迎指出!!!!
为了方便大家交流,建了两个QQ群:QQ群3号:198387118  【1000人群】QQ群5号: 239316959【2000人群】群内已有成员3000余人!
更多内容关注微信公众号:单片机精讲吴鉴鹰

回复

使用道具 举报

1419

TA的帖子

0

TA的资源

纯净的硅(高级)

Rank: 6Rank: 6

发表于 2014-6-20 08:47 | 显示全部楼层
很给力,支持下

点评

谢谢支持!!!一定分享更多给力的东西!!!  详情 回复 发表于 2014-6-20 10:03

回复

使用道具 举报

364

TA的帖子

0

TA的资源

纯净的硅(初级)

Rank: 4

 楼主| 发表于 2014-6-20 10:03 | 显示全部楼层
sint27 发表于 2014-6-20 08:47
很给力,支持下

谢谢支持!!!一定分享更多给力的东西!!!
为了方便大家交流,建了两个QQ群:QQ群3号:198387118  【1000人群】QQ群5号: 239316959【2000人群】群内已有成员3000余人!
更多内容关注微信公众号:单片机精讲吴鉴鹰

回复

使用道具 举报

42

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2014-6-20 10:34 | 显示全部楼层
xie楼主  

回复

使用道具 举报

431

TA的帖子

3

TA的资源

纯净的硅(初级)

Rank: 4

发表于 2014-6-20 13:00 | 显示全部楼层
谢谢楼主分享这些很实用的东西,标记一下子,等有时间了在来看。都是好东西啊!

点评

谢谢支持  详情 回复 发表于 2014-6-20 13:04
我在想
我知道什么

回复

使用道具 举报

364

TA的帖子

0

TA的资源

纯净的硅(初级)

Rank: 4

 楼主| 发表于 2014-6-20 13:04 | 显示全部楼层
zmsxhy 发表于 2014-6-20 13:00
谢谢楼主分享这些很实用的东西,标记一下子,等有时间了在来看。都是好东西啊!

谢谢支持
为了方便大家交流,建了两个QQ群:QQ群3号:198387118  【1000人群】QQ群5号: 239316959【2000人群】群内已有成员3000余人!
更多内容关注微信公众号:单片机精讲吴鉴鹰

回复

使用道具 举报

7

TA的帖子

1

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2014-6-20 13:07 | 显示全部楼层
牛,顶一下

回复

使用道具 举报

67

TA的帖子

2

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2014-6-20 17:47 | 显示全部楼层
好东西,嘿嘿谢谢楼主分享。学习了

点评

谢谢你们的支持!!!  详情 回复 发表于 2014-6-25 11:03

回复

使用道具 举报

364

TA的帖子

0

TA的资源

纯净的硅(初级)

Rank: 4

 楼主| 发表于 2014-6-21 09:39 | 显示全部楼层
同向比例放大器,公式如图所示!
102704vc7dl3qq5qecjqdl.jpg.thumb.jpg
为了方便大家交流,建了两个QQ群:QQ群3号:198387118  【1000人群】QQ群5号: 239316959【2000人群】群内已有成员3000余人!
更多内容关注微信公众号:单片机精讲吴鉴鹰

回复

使用道具 举报

364

TA的帖子

0

TA的资源

纯净的硅(初级)

Rank: 4

 楼主| 发表于 2014-6-21 11:16 | 显示全部楼层
以下章节会进行12864的运用讲解,从汉字显示,到图片显示,到最后贪吃蛇,俄罗斯方块,电子密码锁显示!
为了方便大家交流,建了两个QQ群:QQ群3号:198387118  【1000人群】QQ群5号: 239316959【2000人群】群内已有成员3000余人!
更多内容关注微信公众号:单片机精讲吴鉴鹰

回复

使用道具 举报

364

TA的帖子

0

TA的资源

纯净的硅(初级)

Rank: 4

 楼主| 发表于 2014-6-22 11:23 | 显示全部楼层
14、吴鉴鹰单片机实战项目精讲(连载)之驱动12864的滚动文字以及漫画图片的显示


为了方便大家交流,建了两个QQ群:QQ群3号:198387118  【1000人群】QQ群5号: 239316959【2000人群】群内已有成员3000余人!
更多内容关注微信公众号:单片机精讲吴鉴鹰

回复

使用道具 举报

3

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2014-6-23 01:38 | 显示全部楼层
这个确实太好了!感谢中。。。

点评

欢迎大家提出宝贵的意见!  详情 回复 发表于 2014-6-30 08:47

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

关闭

站长推荐上一条 1/5 下一条

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

Archiver|手机版|小黑屋|电子工程世界 ( 京ICP证 060456 )

GMT+8, 2020-3-31 15:44 , Processed in 0.550174 second(s), 18 queries , Gzip On, MemCache On.

快速回复 返回顶部 返回列表