一、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);
}
}