首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

STM32--超声波模块(HC—SR04)(标准库+HAL库)

  • 25-03-08 00:42
  • 4299
  • 11605
blog.csdn.net

一、HC-SR04工作原理

1)采用IO触发测距,给至少10us的高电平信号。

2)模块自动发送8个40KHz的方波,自动检测是否有信号返回。

3)有信号返回,通过IO输出一高电平,高电平持续时间就是超声波从发射到返回的时间声波从发

射到返回的时间。

4)HC-SR04超声波测距模块提供2cm~400cm的测距功能,精度达3mm。

二、实物介绍


以下图片截取自深圳市捷深科技有限公司的《HC-SR04超声波测距模块说明书》:

VCC         3.3-5V供电(推荐5V供电)

GND        接地

Trig          外部触发信号输入,输入一个高于10μs的高电平即可触发模块测距

Echo        回响信号输出,测距结束时此管脚输出一个低电平,电平宽度反映超声波往返时间之和

三、工作说明

1、触发信号Trig直接通过IO输出和延时给一个大于10us的高电平即可触发。

2、Echo引脚需要接收并记录高电平的持续时间。

3、在发送触发信号后,Echo响应后(上升沿)触发外部中断,开启定时器计时直到Echo变为低电

平,关闭定时器记录下计时时间。

4、实际应用,如果需要精确距离值,必需要考虑温度影响,做温度补偿。

distance = time * 0.017

距离=T*C/2(C 为声速)

声速温度公式:c=(330.45+0.61t/℃)m/s-1    (其中330.45是在0℃)

0℃声速:330.45m/s        20℃声速:342. 62m/s        40℃声速:354.85M/S

四、标准库工作代码

我一般使用标准库较少,使用代码时请注意检查

使用OLED显示,OLED使用可以看:

STM32--SPI&IIC使用OLED-CSDN博客

  1. uint32_t distance;
  2. while(1)
  3. {
  4. distance = 0;
  5. for(int i=0;i<10;++i)
  6. { //每次取10次测距数据,取平均值减少误差
  7. GPIO_SetBits(GPIOA,GPIO_Pin_6);
  8. Delay_us(15); //需要提供至少10us的高电平
  9. GPIO_ResetBits(GPIOA,GPIO_Pin_6);
  10. Delay_ms(70); //每个周期至少需要等待60ms
  11. distance+=(times/5.8); //获取单位为mm的距离
  12. }
  13. distance/=10;
  14. OLED_ShowNum(2,1,distance,4); //使用OLED显示
  15. }
  16. //定时器中断函数
  17. //72MHz/72/100=1000,每秒定时器计数1000个,因此每个计数为100us
  18. void TIM2_IRQHandler(void)
  19. {
  20. if(SET==TIM_GetITStatus(TIM2,TIM_FLAG_Update))
  21. {
  22. number++; //每次中断将次数++
  23. TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update);
  24. }
  25. }
  26. //外部中断函数,利用外部中断检测高低电平变化来控制定时器开关
  27. void EXTI9_5_IRQHandler(void)
  28. {
  29. if(SET==EXTI_GetITStatus(EXTI_Line7))
  30. {
  31. if(flag==0)
  32. {
  33. //上升沿即回响电平开始,打开计数器
  34. number=0;flag=1;
  35. TIM_SetCounter(TIM2,0);
  36. TIM_Cmd(TIM2,ENABLE);
  37. }
  38. else
  39. {
  40. //下降沿即回响电平结束,统计高电平持续时长
  41. TIM_Cmd(TIM2,DISABLE);
  42. flag=0;
  43. times=number*100+TIM_GetCounter(TIM2); //得到回响的高电平持续的us
  44. }
  45. EXTI_ClearITPendingBit(EXTI_Line7);
  46. }
  47. }

五(1)、HAL--CubeMX配置

GPIO配置(Trig端口):设置PA1为触发端(可更改为其他GPIO口)。单击芯片的PA1引脚会跳

出选择项,选择GPIO_Output,即为GPIO输出。

定时器配置(Echo端口):为方便计算定时器的分频系数和定时周期,将APB1设置为50MHz。

先设置TIM2的通道1位直接模式输入捕获,在参数设置中设置预分频为71,通过计算分频器输出的

时钟信号频率为1000kHz,通过换算得到1us,极性为上升沿触发。设置完成后自动引出PA0引

脚,即为接收端引脚Echo,使能NVIC中断。

USART1配置:串口输出显示结果,设置为异步模式,波特率为115200Bits/s,

RX--PA10//TX--PA9

五(2)、HAL库工作代码

1、HCSR04.h

  1. #ifndef __HCSR04_H
  2. #define __HCSR04_H
  3. #include "main.h"
  4. //#include "tim.h"
  5. #include "stdio.h"
  6. #define TRIG_H HAL_GPIO_WritePin(Trig_GPIO_Port,Trig_Pin,GPIO_PIN_SET)
  7. #define TRIG_L HAL_GPIO_WritePin(Trig_GPIO_Port,Trig_Pin,GPIO_PIN_RESET)
  8. void delay_us(uint32_t us);
  9. void HCSR04_GetData(void);
  10. #endif

2、HCSR04.c

  1. #include "HCSR04.h"
  2. float distance; //测量距离
  3. uint32_t Buf[3] = {0}; //存放定时器计数值的数组
  4. uint8_t Cnt = 0; //状态标志位
  5. uint32_t high_time; //超声波模块返回的高电平时间
  6. //读取距离
  7. void HCSR04_GetData(void)
  8. {
  9. switch(Cnt)
  10. {
  11. case 0:
  12. TRIG_H; //发送信号
  13. delay_us(30);
  14. TRIG_L;
  15. Cnt++; //标志位为1
  16. __HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);
  17. HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); //开启TIM2
  18. //启动输入捕获或者:__HAL_TIM_ENABLE(&htim5);
  19. break;
  20. case 3:
  21. high_time = Buf[1]- Buf[0]; //计算高电平时间
  22. printf("\r\n----高电平时间-%d-us----\r\n",high_time); //串口打印时间
  23. distance=(high_time*0.034)/2; //计算距离单位cm
  24. printf("\r\n-检测距离为-%.2f-cm-\r\n",distance); //串口打印距离
  25. Cnt = 0; //清空标志位
  26. TIM2->CNT=0; //清空计时器计数
  27. break;
  28. }
  29. }
  30. //中断回调函数
  31. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
  32. {
  33. if(TIM2 == htim->Instance)// 判断触发的中断的定时器为TIM2
  34. {
  35. switch(Cnt)
  36. {
  37. case 1:
  38. //获取当前的捕获值
  39. Buf[0] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);
  40. //设置为下降沿捕获!!!
  41. __HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);
  42. Cnt++;
  43. break;
  44. case 2:
  45. //获取当前的捕获值
  46. Buf[1] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);
  47. HAL_TIM_IC_Stop_IT(&htim2,TIM_CHANNEL_1);
  48. //停止捕获或者: __HAL_TIM_DISABLE(&htim5);
  49. Cnt++; //此时标志位为3
  50. break;
  51. }
  52. }
  53. }

注:本文转载自blog.csdn.net的灯色_的文章"https://blog.csdn.net/2301_80163712/article/details/141354617"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

124
嵌入式
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top