基于STM32的超声波传感器测距(含代码)

        上学期写的嵌入式系统课程实验报告中超声波传感器设计部分, 在此分享一下~

1. 实验原理

        超声波传感器采用的是HC-SR04,具有VCC、GND、Trig、Echo四个引脚,其使用方法为:将Trig 设置为高电平并保持至少10us,传感器将发出 8 个脉冲的声波。对于声波产生回声所需的整个时间内, Echo 为高电平。测量该高电平时间即可知经过的时间,则可计算障碍物的距离。

         测量Echo 为高电平的时间是利用STM32的通用定时器进行输入捕获,测量得到的高电平时间通过公式:距离 =  Thigh *340/2 (m) ,其中Thigh 单位为秒(s), 340米/秒(m/s)为声速。

2. 设计分析

        由STM32F4xx数据手册可知,所采用的板子有TM2-TM5四个通用定时器,该设计中采用TIM3定时器(16位)。它具有输入捕获模式、输出比较模式、单脉冲模式等多种功能模式,其中,输入捕获模式可以设置捕获上升沿或下降沿对输入信号进行捕获,发生捕获事件时,当前计数值可被获得,如果已使能中断则可触发中断。本设计采用输入捕获模式对Echo信号进行捕获与计时。

        根据HC-SR04数据手册得知,该超声波传感器射程为2cm-4m,代入距离公式中可得Thigh的范围大致为0.0235~ 0.0002857s,即1/Thigh的范围在42.5-8500Hz之间,故选择计数器时钟1MHz即可满足要求。

3. 设计过程

1. 用 STM32CubeMX配置对应引脚生成项目代码。

1)配置引脚

在左端设置TIM3为内部时钟输入,并使能通道1,可以看到右边PA6变为绿色,在电路图中寻找PA6对应的外部引脚编号为D12,该引脚将连接超声波传感器的Echo引脚,为方便器件连接,选择D12相邻的外部引脚D11作为输出与Trig连接,故配置D11相应的引脚PA7为GPIO输出。引脚配置图与电路图见下方所示。

图1 引脚配置图

图2 引脚对应电路图

2)配置计时器TIM3参数

      板子没有焊外部晶振,故时钟源选用HIS,定时器时钟频率为16MHz。如下图所示。

图3 时钟配置图

         定时器TIM3参数配置如下图所示,预分频系数位15,即TIM3定时器最后频率为16 MHz/(15+1)=1MHz;最大计数值为0xffff(65535),并在NVIC中开启中断。 

图4 TIM3参数配置图

3)生成项目代码

2. 用Keil打开生成的项目代码,增加处理逻辑代码

1)首先定义捕获次数capture_cnt,捕获计数值capture_value1,capture_value2,及高电平时间hightime与距离distance。

2)查看HAL库中关于TIM的函数,在主函数的while 中添加以下代码。根据捕获次数进行不同操作。当捕获次数为0时,使能TIM3中断模式的输入捕获,并设置其触发捕获方式为上升沿触发;当发送捕获时,进入捕获中断函数(其中中断函数为自动生成的,里面调用了触发回调函数,故可直接在回调函数中处理),在捕获回调函数中获取当前计数值赋给capture_value1,再更改捕获方式为下降沿触发;当再次发生捕获时,将当前计数值赋给capture_value2,然后停止输入捕获。在主函数中,根据capture_value1和capture_value2直接的差值即可得到时间,再代入距离公式便求得距离。

 

 3)在主函数的while循环中打开串口接收,判断接收到的数据为00时,进行距离测量:给超声波模块的Trig引脚一个高电平。

 

此处附上项目代码以供参考:

STM32超声波测距代码-HC-SR04.zip_stm32超声波测距-嵌入式文档类资源-CSDN下载

  • 80
    点赞
  • 603
    收藏
    觉得还不错? 一键收藏
  • 39
    评论
您好!下面是一个简单的使用STM32F4的超声波模块进行测距的示例代码: ```c #include "stm32f4xx.h" #include "stdio.h" #define TRIG_PIN GPIO_Pin_0 #define ECHO_PIN GPIO_Pin_1 #define TRIG_PORT GPIOA #define ECHO_PORT GPIOA void Delay_us(uint32_t us) { uint32_t i; for(i = 0; i < us * 9; i++); } void Delay_ms(uint32_t ms) { uint32_t i; for(i = 0; i < ms * 9000; i++); } float GetDistance(void) { GPIO_SetBits(TRIG_PORT, TRIG_PIN); Delay_us(20); GPIO_ResetBits(TRIG_PORT, TRIG_PIN); while(!GPIO_ReadInputDataBit(ECHO_PORT, ECHO_PIN)); TIM_Cmd(TIM2, ENABLE); while(GPIO_ReadInputDataBit(ECHO_PORT, ECHO_PIN)); TIM_Cmd(TIM2, DISABLE); return (float)(TIM_GetCounter(TIM2) / 58.0); } int main(void) { GPIO_InitTypeDef GPIO_InitStruct; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStruct.GPIO_Pin = TRIG_PIN; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz; GPIO_Init(TRIG_PORT, &GPIO_InitStruct); GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStruct.GPIO_Pin = ECHO_PIN; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz; GPIO_Init(ECHO_PORT, &GPIO_InitStruct); TIM_TimeBaseInitTypeDef TIM_InitStruct; TIM_InitStruct.TIM_Prescaler = 84 - 1; TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_InitStruct.TIM_Period = 0xFFFFFFFF; TIM_InitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInit(TIM2, &TIM_InitStruct); while(1) { float distance = GetDistance(); printf("Distance: %.2f cm\n", distance); Delay_ms(500); } } ``` 这段代码使用了STM32F4的GPIO模块和TIM2定时器模块来实现超声波测距功能。其中,TRIG_PIN和ECHO_PIN分别连接超声波模块的Trig和Echo引脚,TRIG_PORT和ECHO_PORT是相应的GPIO端口。 该代码在主循环中通过调用GetDistance函数获取超声波测量的距离,并使用printf函数打印到串口调试助手上。您可以根据实际情况进行修改。 请注意,此代码只是一个简单的示例,并且假设您已经正确配置了GPIO和定时器的引脚和时钟。在使用前,请确保您已经正确配置了相关的GPIO引脚和定时器,并根据实际情况进行修改适配。 希望对您有所帮助!如有任何问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 39
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值