首先要说明一下原理:使用stm32无法准确产生1us的时间,但是超声波测距一定要依赖时间,时间不准,距离一定不准,这是要肯定的,但是在不准确的情况下,要测量一个比较准确的时间,那么只能够把误差控制在一定范围内,这就是基本思想。
经过实验,获得实验数据如下:
这是delay_us(50)时候获取的实验数据:
这是delay_us(100)时候获取的实验数据:
可以发现结论并不像我们预想的那样平均delay_us(1)会产生非常的的误差,因为delay_us(1)花费了20us的时间,误差20倍是无论如何不可接受的。如果要画出一条曲线来表示,那么会类似于一条这样的:
写到这里就不用再怎么写了,已经很清楚了
下面写一点废话:通过观察可以发现:超声波测距在距离进的时候不准确,因为此时通过观察曲线可知,误差很大,当距离远的时候精度会诸将提高,直到超出测量范围。可以预料到精度会再次下降,如果要画出来一条曲线应该类似于这个样子;
此图片中不包含2线之间的相对关系
再来看这个表:
假设声波不受温度映像设此时为340m/s,那么100us来回的距离,那个检测到的物体离我们的距离是多少:340 /1000 000 x 100 / 2 =0.017m=1.7cm,也就是说此时候的距离是1.7厘米,也就是说当物体离我们1.7cm时候,误差和已经控制在10%,而且会越来越小,所以超声波模块有效测量距离应该符合说明书上面的:2cm--3m,即是说当物体处于2cm--3m范围内的时候,是准确的
这个就是我用的delay_us函数,使用了内部时钟8MHZ
void delay_us(uint32_t ii)
{
uint32_t temp;
SysTick->LOAD=ii;
SysTick->VAL=0x00;
SysTick->CTRL=0x01;//2号位1使用内核时钟
do
{
temp=SysTick->CTRL;
}
while(temp&0x01&&!(temp&(1<<16)));
SysTick->CTRL=0X00;
SysTick->VAL=0X00;
}
那个实在不好意思说一点,本来8MHZ按照我的理解,那个ii应该要乘以8就是Systick->LOAD=ii*8;
但是不知道为什么这里就是表现为不用乘以8的时候是对的,即使用这个函数产生1s的时间,还是对的,所以我就不管了,方正就是这样就可以用了
那么是不是便宜的单片机质量不合格?
不是这样的,当使用keil arm模拟的时候得出了同样的结论,所以可以判定这个算子是正确的,只是暂时不知道原因
后来我又看到一些东西:
- 观点一:超声波测量最好是测量一个平面,才会准确些,另外超声波并不是测量一个点到点距离,超声波测量是与中轴线有一个角度的,它是一个圆锥形的发散出去,所以旁边的东西都可能影响到。你如果想测量点的话,用激光可能还好些
- 观点2:超声波测距本来测平面的东西就准确,人体是不规则的,超声波测不准,而且超声波测距不适合远距离,测人体可以用人体红外模块
- 观点3:反射声波的物体的形状和材质会有影响,多次测量移除最大最小值取平均
总而言之:这个东西不太精确,但是可以用来判断附近是不是有物体,可以用于ros2下位机或者stm32智能小车的避障。
int main(void)
{
int beginTime=0,endTime=0;
int radari=0;
int distance_cm;
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
//
radari=0;
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,1);
delay_us(12); //实际花费了20us
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,0);
while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_2)==0);
while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_2)==1)
{
radari++;
delay_us(50);
}
distance_cm=340.0/1000000*(50*radari)/2;//这个就是测量的距离
radari=0;
//
}
/* USER CODE END 3 */
}