| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 嵌入式 -> STM32连接HC-SR04超声波测距(结合STM32CubeMX和HAL库函数) -> 正文阅读 |
|
[嵌入式]STM32连接HC-SR04超声波测距(结合STM32CubeMX和HAL库函数) |
实验说明实验平台:STM32H743 (野火挑战者) 实验内容:使用GPIO激活HC-SR04超声波模块 ,接收信号。 使用IO口:PC10连接TRIG,PC11连接ECHO,GND接GND,VCC接5V。 HC-SR04超声波测距模块可提供2cm-400cm的非接触式距离感测功能,测距精度可达高到3mm;模块包括超声波发射器、接收器与控制电路。 STM32H743 控制器有 2 个高级控制定时器、10 个通用定时器和 2 个基本定时器,还有 2 个看门狗定时器。因为设计功能不复杂,这次主要使用的就是TIM6基本定时器,从表可以看出TIM6的时钟来源是APB1。 原理十分简单,比如我往箱子里丢小球,丢一个小球为1s,如果我想计时10s,其实就是丢10次小球,那TIMx_CNT开始从0计数,当计数值达到10,就产生中断并清0,重新开始计数。这个10就是后面要设置的Period。 STM32CubeMX新建工程1.设置定时器时钟首先系统的时钟设置为400MHZ,具体如何设置可以参考STM32 RCC-使用HSE/HSI配置时钟(以STM32MUX时钟树作为图例)。最后可以看到APB1 Timer的时钟是200MHZ,不是上面那个100MHZ,那是搭载在APB1的其他外设时钟。 2.设置定时器激活定时器TIM6,设置prescaler为19999,Counter Period为4999,auto-reload为Enable。
定时计算: 前面设置了定时器TIM6的时钟频率TIMxCLK为200MHZ,那是时钟来源,真正的定时器频率需要结合预分频进行计算,公式TIMxCLK/(TIM_Prescaler+1)=200M/(19999+1)=10000HZ。频率为10000HZ,时间就是0.1ms,也就是定时器计数增加1,时间为0.1ms。如果想要增加定时精度,就是需要调整预分频Prescaler。 现在知道了一次计数为0.1ms,我们需要定时0.5s,也就是500ms,可以反推出需要计数5000次。因为定时器是从0开始计算的,所以最终计数值Counter Period就是5000-1=4999。 点击NVIC中断管理,勾选定时器更新中断,产生溢出时会跳转到中断服务函数。 3.设置GPIOGPIO口设置对应ECHO和TRIG引脚,一个触发信号输入,一个是回响信号输出。那就是设置两个GPIO口,一个输出触发超声波模块,一个输入接收信号。 4.生成工程设置好参数,我们生成keil工程。
代码解析生成的工程含有三个文件,分别是GPIO配置、定时器配置、中断相关文件。 gpio.c文件
这个文件主要是配置GPIO口,之前在STM32CubeMX设置的参数这里已经自动生成了,而且pin引脚也定义成了我们输入的标签TRIG_Pin和ECHO_Pin。 tim.c文件
这是定时器初始化函数,比较重要的是设置预分频和计数值,19999和4999值。
这个是定时器中断回调函数,相当于定时中断就是进入这里执行代码。代码写在 /* USER CODE BEGIN TIM6_MspDeInit 0 */之间。 增加代码前面都是CubeMX之间生成的工程文件,现在需要我们自己添加代码启动超声波模块。在tim.c文件添加两个启动和停止函数。
start经常用了HAL两个库函数,第一个函数作用是把TIMx_CNT 寄存器的计数值清0,第二个函数就是启动定时器更新中断。 设置的计数值是4999,也就是0-4999计数5000次。一次0.1ms,总共计时0.5s进入中断,0.5s*340m/s/2等于85m。因为项目实验不需要测这么远,所以虽然我开了中断,但是这次实验并没有用到中断,而是在中断前就停止定时器。 我们通过__HAL_TIM_GetCounter函数得到TIMx_CNT寄存器的当前值,然后通过公式就可以算出距离。因为在循环测量距离当中并没有对定时器初始化进行循环,所以CNT的值并不会自动归0,这就是为什么start函数里面有清0操作__HAL_TIM_SetCounter(&TIM_Base,0)的原因。 建立echo.c文件存放超声波相关函数,如下。
读取ECHO状态使用的是HAL_GPIO_ReadPin()函数,这个也是HAL自带的读取引脚状态的函数,返回值为0或1。
当ECHO为0时,说明还没有信号返回,就while循环等待。如果ECHO变为1,会跳出循环,启动定时器,然后需要等待。如果ECHO从1到0,就会跳出循环,然后结束定时器计算距离。最后printf输出串口助手。 可以改进的方面如果需要测量的距离大于85m怎么办,那就在中断函数里面计数,一次中断85m,两次中断170m,然后加上通过CNT算的距离,就是完整的距离。 一次计数是0.1ms,对应的距离是3.4cm,所以距离的分度值是3.4cm,测出的距离一定是它的倍数。如果想要增加精度,就需要把一次计数的时间0.1ms调小。通过公式TIMxCLK/(TIM_Prescaler+1)得知,我们把Prescaler调高,就可以增大定时器时钟频率,降低时钟周期。如果Prescaler取最小0,那定时器频率为200MHZ,一次计数的时间为1/200M=0.5*10负八次方s,对应的距离是1.7微米。 |
|
嵌入式 最新文章 |
基于高精度单片机开发红外测温仪方案 |
89C51单片机与DAC0832 |
基于51单片机宠物自动投料喂食器控制系统仿 |
《痞子衡嵌入式半月刊》 第 68 期 |
多思计组实验实验七 简单模型机实验 |
CSC7720 |
启明智显分享| ESP32学习笔记参考--PWM(脉冲 |
STM32初探 |
STM32 总结 |
【STM32】CubeMX例程四---定时器中断(附工 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 18:54:03- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |