基于RT-Thread的HC-SR04超声波驱动

前言

本次驱动用的是这款超声波,超声波的驱动大同小异,均可参考
在这里插入图片描述

一、引脚定义

引脚功能
VCC接直流5V
TRIG接外部电路的TRIG端,向此引脚输入10us以上的高电平可触发超声波测距
ECHO接外部电路的ECHO端,测距结束时该引脚会输出一个高电平,电平宽度为超声波往返时间之和
GND

二、工作原理

1、采用 IO 触发测距,给至少 10us 的高电平信号;
2、模块自动发送 8 个 40khz 的方波,自动检测是否有信号返回;
3、有信号返回,通过 IO 输出一高电平,高电平持续的时间就是超声波从发射到返回的时间
4、测试距离=(高电平时间*声速(340M/S))/2;

三、引脚时序图

建议测量周期在60ms以上,防止发射信号对回响信号的有影响

在这里插入图片描述

四、创建RTT工程(开始动手

在这里插入图片描述

五、打开CubeMX

在这里插入图片描述

六、配置串行调试口

在这里插入图片描述

七、配置使用外部高速晶振

在这里插入图片描述

八、创建工程时默认使用了串口一,这里也打开串口一

在这里插入图片描述

九、开启定时器三,定时器三是用来给超声波回波信号计时的,计算高电平时间从而得到测量距离

在这里插入图片描述

十、配置时钟线

在这里插入图片描述

十一、生成代码

在这里插入图片描述

十二、打开定时器设备驱动程序

在这里插入图片描述

十三、使能定时器模块

在这里插入图片描述

十四、打开定时器三的注释(使用哪个定时器就打开哪个,没有的就自己写上去

在这里插入图片描述

十五、在主函数中写入如下代码

/** Copyright (c) 2006-2024, RT-Thread Development Team** SPDX-License-Identifier: Apache-2.0** Change Logs:* Date           Author       Notes* 2024-05-10     先睡个好觉    first version*/#include <rtthread.h>
#include <rtdevice.h>  //加载设备驱动头文件
#include <board.h>#include <hwtimer.h>#define HWTIMER_DEV_NAME   "timer3"     /* 定时器名称 */
rt_device_t hw_dev;                     /* 定时器设备句柄 */rt_err_t ret = RT_EOK;    //返回值判断是否成功
rt_uint32_t timer_cb_num = 0;           /*进定时器超调函数次数  */
rt_uint32_t level_flag = 1;         /*判断超声波接受引脚是否是第一个上升沿*/
rt_uint32_t echo_high_time = 0;     //超声波接受引脚高电平总时间,单位为us
rt_uint32_t freq = 1000000;               /* 计数频率 */
rt_hwtimer_mode_t mode;                 /* 定时器模式 */
rt_hwtimerval_t timeout_s;      /* 定时器超时值 */rt_uint32_t distance_cm = 0;     //超声波测量出的距离#define SR04T_PIN_TRIG   GET_PIN(C, 9)  //获取sr04t超声波触发引脚号
#define SR04T_PIN_ECHO   GET_PIN(C, 8)  //获取sr04t超声波接收引脚号/* 定时器3超时回调函数,每10us会进来一次*/
static rt_err_t timeout3_cb(rt_device_t dev, rt_size_t size)
{timer_cb_num++;//每进一次超调函数,该变量加一if((rt_pin_read(SR04T_PIN_ECHO) == PIN_HIGH)&&(level_flag)){timer_cb_num = 0;  //如果超声波接收引脚被拉高了,重新进行计数level_flag = 0;}if ((rt_pin_read(SR04T_PIN_ECHO) == PIN_LOW)&&(level_flag == 0)){echo_high_time = timer_cb_num*10; //一个timer_cb_num是10uslevel_flag = 1;rt_kprintf("%d\n",timer_cb_num/9);}return 0;
}int sr04_Init(void)
{//设置sr04t超声波引脚的模式rt_pin_mode(SR04T_PIN_TRIG, PIN_MODE_OUTPUT);//设置引脚为输出模式rt_pin_mode(SR04T_PIN_ECHO, PIN_MODE_INPUT_PULLDOWN);//设置ECHO引脚为输入模式rt_pin_write(SR04T_PIN_TRIG, PIN_LOW);//拉低引脚rt_pin_write(SR04T_PIN_ECHO, PIN_LOW);//拉低引脚/* 查找定时器设备 */hw_dev = rt_device_find(HWTIMER_DEV_NAME);if(hw_dev == RT_NULL){rt_kprintf("hwtimer sample run failed! can't find %s device! \n",HWTIMER_DEV_NAME);return RT_ERROR;}/* 以读写方式打开设备 */rt_device_open(hw_dev, RT_DEVICE_OFLAG_RDWR);if(ret != RT_EOK){rt_kprintf("open %s device failed!\n",RT_DEVICE_OFLAG_RDWR);return ret;}/* 设置超时回调函数 */rt_device_set_rx_indicate(hw_dev, timeout3_cb);/* 设置计数频率(若未设置该项,默认为1Mhz 或 支持的最小计数频率) */rt_device_control(hw_dev, HWTIMER_CTRL_FREQ_SET, &freq);/* 设置模式为周期性定时器(若未设置,默认是HWTIMER_MODE_ONESHOT)*/mode = HWTIMER_MODE_PERIOD;rt_device_control(hw_dev, HWTIMER_CTRL_MODE_SET, &mode);/* 设置定时器超时值为10us并启动定时器 */timeout_s.sec = 0;      /* 秒 */timeout_s.usec = 10;     /* 微秒 */if (rt_device_write(hw_dev, 0, &timeout_s, sizeof(timeout_s)) != sizeof(timeout_s)){rt_kprintf("set timeout value failed\n");return RT_ERROR;}return RT_EOK;
}//信号触发
void US_SendStartSignal(void)
{rt_pin_write(SR04T_PIN_TRIG, PIN_HIGH);//拉高引脚,触发信号rt_hw_us_delay(20);   //给20us的延时//rt_thread_mdelay(5);rt_pin_write(SR04T_PIN_TRIG, PIN_LOW);//拉低引脚
}//数据处理
//count传进去的参数是us
float SR04T_DataConversion(rt_uint32_t *count)
{float result = 0;result = (float)((float)(*count * 340) / 2000000.0);*count = 0;result = result*100.0; //将米转化为厘米return result;
}//-------------------超声波线程-----------------------------------------------
rt_thread_t Sr04Th_Handler;   //姿态解算线程句柄
#define Sr04_TH_PRIO    10    //姿态解算线程优先级
#define Sr04_STK_SIZE   700  //姿态解算线程堆栈大小
#define Sr04_TICK_LEN   5    //姿态解算线程执行时间void th_sr04_entry(void *parameter)
{rt_uint16_t num_trig_time=0;while(1){num_trig_time++;if(num_trig_time>12){num_trig_time = 0;US_SendStartSignal();//超声波信号触发}distance_cm = SR04T_DataConversion(&timer_cb_num);//超声波数据处理//rt_kprintf("%d\n",echo_high_time/28);rt_thread_mdelay(5);}
}int sr04_th_creat(void)
{//超声波线程Sr04Th_Handler = rt_thread_create("th_sr04_entry",th_sr04_entry,NULL,Sr04_STK_SIZE,Sr04_TH_PRIO,Sr04_TICK_LEN);if(Sr04Th_Handler == NULL){rt_kprintf("th_sr04_entry(create)failed...\n");return -ENOMEM;}return RT_EOK;
}void th_start(void)
{rt_thread_startup(Sr04Th_Handler);   //开启超声波线程线程调度
}int main(void)
{sr04_Init(); //超声波初始化sr04_th_creat();//超声波线程创建th_start();//开启线程调度return RT_EOK;
}

十六、编译,有如下报错,先双击进入第一个错误

在这里插入图片描述

十七、把这段代码进行注释

在这里插入图片描述

十八、再编译还剩这个报错,找不到hwtimer.h文件

在这里插入图片描述

十九、跳转进入这个头文件

在这里插入图片描述

二十、找到它的文件路径

在这里插入图片描述

二十一、打开构建配置,进行路径包含,应用后关闭

在这里插入图片描述

二十二、再次编译,报错解决

在这里插入图片描述

二十三、连接好硬件

在这里插入图片描述

二十四、下载程序,查看串口一,有数据输出,并且随着遮挡物的远近,数据大小有变化

在这里插入图片描述

二十五、这里需要注意一下,如果你使用的定时器里面没有,需要模仿里面的结构自行添加

在这里插入图片描述

二十六、最后提醒一下,代码中输出的并不是准确的cm数,我只是随意除了一个数字就输出了,数据转换函数在代码中我也写了,不过没有使用,因为它输出的是浮点数,rtthread要想打印浮点数需要另行配置,在这个工程里我没有配置,所以要想得到精确的cm数,请自行数据转换。

rtthread输出浮点数,可以参考我的这篇文章
⬇ ⬇ ⬇ ⬇ ⬇ ⬇ ⬇ ⬇ ⬇ ⬇ ⬇ ⬇ ⬇ ⬇ ⬇ ⬇
RT-Thread(RTT)如何打印输出浮点数
在这里插入图片描述

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

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

相关文章

Python框架Django入门教程

Django 是一个使用 Python 编程语言开发的、免费且开源的 Web 应用框架。它遵循 "DRY&#xff08;Dont Repeat Yourself&#xff09;" 原则&#xff0c;旨在简化创建功能丰富的、高效率的 Web 网站。Django 提供了模型-视图-控制器&#xff08;MVC&#xff09;架构的…

时尚圈的节制美学 — 奥柔拉 AVRALA的独特设计理念

在这个多元化的时代&#xff0c;女性正在经历一场前所未有的角色变革。她们不再仅仅满足于传统的社会角色&#xff0c;而是勇敢地追求个人职业发展和自我实现。在这样的背景下&#xff0c;服饰不仅仅是外在的装饰&#xff0c;更是内心故事的讲述者、个性自我的表达者、身份归属…

NX/UG二次开发—3D几何—多边形内部最大圆

多边形内部最大圆&#xff0c;为什么不能说最大内切圆&#xff1f;如果正方形或正凸多边形&#xff0c;最大内部圆是与边相切的&#xff0c;但对于不规则多边形&#xff0c;很多情况是正好经过一些凹点。 本次介绍在NX中计算封闭边界内部最大圆&#xff1a; 1、首先按顺序排序…

Spring、SpringMVC

一、Spring框架中的单例Bean是线程安全的吗&#xff1f; 【默认单例的情况下】Spring Bean并没有可变的状态&#xff08;如Service类和DAO类&#xff09;&#xff0c;即只能查不能改&#xff0c;所以没有并发问题&#xff0c;所以某种程度上来说Spring的单例Bean是线程安全的。…

【ZZULI数据结构实验】压缩与解码的钥匙:赫夫曼编码应用

&#x1f4c3;博客主页&#xff1a; 小镇敲码人 &#x1f49a;代码仓库&#xff0c;欢迎访问 &#x1f680; 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&#x1f3fd;留言 &#x1f60d;收藏 &#x1f30f; 任尔江湖满血骨&#xff0c;我自踏雪寻梅香。 万千浮云遮碧…

前端工程化之包管理器

这里写目录标题 什么是包包管理工具常用的包管理工具npmnpm 基本使用初始化搜索工具包下载安装包导入 npm 包基本流程生产依赖与开发依赖全局安装安装全部依赖安装指定版本的包删除依赖包 cnpm全局安装nrm 的使用 yarn全局安装yarn 常用命令 pnpm 【推荐使用】全局安装 什么是包…

我国吻合器市场规模不断扩大 国产化率有所增长

我国吻合器市场规模不断扩大 国产化率有所增长 吻合器是替代手工切除或缝合的一种医疗器械&#xff0c;其工作原理与订书机十分相似&#xff0c;可利用钛钉对组织进行离断或吻合。经过多年发展&#xff0c;吻合器种类逐渐增多&#xff0c;根据手术方式不同&#xff0c;吻合器大…

【JavaEE 初阶(三)】多线程代码案例

❣博主主页: 33的博客❣ ▶️文章专栏分类:JavaEE◀️ &#x1f69a;我的代码仓库: 33的代码仓库&#x1f69a; &#x1faf5;&#x1faf5;&#x1faf5;关注我带你了解更多线程知识 目录 1.前言2.单例模式2.1饿汉方式2.2饿汉方式 3.阻塞队列3.1概念3.2实现 4.定时器4.1概念4.…

支付宝小程序如何去除页面下拉回弹

描述&#xff1a;支付宝小程序页面下拉时会产生回弹&#xff0c;如果页面上有拖拽功能&#xff0c;会有影响 解决方法&#xff1a; 页面xx.config.js中设置&#xff1a;allowsBounceVertical: “NO” 官方文档&#xff1a;https://opensupport.alipay.com/support/FAQ/7110b5d…

WT32-ETH01作为TCP Client进行通讯

目录 模块简介WT32-ETH01作为TCP Client设置电脑作为TCP Server设置连接并进行通讯总结 模块简介 WT32-ETH01网关主要功能特点: 采用双核Xtensa⑧32-bit LX6 MCU.集成SPI flash 32Mbit\ SRAM 520KB 支持TCP Server. TCP Client, UDP Server. UDP Client工作模式 支持串口、wif…

鸿蒙OpenHarmony技术:【Docker编译环境】

Docker环境介绍 OpenHarmony为开发者提供了两种Docker环境&#xff0c;以帮助开发者快速完成复杂的开发环境准备工作。两种Docker环境及适用场景如下&#xff1a; 独立Docker环境&#xff1a;适用于直接基于Ubuntu、Windows操作系统平台进行版本编译的场景。基于HPM的Docker环…

uni-app+vue3 +uni.connectSocket 使用websocket

前言 最近在uni-appvue3websocket实现聊天功能&#xff0c;在使用websocket还是遇到很多问题 这次因为是app手机应用&#xff0c;就没有使用websocket对象&#xff0c;使用的是uni-app的uni.connectSocket 为了方便测试这次用的是node.js一个简单的dom&#xff0c;来联调模拟…

Apache Flume Agent内部原理

Apache Flume Agent内部原理 Apache Flume 是一个可扩展的、分布式的日志收集、聚合和传输系统。在 Flume 中&#xff0c;Agent 是一个独立的进程&#xff0c;负责接收、传输和处理数据。Agent 内部包含多个组件&#xff0c;每个组件都有不同的功能和责任。 1. Source&#xff…

三下乡社会实践投稿攻略在这里

在当今信息爆炸的时代&#xff0c;如何让自己的声音被更多人听到&#xff0c;成为许多人和企业所关心的问题。其中&#xff0c;向各大媒体网站投稿&#xff0c;成为了一种常见的宣传方式。但是&#xff0c;如何投稿各大媒体网站&#xff1f;新闻媒体发文策略又有哪些呢&#xf…

光耦推荐—高速风筒方案中用到哪些光耦型号

高速风筒是现代生活中常见的电器设备&#xff0c;广泛应用于家庭、商业和工业领域&#xff1b;光耦是一种能够将输入信号转换成输出信号的元器件&#xff0c;其作用在于将电气信号转换成光信号&#xff0c;从而实现电路的隔离和保护&#xff1b;采用光耦可实现对风机转速和温度…

【管理咨询宝藏99】离散制造智能工厂战略规划方案

本报告首发于公号“管理咨询宝藏”&#xff0c;如需阅读完整版报告内容&#xff0c;请查阅公号“管理咨询宝藏”。 【管理咨询宝藏99】离散制造智能工厂战略规划方案 【格式】PDF版本 【关键词】智能制造、先进制造业转型、数字化转型 【核心观点】 - 推进EHS、品质一致性、生…

Failed to start tomcat.service: Unit is not loaded properly: Bad message 如何解决?

错误 “Failed to start tomcat.service: Unit is not loaded properly: Bad message” 通常意味着的 tomcat.service systemd 配置文件存在语法错误或配置不正确。为了解决这个问题&#xff0c;一步步检查和修正这个服务文件。 1. 检查 tomcat.service 文件 首先&#xff0c…

CSS文字描边,文字间隔,div自定义形状切割

clip-path: polygon( 0 0, 68% 0, 100% 32%, 100% 100%, 0 100% );//这里切割出来是少一角的正方形 letter-spacing: 1vw; //文字间隔 -webkit-text-stroke: 1px #fff; //文字描边1px uniapp微信小程序顶部导航栏设置透明&#xff0c;下拉改变透明度 onP…

SQL注入(sqli-labs第一关)

sqli-labs第一关 方法一&#xff1a;手工注入 来到第一关&#xff0c;图上说我们需要一个数字的参数 于是我们先手工注入?id1 and 11 跟?id1 and 12发现页面没有报错 每张截图上面页面中有select查询语句&#xff0c;这是我在第一关的源码中加上了echo "$sql ";…

SSM【Spring SpringMVC Mybatis】——Mybatis(二)

如果对一些基础理论感兴趣可以看这一期&#x1f447; SSM【Spring SpringMVC Mybatis】——Mybatis 目录 1、Mybatis中参数传递问题 1.1 单个普通参数 1.2 多个普通参数 1.3 命名参数 1.4 POJO参数 1.5 Map参数 1.6 Collection|List|Array等参数 2、Mybatis参数传递【#与…