【STM32】输入捕获实现超声波测距
1.超声波测距原理
(超声波发出到 遇到障碍物反弹回来的时间)*声速/2就是到障碍物的距离
操作过程:
单片机给TRIG引脚输出一个脉冲,然后超声波模块会将ECHO电平拉高,当超声波遇到障碍物回来时,ECHO电平就会被拉低,而ECHO高电平的时间就是2倍的距离
读取高电平的时间我们可以使用下面代码:
2.输入捕获
开启计数器,对于TI1可以输入一个波形,我们可以用TI1来检测输入的波形中的上升沿,当遇到上升沿时,捕获寄存器1就会拷贝计数器的值,如果还开启捕获中断,就会使其立即去处理,我们可以使用ECHO将其波形输入TI1,来捕获ECHO上升沿时的计数,也同样TI1有一个TI1FP2,就 不用再将波形输入带TI2中就可以让捕获寄存器2来记录当ECHO为下降沿时,捕获寄存器2拷贝到计数器的值,此时捕获寄存器1为直接模式,捕获寄存器2为间接模式
有人说计数可能会溢出,因为超声波测距,计数最大记65535,设置频率为72MHAZ,72分频,也就是1us计数一次,声速为0.034cm/us
65535*0.034/2=1114.095cm,也就是11m多,实际我们测不了那么远,所以就不用考虑溢出问题
3.初始化
PA11设置输出模式输出脉冲
开启定时器1捕获比较中断,让通道4检测下降沿立刻处理
char message[50]="";
int begin=0;
int end=0;
float dis=0.0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim==&htim1&&htim->Channel==HAL_TIM_ACTIVE_CHANNEL_4)//如果是定时器1并且通道四捕获中断
{
begin=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_3);//获取捕获寄存器3的值
end=HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_4);//获取捕获寄存器4的值
dis=((end-begin)*0.034)/2;
}
}
int main(void)
{
OLED_Init();
HAL_TIM_Base_Start(&htim1);//开启定时器1计数
HAL_TIM_IC_Start(&htim1,TIM_CHANNEL_3);//开启定时器1输入捕获通道三
HAL_TIM_IC_Start_IT(&htim1,TIM_CHANNEL_4);//开启定时器1输入捕获通道四,加IT是因为当下降沿时直接在中断中处理转换距离
while (1)
{
HAL_GPIO_WritePin(Trig_GPIO_Port,Trig_Pin,GPIO_PIN_SET); //给Trig一个脉冲
HAL_Delay(1);
HAL_GPIO_WritePin(Trig_GPIO_Port,Trig_Pin,GPIO_PIN_RESET);
__HAL_TIM_SET_COUNTER(&htim1,0);//给计数器设置为0,方便
HAL_Delay(20);
OLED_NewFrame();
sprintf(message,"dis:%.2f",dis);
OLED_PrintString(10,10, message, &font16x16,OLED_COLOR_NORMAL);
OLED_ShowFrame();
HAL_Delay(500);
}
}