单片机c语言中逻辑相同, 写法不同导致的结果不同.

完整的函数代码如下.

void GetDistanceDelay(void)
{


    dis_count=0;

	GPIO_PinState ChaoShengBo_Echo_Pin_state;
    //Trig_SET;
	__HAL_TIM_SET_COUNTER(&htim4, 0);
	HAL_GPIO_WritePin(ChaoShengBo_Trig_GPIO_Port, ChaoShengBo_Trig_Pin,GPIO_PIN_SET); // RESET 在这个器件中才是输出高电平
	while(__HAL_TIM_GET_COUNTER(&htim4) < 110);  //延时超过10us
    HAL_GPIO_WritePin(ChaoShengBo_Trig_GPIO_Port, ChaoShengBo_Trig_Pin,GPIO_PIN_RESET);// SET 在这个器件中是输出低电平

//    while(__HAL_TIM_GET_COUNTER(&htim4) < 12);  //延时超过10us
    uint32_t timeout_start =0;

    //等待回应信号起始,开始计时位置
   timeout_start = HAL_GetTick();
//    while( HAL_GPIO_ReadPin(ChaoShengBo_Echo_GPIO_Port, ChaoShengBo_Echo_Pin)== GPIO_PIN_SET)
   while(1)
    {
	   ChaoShengBo_Echo_Pin_state   = HAL_GPIO_ReadPin(ChaoShengBo_Echo_GPIO_Port, ChaoShengBo_Echo_Pin) ;
		if(ChaoShengBo_Echo_Pin_state == GPIO_PIN_SET)
		{ 
			break;
		} 
		if(HAL_GetTick() - timeout_start > 20) //回应时间超出正常范围
		{
			status = 0;
			distance_cm = -10; //失败后就后退
			//HAL_TIM_Base_Stop(&htim4);
			return;//本次失败
		} 
    }

     __HAL_TIM_SET_COUNTER(&htim4, 0);
    //while(1)//开始计算长度
    while(HAL_GPIO_ReadPin(ChaoShengBo_Echo_GPIO_Port, ChaoShengBo_Echo_Pin)== GPIO_PIN_RESET )//开始计算长度
    {
//    	ChaoShengBo_Echo_Pin_state   = HAL_GPIO_ReadPin(ChaoShengBo_Echo_GPIO_Port, ChaoShengBo_Echo_Pin) ;
//    	if(ChaoShengBo_Echo_Pin_state == GPIO_PIN_SET)
//    	{
//    		 //继续等待超声波信息返回距离信息
//    		continue;
//    	}

		if(HAL_GetTick() - timeout_start > 500)//500ms 以上回应时间超出正常范围
		{
			status = 0;
			distance_cm = -10;//失败后就后退
//			HAL_TIM_Base_Stop(&htim4);
			return;//本次失败
		}
		else
		{
			break;
		}
    }

    dis_count = __HAL_TIM_GET_COUNTER(&htim4);
    //HAL_TIM_Base_Stop(&htim4);
    //距离= (高电平时间(单位秒) * 340M/s) /2
//    distance_cm = (unsigned int)(((long)(dis_count) * 34)/2000);//声速340m/s
    double tim_duty=1.0/64000000.0;
    double time_s= dis_count * tim_duty ;

    distance_cm =( time_s * 340.0) /2.0/100.0;//声速340m/s

    if(distance_cm > 2)
    {
    	HAL_GPIO_WritePin(FengMingQi_GPIO_Port, FengMingQi_Pin , GPIO_PIN_RESET);// 响
    	HAL_Delay(distance_cm);
    	HAL_GPIO_WritePin(FengMingQi_GPIO_Port, FengMingQi_Pin , GPIO_PIN_SET);// 不响
    }

    status = 0;//准备下次发送
}

这个代码是用来驱动超声波传感器计算距离的代码.
问题出在第二个 while(1) 这里.
如上所写, 在循环中不断的判断 超声波的Echo引脚是否进入高电平,
如果超过指定时间就视为超时,不再继续等待, 否则就卡死单片机了.
事实运行结果却是, 用于也接收不到高电平的到来.

下面的是能正确等到高电平到来的老代码.

while( HAL_GPIO_ReadPin(ChaoShengBo_Echo_GPIO_Port, ChaoShengBo_Echo_Pin)== GPIO_PIN_SET) 

我猜测, while(1) 中因为代码过多,期中某一步的执行时间超过了信号的反馈时间. 等它取到第一个电平信号的时候, 反馈信号应该已经过去了. 所以等不到信号的到来.

你可能感兴趣的:(c语言,单片机,stm32)