欢迎光临散文网 会员登陆 & 注册

STM32f103驱动超声波测距模块

2021-04-02 13:18 作者:e小白官方  | 我要投稿

本文章作者为ldld(e小白网站用户名)。e小白网址:www.e-xiaobai.com。

关键词:输入捕获 定时器 中断


使用的超声波测距模块型号为US-015,该模块可实现2cm~4cm的非接触测距功能,供电电压为5v,工作电流为2.2mA,支持GPIO通信模式。

超声波测距模块实物图


 

模块引脚:

VCC引脚      接直流5V电源

Trig引脚        接外部电路的Trig端,向此管脚输入一个10us以上的高电平,触发模块测距

Echo引脚      接外部电路的Echo端,测距结束时,此管脚会输出一个高电平,电平宽度为超声波往返时间之和

GND引脚       接外部电路的地

 

测距原理:

(1)给模块Trig引脚至少10us的高电平信号触发测距

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

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

测试距离=(高电平时间*声速)/2


 

时序图

 

硬件连接:

使用正点原子的stm32mini板子来驱动超声波US-015模块

超声波测距模块                STM32mini

VCC                                  VCC5(VOUT2)

Trig                                    PA8

Echo                                  PA0

GND                                  GND(VOUT2)

 

驱动程序:

(1)点亮LED0时PA8发出高电平,这里给Trig引脚20ms的高电平,触发模块测距    

LED0=1;

                  delay_ms(20);

                  LED0=0;

(2)用输入捕获模式来测量脉冲宽度,参考正点原子的输入捕获实验,配置定时器2的通道1进行输入捕获,即void TIM2_Cap_Init(u16 arr,u16 psc)。

 

捕获原理:通过两次捕获(一次上升沿捕获,一次下降沿捕获)的差值,就可以计算出高电平脉冲的宽度。同时,如果脉宽比较长,那么定时器就会溢出,需要对溢出做处理。

 

 

输入捕获原理图


                           

假设要捕获如图所示波形的脉宽:

1.先设置定时器为向上计数模式

2.设置定时器的采样通道channelx为上升下降沿捕获,所以在t1时刻,上升沿就会捕获到当前CNT的值,随即将CNT清零

3.在t2时刻下降沿会捕获CNT的值,记为CCRx2

4.根据定时器的频率,以及期间溢出的次数,即可算出|t1-t2|的时间,从而得到高电平脉宽。

输入捕获原理转自csdn文章:[stm32]stm32F4输入捕获原理

原文链接:https://blog.csdn.net/slimmm/article/details/82850898

 

关于自动重装载值arr和预分频系数psc的设置:

溢出时间Tout=((arr+1)*(psc+1))/Tclk

Tclk为TIM2输入时钟频率

根据stm32内部时钟树得知:当APB1的时钟分频数为1的时候,TIM2~7 的时钟为APB1的时钟

而如果 APB1 的时钟分频数不为 1,那么TIM2~7 的时钟频率将为 APB1 时钟的两倍,因此,TIM2的时钟为 72MHz

这里设置arr=0xFFFFpsc=7199

即将72MHz时钟7200分频后变为10KHz,用这10KHz的时钟作为定时器的基准时钟,然后计数0xFFFF个数后,产生一次定时器中断。

 

(3)主函数通过 TIM2CH1_CAPTURE_STA 的第 7 位,来判断有没有成功捕获到一次高电平,

如果成功捕获,则将高电平时间通过串口输出到电脑。

TIM2CH1_CAPTURE_STA 各位描述

bit7                            bit6                                    bit5~0

捕获完成标志         捕获到高电平标志         捕获高电平后定时器溢出的次数

 

测量结果:

测量结果


 

以下是main.c程序(库函数版本)

#include "led.h"

#include "delay.h"

#include "sys.h"

#include "timer.h"

#include "usart.h"

 

extern u8  TIM2CH1_CAPTURE_STA;           //输入捕获状态(变量当成寄存器使用)                   

extern u16       TIM2CH1_CAPTURE_VAL;      //输入捕获值

 

 int main(void)

 {    

         float distance;

         u32 temp=0;

         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2

         delay_init();                   //延时函数初始化      

         uart_init(9600);                                //9600      

         LED_Init();                      //初始化与LED连接的硬件接口

      TIM2_Cap_Init(0XFFFF,7200-1);             //以10khz的频率计数

     while(1)

         {

                  LED0=1;

                  delay_ms(20);

                  LED0=0;

                           

                  if(TIM2CH1_CAPTURE_STA&0X80)//成功捕获到了一次高电平

                  {

                          temp=TIM2CH1_CAPTURE_STA&0X3F;//得到捕获高电平后定时器溢出次数

 

                          temp*=65536;                                            //溢出时间总和

                          temp+=TIM2CH1_CAPTURE_VAL;         //得到总的高电平时间

                          distance=(temp*340)/2;        //得到距离,单位:m

                          printf("DISTANCE:%f cm\r\n",distance);       //打印距离

                         TIM2CH1_CAPTURE_STA=0;                   //开启下一次捕获

                }

         }

}

附上一张实物图

实物图




STM32f103驱动超声波测距模块的评论 (共 条)

分享到微博请遵守国家法律