STM32超声波测距:
上一篇提到了STM32输入捕获的初始化函数,(上一篇点击这里)输入捕获的一个重要用途就是测量电平时间,例如:超声波模块,本篇就通过上一篇的.h和.c文件来实现超声波测距。
其实只用外部中断也是可以实现超声波测距的,大致思路就是当高电平来的时候进入外部中断,将定时器计数器清零,然后低电平再次进入外部中断,读取CNT的值,同时设置一个标志位。然后只需要在主程序中检测这个标志位来读取CNT的值即可
但是我照着以上思路写程序,结果我自己的超声波模块一切正常,舍友的就不行,还以为是模块问题呢,结果用下面的程序,舍友的就有可以正常工作了。那就说明是程序的问题,具体是什么原因,哎我还是个菜鸡,能力有限啊!!我也不知道。
超声波模块.h文件:
#ifndef __CHAOSHENGBO_H__
#define __CHAOSHENGBO_H__
void chaoshengbo_Init(void);
uint16_t chaoshengbo_GetDistance(void);
#endif
超声波模块.c文件:
#include "stm32f10x.h" // Device header
#include "GuiStar_TIM.h"
#include "IO.h" //这个文件只是引脚初始化的,大家可以自己手动初始化
#include "Delay.h"
/*
引脚:
Trig:A1
Echo:A6
*/
/**
* @brief 超声波初始化
* @param 无
* @retval 无
*/
void chaoshengbo_Init(void)
{
GuiStar_IC_Init(TIM3);//输入捕获初始化函数(即将TIM3的一通道初始化为捕获通道准备捕获Echo的高电平时间)
IO_Out_PP_Init(GPIOA, GPIO_Pin_1);//初始化引脚A1(接超声波的Trig)为推挽输出
IO_OutPut(GPIOA, GPIO_Pin_1,0);//将A1(Trig)置低电平
}
/**
1. @brief 超声波测距(单位:厘米)
2. @param 无
3. @retval 距离
*/
uint16_t chaoshengbo_GetDistance(void)
{
IO_OutPut(GPIOA, GPIO_Pin_1,1);
Delay_us(10);
IO_OutPut(GPIOA, GPIO_Pin_1,0);//给超声波Trig发送一个10us的高电平
while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)==RESET);//等待Echo引脚变为高电平
while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)==SET);//等待Echo引脚变为低电平
//以上两步是的间隔就是Echo引脚高电平持续时间,可以用TIM_GetCapture2来获取这两个边沿
//的计数值,计数值的标准频率是1M,所以一个计数值就是1us,单位是us
Delay_ms(10);
return TIM_GetCapture2(TIM3)*0.034/2;//距离(单位:厘米)
}
总结:
以上就是超声波模块了。可以看出,封装了输入捕获之后,相比于外部中断测量高电平时间有两个优点:
- 代码更简洁
- 比外部中断更高效一点,因为输入捕获是定时器自动完成对高电平时间的测量;而外部中断则需要频繁的进入中断函数来清零定时器的计数值,这就会对主进程有一定的影响,并且我猜测舍友的超声波模块很可能就是因为这一点(当然也可能是其他原因,哈哈哈)