找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 11122|回复: 9
打印 上一主题 下一主题
收起左侧

[经验] 自编超声波测距模块(HC-SR04)STC单片机程序开源

  [复制链接]
跳转到指定楼层
楼主
各位朋友,大家好~  
       相信很多朋友都用过一款HC-SR04超声波测距模块,这个模块售价很平民,某宝上仅4RMB左右:能测3-400cm,真的很不错的。
      前一段时间,偶尔看到一款超声波测距模块(m**eblock的),控制方式与HC-SR04有所不同,硬件上是大同小异的,但售价非常有逼格。
      本菜出于好奇,在网上找了很久的资料,大多数都是讲怎么使用HC-SR04模块的,而我想找的资料是如何制作HC-SR04这个模块,关键是模块中STC单片机的程序。

1、原理部分
      HC-SR04这个模块是2线制的(不包含电源线),
Echo与Trig,Trig负责接收10us以上的触发信号,Echo则是输出距离信号;下面是时序图:

      而m**eblock的超声波模块采用1线制(不包含电源线),,Echo与Trig和二为一(SIG),在一定程度上节省了IO资源,SIG在收到触发信号后采集并输出距离信号,其时序图与HC-SR04类似,使用起来略有不同,需要注意IO模式的转换,而如果使用m**eblock官方提供的库(Arduino)就非常简单了;
             关于HC-SR04系列超声波传感器的介绍网上有很多的帖子,本菜不赘述了。


2、硬件部分:
      下面就先看一个原理图吧,由于本菜的硬件不行,只是简单的分析一下,有说错的地方,欢迎大神们吐槽!


左边是m**eblock的原理图,右边是HC-SR04的原理图,可以看到,硬件部分的实现方式是大同小异的,下面以m**eblock为例。
      这里主要分成三个部分:
      1、主控IC部分:完成触发信号的检测、产生8个40KHz脉冲信号、检测回波信号、输出距离信号等;
      2、发射部分:由主控IC产生8个40KHz脉冲信号后,经过MAX232放大后驱动超声波发射端;
      3、接收部分:将微弱的回波信号放大,送到主控IC的IO端检测回波。

3、软件部分
下面是程序思路,围绕STC展开,说一下STC每个管脚的作用~
1、P30(SIG): 负责监测触发信号;
   配置其为高阻输入,可以轮询其高低电平并使用Timer0(2),也可以轮询高电平后使用INT4低电平,完成一个触发脉冲的检测(10us以上),一旦检测到触发信号,此管脚配置为推挽输出,并拉低,当8个40KHz信号发送完成后将其拉高,等到回波到来。

2、P33(T2)、P32(T1):8个40KHz脉冲信号;
   配置为推挽输出,当SIG检测到触发信号后,其同时发送8个40KHz信号,注意这两个信号存在半个周期的相位差(重要!),发射完成之后将SIG拉高。

3、P31(T_PWR):MAX232供、断电;
   配置其为推挽输出;通过NPN控制232,低电平有效,只在8个40KHz脉冲信号时给232供电,防止杂波出现,232在这里起到一个驱动放大功率的作用;

4、P34(PWM): 比较电压;
   一开始我以为这是一个PWM信号,后来发现我错了,可以看一下电路图中的放大器A,是作为一个比较器使用的。其实只要在检测回波信号的时候将其拉高就行了。(目前我是这样做的)

5、P35(CHK):回波检测;
    配置为高阻输入;可以利用INT3来检测下降沿并使用Timer2(0)计算周期,并检测回波频率,判断是否为发射出去的40KHz信号,检测完成后将SIG拉高,完成一次测量。

    第一次发表这么长的开源贴子,欢迎大家吐槽(鼓励~~),源代码中几乎每一条代码后都跟有注释,相信大家读起来不会太费时间的。程序中难免有些处理不妥的地方,欢迎大家下载优化,记得分享您的成果哈~~~

单片机源程序如下:
  1. /*-----------------------------------------------
  2.   名称:HC-SR04内源码
  3.   版本:v1.1
  4.   编写:XiaoKai
  5.         环境:MDK51 Pro V9.50a
  6.   日期:2017.2.23
  7.   修改:无
  8.   内容:超声波测距模块源码
  9. ------------------------------------------------*/

  10. #include "main.h"

  11. bit TRRIG  = FALSE;  //标志是否接收到触发信号:FALSE(否)、TRUE(是)
  12. /*------------------------------------------------
  13.                     主函数
  14. ------------------------------------------------*/
  15. void main (void)
  16. {
  17.         Clock_Init();  //系统时钟初始化
  18.         GPIO_Init();  //GPIO 口初始化
  19.         Timer0_Init();  //Timer0 初始化,负责测量回波信号频率
  20.         Timer2_Init();  //Timer2 初始化,负责测量触发脉冲宽度
  21.         Exint3_Init();  //INT3 初始化,负责检测回波信号
  22.         
  23.         DelayMs(10);  //延时等待完成
  24.         
  25.         while (1)  //主循环
  26.   {
  27.                 //---------------监测触发信号-------------
  28.                 TRIGGER();
  29.                 //--------------监测到触发信号------------
  30.                 if(TRRIG)
  31.                 {
  32.                         //------------P3.0 设置为推挽输出----------
  33.                         P3M0 |=  (1 << 0);  //P3.0 设置为推挽输出
  34.                         P3M1 &= ~(1 << 0);
  35.                         //-----------------拉低 SIG----------------
  36.                         SIG = LOW;  //SIG 由输入模式变为输出模式后默认输出高
  37.                         //-----------发送 8 个 40KHz 信号----------
  38.                         EIGHT();  //发送脉冲后应该立即拉高SIG,这样测量更加精准???
  39.                         //-----------------拉高 SIG----------------
  40.                         SIG = HIGH;  //发送完 8 个 40KHz 后,拉高 SIG 表示测量开始
  41.                         //----------开启Timer0及接收INT3-----------
  42.                         INT_CLKO |= (1<<5);  //接收INT3
  43.                         //--------------等待 SIG 被拉低------------
  44.                         while(SIG)  //SIG 在 exint3.c 中被检测
  45.                         {
  46.                                 //--------------比较电压输出高-----------
  47.                                 PWM = HIGH;  //P34输出比较电压,允许信号通过
  48.                         }
  49.                 }
  50.                 //-----------------拒收INT3----------------
  51.                 INT_CLKO &= ~(1<<5);  //拒收INT3
  52.                 //----------------关闭Timer2---------------
  53.                 TR0=0;  //关闭Timer0
  54.                 //---------------比较电压输出低------------
  55.                 PWM = LOW;//不允许信号通过
  56.                 //----------表示没有接收到触发信号---------
  57.                 TRRIG = FALSE;
  58.   }
  59. }
复制代码


所有资料51hei提供下载:
HC-SR04-V1.2.zip (4.27 MB, 下载次数: 191)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏5 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:403531 发表于 2018-10-25 10:47 | 只看该作者
回复

使用道具 举报

板凳
ID:343102 发表于 2018-10-25 19:39 | 只看该作者
学习一下。楼主可以做个大功率的。
回复

使用道具 举报

地板
ID:393140 发表于 2019-4-8 22:45 | 只看该作者
可以用嘛
回复

使用道具 举报

5#
ID:476328 发表于 2019-5-16 23:07 | 只看该作者
写的真棒 学习了
回复

使用道具 举报

6#
ID:725010 发表于 2020-4-8 18:43 | 只看该作者
终于找到自编HC-04的制作方法了
回复

使用道具 举报

7#
ID:701637 发表于 2020-5-24 20:10 | 只看该作者
STC的是编写GPIO吗
回复

使用道具 举报

8#
ID:284659 发表于 2020-6-4 17:07 | 只看该作者
楼主自己验证过吗
回复

使用道具 举报

9#
ID:829442 发表于 2020-10-13 18:50 | 只看该作者
谁亲测过?
回复

使用道具 举报

10#
ID:241273 发表于 2021-10-20 10:50 | 只看该作者
void exint3() interrupt 11  //INT3ÖD¶Ïèë¿ú
{
        INT_CLKO &= 0xDF;  
        INT_CLKO |= 0x20;  
       
        //T_PWR =!T_PWR;
        if(EX_COUNT > 2) EX_COUNT++;  //这里应该有问题吧      
        else EX_COUNT=0;
       
        if(TRRIG&&SIG)  
        {
                if(EX_COUNT == 1)
                {
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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