STM32 超声波模块输入捕获测距(标准库)

一、HC—SR04简介

超声波传感器模块上面通常有两个超声波元器件,一个用于发射,一个用于接收。

电路板上有四个引脚:VCC、GND、Trig(触发)、Echo(回应)。

工作电压与电流:5V,15mA

 感应距离:2~400cm

 感测角度:不小于15度

 被测物体的面积不要小于50平方厘米并且尽量平整

输入捕获原理可以看看这位大佬,感觉写的很清楚,

STM32之TIM输入捕获(IC)_stm32 tim1 输入捕获_韩立 •的博客-CSDN博客

下面这部分是超声波模块测距的实现

原理图:

分析:

通道1设置为上升沿触发,触发的瞬间会将CNT的值记录到CCR1里面,同时设置通道1触发带有从模式,并把从模式设置为置零CNT

通道2设置为下降沿触发,触发瞬间会将CNT的记录到CCR2中,由于上升沿触发时已经将CNT置零所以此时的CNT的值就是高电平的持续时间。

//通道一
	TIM_ICInitTypeDef TIM_IC_InitStructure;
	TIM_IC_InitStructure.TIM_Channel=TIM_Channel_1;//捕获通道一
	TIM_IC_InitStructure.TIM_ICFilter=0xF;//滤除高频波动
	TIM_IC_InitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;//上升触发捕获
	TIM_IC_InitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;//不分频
	TIM_IC_InitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;//直连通道
	TIM_ICInit(TIM3,&TIM_IC_InitStructure);
	
	//通道二
	TIM_IC_InitStructure.TIM_Channel=TIM_Channel_2;//捕获通道二
	TIM_IC_InitStructure.TIM_ICFilter=0xF;//滤除高频波动
	TIM_IC_InitStructure.TIM_ICPolarity=TIM_ICPolarity_Falling;//下降触发捕获
	TIM_IC_InitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;//不分频
	TIM_IC_InitStructure.TIM_ICSelection=TIM_ICSelection_IndirectTI;//交叉通道输入
	TIM_ICInit(TIM3,&TIM_IC_InitStructure);
	
TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);//触发从模式
  TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);//设置给CNT置0;注:reset功能,没触发一次高电平就重新计数*/
	

代码演示:

TIM.c

#include "stm32f10x.h"                  // Device header


void Timer_Init(void){
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	//Trig 输出引脚
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	GPIO_ResetBits(GPIOA,GPIO_Pin_5);//置为低电平,为后面作准备
	//Echo输入引脚
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;//下拉输入
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	//选择时基时钟
	TIM_InternalClockConfig(TIM3);//内部时钟 这步可要可不要
	//配置时基单元
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseInitStructure;	
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1  ;//设置时钟分频
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数
	TIM_TimeBaseInitStructure.TIM_Period=65536-1;//ARR 自动重装载计数值
	TIM_TimeBaseInitStructure.TIM_Prescaler=72-1;//psc   time=ARR*PSC)/72 
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;//重复计数——
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//初始化时基单元
	//通道一
	TIM_ICInitTypeDef TIM_IC_InitStructure;
	TIM_IC_InitStructure.TIM_Channel=TIM_Channel_1;//捕获通道一
	TIM_IC_InitStructure.TIM_ICFilter=0xF;//滤除高频波动
	TIM_IC_InitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;//上升触发捕获
	TIM_IC_InitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;//不分频
	TIM_IC_InitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;//直连通道
	TIM_ICInit(TIM3,&TIM_IC_InitStructure);
	
	//通道二
	TIM_IC_InitStructure.TIM_Channel=TIM_Channel_2;//捕获通道二
	TIM_IC_InitStructure.TIM_ICFilter=0xF;//滤除高频波动
	TIM_IC_InitStructure.TIM_ICPolarity=TIM_ICPolarity_Falling;//下降触发捕获
	TIM_IC_InitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;//不分频
	TIM_IC_InitStructure.TIM_ICSelection=TIM_ICSelection_IndirectTI;//交叉通道输入
	TIM_ICInit(TIM3,&TIM_IC_InitStructure);
	
	
	
	
	TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);//触发从模式
  TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);//设置给CNT置0;注:reset功能,没触发一次高电平就重新计数*/
	
	
	TIM_Cmd(TIM3,ENABLE);//启动定时器
	
}



Sound.c

uint32_t IC2_count;

void Sound_Init(void){
    Timer_Init();}


		
		
float GetLength(void){
	int i=0;
	
	float length=0;
	float sum=0;
	float Length;
	for(i=0;i<5;i++){//减小误差,计算五次
		 GPIO_SetBits(GPIOA,GPIO_Pin_5);
		 Delay_ms(20);//发送一段20m的高电平
		GPIO_ResetBits(GPIOA,GPIO_Pin_5);
		  IC2_count=TIM_GetCapture2(TIM3);
		  length=(IC2_count/58.0);//固定计算超声波距离公式:时间/58.0;单位厘米
		 sum=sum+length;
	}
	
	Length=sum/5.0;
	return Length;
	
	
	
}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "Sound.h"
#include "OLED.h"
#include "Timer.h"
float num; 
float val=0;
uint8_t a=0;
int main()
	
{
    OLED_Init();
	
	  Sound_Init();
	OLED_ShowString(1,1,"DISTANCE:");
	OLED_ShowString(2,6,"  .  cm");
	
	while(1){
		num=GetLength(); 
		a=(int)num;
		val=num-val;
    OLED_ShowNum(2,6,num,2);
		OLED_ShowNum(2,9,val,2);
		Delay_ms(400);
	}
	
}

  • 4
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值