解决STM32避障小车HC-SR04超声波模块程序卡死问题

        能找到这的肯定是找了好久没找到问题的,代码就不介绍了,直接说问题。

        单独使用HC-SR04测距没问题,但涉及到测距控制小车移动就会卡死(能找到这的应该都知道),经过我的测试,卡在了等待接收超声波返回信号这行代码,只需要再增加一个计时变量(和超声波计时变量同步计时),放在中断里++,然后这个变量放在等待接收超声波信号这行代码中if时间大于等待时间就break;这个等待时间可以自己设置。

        举个例子,下面是我的代码,我增加了个T用来计时,10us进一次中断,我的主程序中,小车距离障碍物大于200mm就前行,如果T设置成T*10/1000=38ms的话,卡死的时候就要卡38ms,小车就认为距离前方障碍物4米,如果前方有障碍物就会撞上去,所以我T设置成1995(小车认为距离前方障碍物210mm),小车就会快点的脱离卡死,并且210mm大于200mm,小车还是前进。简单说这句话的逻辑就是:如果T=1995,超声波没有返回 ,认为前方无障碍物,退出等待信号循环,小车前进(我代码有写手动翻转电平)。我就是这样防止卡死,当然这个防卡死时间我这个不一定是最合适的,大家根据自己的实际情况自己配置,希望对大家有所帮助。能力有限,有不足之处还望谅解。

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "Timer1.h"

#define Trig GPIO_Pin_0		//HC-SR04模块的Trig脚接GPIOA1
#define Echo GPIO_Pin_1		//HC-SR04模块的Echo脚接GPIOA2

uint64_t Time=0,T=0;	//用来计时
uint64_t Time_end=0;	//接收保存计时,用来对比

void HC_SR04_Init(void)	//超声波检测
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;	//推挽输出
	GPIO_InitStructure.GPIO_Pin=Trig;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	GPIO_WriteBit(GPIOA,Trig,Bit_RESET);	//先将端口拉低防止干扰
	Delay_us(15);
	
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;	//下拉输出
	GPIO_InitStructure.GPIO_Pin=Echo;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	Timer1_Init();	//开启定时器中断
}

uint16_t HC_SR04_Time(void)	//计算距离
{
	uint32_t distance_mm=0;	//距离
	GPIO_WriteBit(GPIOA,Trig,Bit_SET);	//给至少10us高电平启动模块
	Delay_us(50);	
	GPIO_WriteBit(GPIOA,Trig,Bit_RESET);	//输出低电平
	TIM_Cmd(TIM2,ENABLE);	//开启TIM2定时器
	while(GPIO_ReadInputDataBit(GPIOA,Echo)==0)
	{
		Time=0;	//低电平未开始time为0
		if(T>1995)
		{
			break;
		}
	}	
	GPIO_WriteBit(GPIOA,Echo,Bit_SET);    //输出高电平
	while(GPIO_ReadInputDataBit(GPIOA,Echo)==1){Time_end=Time;}	//高电平开始计时time增加赋值给Time_end	
	TIM_Cmd(TIM2,DISABLE);	//关闭TIM2定时器
	TIM_SetCounter(TIM2,0);	//计数器清零
	T=0;    //防卡死计时清零
	if(Time_end/100<38)
	{
		distance_mm=(Time_end*346)/200;	//距离计算,声音在25℃空气中传播速度为346mm/ms	
	}
	return distance_mm;
}

void TIM2_IRQHandler(void)	//TIM2中断函数
{
	if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
	{	
		Time++;	
		T++;
	}	
	TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}

作者:淡淡成仙

物联沃分享整理
物联沃-IOTWORD物联网 » 解决STM32避障小车HC-SR04超声波模块程序卡死问题

发表评论