e小白

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 352|回复: 2

STM32f103驱动超声波测距模块

[复制链接]

1

主题

4

帖子

36

积分

新手上路

Rank: 1

积分
36
发表于 2021-4-2 07:08:29 | 显示全部楼层 |阅读模式
关键词:输入捕获 定时器 中断

使用的超声波测距模块型号为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进行输入捕获,即voidTIM2_Cap_Init(u16 arr,u16 psc)。

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



假设要捕获如图所示波形的脉宽:
1.先设置定时器为向上计数模式
2.设置定时器的采样通道channelx为上升下降沿捕获,所以在t1时刻,上升沿就会捕获到当前CNT的值,随即将CNT清零
3.t2时刻下降沿会捕获CNT的值,记为CCRx2
4.根据定时器的频率,以及期间溢出的次数,即可算出|t1-t2|的时间,从而得到高电平脉宽。
输入捕获原理转自csdn文章:[stm32]stm32F4输入捕获原理
关于自动重装载值arr和预分频系数psc的设置:
溢出时间Tout=((arr+1*psc+1))/Tclk
TclkTIM2输入时钟频率
根据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:%fcm\r\n",distance);       //打印距离
                         TIM2CH1_CAPTURE_STA=0;                   //开启下一次捕获
                }
         }
}
附上一张实物图

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

0

主题

1

帖子

18

积分

新手上路

Rank: 1

积分
18
发表于 2021-4-20 17:11:46 | 显示全部楼层
多看多学习
回复

使用道具 举报

1

主题

4

帖子

36

积分

新手上路

Rank: 1

积分
36
 楼主| 发表于 2021-4-21 09:39:26 | 显示全部楼层
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|e小白

GMT+8, 2021-6-24 04:47 , Processed in 0.042945 second(s), 23 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表