找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 18727|回复: 18
收起左侧

HC-SR04(HY-SRF05)超声波测距串口显示(超详细版单片机源程序)

  [复制链接]
ID:244281 发表于 2017-10-30 17:45 | 显示全部楼层 |阅读模式

好久没有用51单片机了,最近有点时间又拿出来玩,最基本的往往也是最重要的。

51单片机作为大多数人入门单片机接触的第一个板子虽然比较简单,但是仍需要细细揣摩,对51单片机的熟练掌握对以后接触其他单片机有很大帮助,而借助51单片机做其他模块开发也是一件很有意思的事情。

之前看到一下超声波模块的程序代码往往是网上代码进行删减更改,让新手看着一头雾水,因此最近整理了一下关于该模块的一套比较不错的代码,可以说是目前我所见到最详细的了,老鸟可以路过,很适合新手入门。

近期也会继续整理其他资料陆续上传。



提供的代码均为原创代码并通过测试 !

提供技术支持 !

**************  超声波测距串口显示C程序   **************
1、需要具备51单片机C语言开发基础
2、需对51单片机基础中的定时器/计数器以及串口中断部分内容进行复习 !

单片机源程序如下:
  1. /******************************************************************************/
  2. /*  NAME : HC-SR04 超声波模块测距PC端串口显示程序    */
  3. /*  MCU:STC89C51                                     */
  4. /*  晶振:11.0592MHz                                 */
  5. /*  接线:  TRIG ---- P1.2                           */
  6. /*          ECH0 ---- P1.1                           */
  7. /*  串口波特率9600                                   */
  8. /***********************************************************************************************************/         
  9. #include <AT89X51.H>
  10. #include <intrins.h>
  11. #include <stdio.h>

  12. void InitIRQ(void);
  13. void Conut(void);
  14. void delayms(unsigned int ms);
  15. void StartModule();        

  16. #define uchar unsigned  char
  17. #define uint  unsigned   int  
  18. #define RX  P1_1
  19. #define TX  P1_2
  20.   
  21. unsigned int  time=0;
  22. float         Distance=0;//距离
  23. bit           flag =0;   //中断溢出标志
  24.         
  25. /********************************************************/
  26. void main()
  27. {
  28.         InitIRQ();
  29.         while(1)
  30.   {
  31.          StartModule();
  32.          while(!RX);                //当超声波模块接收口输出低电平则等待
  33.          TR0=1;                //开启计数
  34.          while(RX);                        //当RX为1计数并等待
  35.          TR0=0;                                  //关闭计数
  36.    Conut();                          //读取定时器的值,计算
  37.          delayms(60);        
  38.         }
  39. }

  40. /*********** 中断寄存器设置初始化 ***********/
  41. void InitIRQ(void)
  42. {
  43.         TMOD=0x21;  //T/C工作方式寄存器 0010 0001
  44.                     //T0 :GATE=0; 定时模式; 工作方式1,16位T/C; 计数器溢出中断,用于判定超出测距范围
  45.                     //T1 :GATE=0; 定时模式; 工作方式2,8位可自动重载T/C; 用于串口通信 波特率发生器
  46.         SCON=0x50;  //串行口控制寄存器  0101 0000
  47.                     //SM0 SM1:工作方式1;10位异步收发;波特率由定时器T1控制
  48.                     //SM2: 多机通信控制位,方式0和方式1为非多机通信,设置0
  49.                     //REN: 串行口接收允许位,允许串行口接收数据
  50.                     //TB8:方式0和方式1中该位不用
  51.                     //RB8: 方式0和方式1中该位不用
  52.                     //TI: 发送中断标志位。串行发送停止位时,由内部硬件置1,向CPU发中断申请,必须由软件清0
  53.                      //RI: 接收中断标志位。串行接收停止位时,由内部硬件置1,向CPU发中断申请,必须由软件清0
  54.         TH0=0;      //T0初始化,,用于判断测距溢出,最大65.536 ms
  55.         TL0=0;         
  56.         TH1=0xFD;   //T1初始化  设定波特率9600 (波特率计算参考文档)
  57.         TL1=0xFD;   
  58.         
  59.         ET0=1;      //T0中断允许
  60.         TR0=1;      //开启定时器0
  61.         TR1=1;      //开启定时器1
  62.         //ES=1;     //串口允许中断
  63.                     /*
  64.                                                           可删除,我的理解是:在系统正常运行情况下,串口发送完成则置位TI=1,
  65.                                                           向CPU请求中断,在我们软件人为的直接设置TI=1的情况下可以直接向CPU
  66.                                                           请求中断了,已经跳过了“允许”那一步
  67.                                                                 并且最好删除!
  68.                                                                 因为TI为中断标志位如果程序使用了串口中断,那么每次调用printf都
  69.                                                                 会进入中断,因此在使用printf前要禁用中断
  70.                                                         */
  71.         TI=1;       /*
  72.                      发送中断标志 ☆直接使用printf必须加此语句才能发送
  73.                在KEILC中,printf在传输数据前需要确保前一个数据传输
  74.                                                          结束,也就是TI=1,否则将处于等待状态
  75.                                                          因为printf函数会调用putchar函数,而putchar函数会判断TI,
  76.                                                          不为1则等待(相当于死机),为1则清0,发送完成后又自动置1
  77.                                                          因此第一次运行printf时检查TI=1则进行发送,发送完成后
  78.                                                          发送中断标志位TI又自动置1
  79.                                                          */
  80.   EA=1;       //开启总中断
  81. }

  82. /*********** 触发超声波模块 ***********/
  83. void  StartModule() //超声波模块Trig控制端给大于10us的高电平触发模块测距        
  84. {
  85.           TX=1;     
  86.           _nop_();
  87.           _nop_();
  88.           _nop_();
  89.           _nop_();
  90.           _nop_();
  91.           _nop_();
  92.           _nop_();
  93.           _nop_();
  94.           _nop_();
  95.           _nop_();
  96.           _nop_();
  97.           _nop_();
  98.           _nop_();
  99.           _nop_();
  100.           _nop_();
  101.           //_nop_();
  102.           //_nop_();
  103.           //_nop_();
  104.           //_nop_();
  105.           //_nop_();
  106.           TX=0;
  107. }

  108. /*********** 定时器T0计数 ***********/
  109. void Conut(void)
  110. {
  111.          time=TH0*256+TL0;
  112.          TH0=0;
  113.          TL0=0;
  114.          Distance = (time*1.87)/100;  //CM  (见代码最后注释)
  115.          if(flag==1)                    //超出测量
  116.          {
  117.           flag=0;
  118.           printf("-----\n");
  119.          }
  120.           printf("Distance = %f CM\n",Distance);
  121. }
  122. /********************************************************/
  123. void delayms(unsigned int ms)
  124. {
  125.         unsigned char i=100,j;
  126.         for(;ms;ms--)
  127.         {
  128.                 while(--i)
  129.                 {
  130.                         j=10;
  131.                         while(--j);
  132.                 }
  133.         }
  134. }
  135. /*********** 定时器T0中断服务函数 ***********/
  136. void Timer0IRQ() interrupt 1 //T0中断用来计数器溢出,超过测距范围
  137. {
  138.     flag=1;        
  139. }

  140. /*12分频:就是f/12,假设(接晶振12MHz)输入信号频率12MHz,12分频后,则输出1MHz
  141.         *时钟周期周期变为原来的12倍, T=1/1MHz=1us
  142.         *即单片机内部的加1计数器在加1这个过程中 ,寄存器要完成这个动作,是一个机器周期
  143.         *时钟周期为1/12MHz=1/12us
  144.         *机器周期=12个时钟周期=1us,也就是计数器每加1需要的时间问1us
  145.         *单片机中的部件都是在晶振12分频后的一个机器周期在跑
  146.         *时钟周期 = 晶振频率的倒数,即1/fosc
  147.         *机器周期 = 12 * 时钟周期 = 12/fosc
  148.         ------------------------------------------------------
  149.         |距离计算公式
  150.         |2S(m) = t(s) * 344(m/s)
  151.         |S(m)  = t(s) * 172(m/s)
  152.         |S(cm) = t(us) * 0.0172(cm/us)
  153.         |      = t(us) * 1/58
  154.         |t在晶振位12MHz时等于计数值(机器周期1us),但晶振为11.0592MHz时
  155.         |t(us) = 计数 * (12/11.0592) * (1/58)
  156.         |      = 计数 * 0.0187
  157.         |      = (计数 * 1.87)/100

  158.         …………
  159.         …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
HC-SR04超声波测距串口显示.rar (32.19 KB, 下载次数: 488)

评分

参与人数 3黑币 +63 收起 理由
kljie1000 + 3
白鹤859 + 10 很给力!
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:244281 发表于 2017-11-8 20:51 | 显示全部楼层
very good!
回复

使用道具 举报

ID:253663 发表于 2017-11-26 19:52 | 显示全部楼层
不能下载了,楼主
回复

使用道具 举报

ID:152690 发表于 2018-3-28 16:12 | 显示全部楼层
好东西啊 最近课程要做这个东西
回复

使用道具 举报

ID:234095 发表于 2018-6-15 21:40 | 显示全部楼层
这好东西啊,找了很多地方在这里找到了
回复

使用道具 举报

ID:356959 发表于 2018-6-22 23:16 | 显示全部楼层
在串口显示的是16金进制数还是别德
回复

使用道具 举报

ID:326451 发表于 2018-7-3 22:22 | 显示全部楼层
厉害了呀终于
回复

使用道具 举报

ID:405797 发表于 2018-10-6 12:25 | 显示全部楼层
挺好的
回复

使用道具 举报

ID:407566 发表于 2018-10-10 15:29 | 显示全部楼层
很给力很给力
回复

使用道具 举报

ID:410960 发表于 2018-10-17 16:28 | 显示全部楼层
不知道评论里有没有人实现过
回复

使用道具 举报

ID:51321 发表于 2018-10-17 23:35 | 显示全部楼层

很给力很给力   
回复

使用道具 举报

ID:397622 发表于 2018-12-24 00:18 | 显示全部楼层
看看 很需要希望可以下载
回复

使用道具 举报

ID:496367 发表于 2019-3-22 20:08 | 显示全部楼层
回复

使用道具 举报

ID:490762 发表于 2019-3-26 23:22 | 显示全部楼层
不知道几米是个问题
回复

使用道具 举报

ID:471632 发表于 2019-3-27 11:31 | 显示全部楼层
好,就需要这种原创的教程
回复

使用道具 举报

ID:218320 发表于 2019-4-20 15:01 | 显示全部楼层
有没有一个单片机测距离,然后向另外一个单片机传送距离的代码,使用串口通信
回复

使用道具 举报

ID:529417 发表于 2019-5-7 12:13 | 显示全部楼层
可以,用处很大
回复

使用道具 举报

ID:366678 发表于 2019-7-30 16:34 | 显示全部楼层
已下载,只有超声波测距代码,并没发现串口传输代码
回复

使用道具 举报

ID:493620 发表于 2019-9-16 22:57 | 显示全部楼层
已下载,只有超声波测距代码,并没发现串口传输代码
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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