超声波US-025A

Posted on 2026-09-23 11:24  Fosi  阅读(13)  评论(0)    收藏  举报

需要掌握的知识点

接线

Pin 接线
1 接 VCC 电源(直流 3V-5.5V)
2 接外部电路的输出端,向此超声波管脚输入一个10uS 以上的高电平,可触发模块测距
3 接外部电路的输入端,当测距结束时,此管脚会输出一个高电平,电平宽度为超声波往返时间之和
4 接地

具体流程

graph LR; A[STM32]-.-gpio推挽输出--高电平触发-->Trig-.-B[超声波]
graph RL; B[超声波]-.-Echo--高电平返回-->gpio浮空输入-.-A[STM32]

测距工作原理

测量范围内有障碍物的情况

超出测量范围的情况

距离计算

根据Echo 管脚输出高电平的持续时间t可以计算距离值。
距离值=( t * 340m/s ) / 2

Q:如何求t?
A:定时器

int overnum = 0;//定时器溢出数
void TIM3_Init() //定时器3初始化
{
  GPIO_InitTypeDef GPIO_InitStruct;
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  NVIC_InitTypeDef NVIC_InitStructure;

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //超声波使能

  //A6作为Trig的触发口,A7作为Echo的接收口
  GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
  GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6;
  GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
  GPIO_Init(GPIOA,&GPIO_InitStruct);

  GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPD;
  GPIO_InitStruct.GPIO_Pin=GPIO_Pin_7;
  GPIO_Init(GPIOA,&GPIO_InitStruct);
  	
  	
  //定时器3初始化
  TIM_TimeBaseStructure.TIM_Period = 999; //设置自动重转载值为999,记0.001秒溢出一次
  TIM_TimeBaseStructure.TIM_Prescaler =71; //设置预分频系数
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//滤波时的时钟不分频
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

  TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );//使能制定TIM3中断,允许更新中断

  //中断设置
  NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  TIM_Cmd(TIM3, DISABLE);
 }

  void TIM3_IRQHandler(void)
  {
      if (TIM_GetITStatus(TIM3,TIM_IT_Update)!= RESET) //检查是否发生TIM3中断
      {
       overnum++;定时器溢出数加1
       TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除中断更新标志
      }
  }

  //下面写测距函数
  float Senor_Using(void) //单精度数据类型
 {
  float length=0;
  uint16_t tim;//获取TIM3的计数值
  GPIO_WriteBit(GPIOA, GPIO_Pin_6, (BitAction)(1));//拉高电平,作为触发信号
  Delay_us(20); //高电平信号超过10us
  GPIO_WriteBit(GPIOA, GPIO_Pin_6, (BitAction)(0)); //等待回响信号
  while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)==RESET);//收到高电平回响信号跳出死循环
  //回响信号到来,开启定时器计数
  TIM_Cmd(TIM3,ENABLE);
  while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)==SET);//回响信号消失
  TIM_Cmd(TIM3,DISABLE);//关闭定时器
  tim=TIM_GetCounter(TIM3); //获取TIM3现在的计数值
  length=(tim*0.0001+overnum*0.1)*180.0; //通过回响信号计算距离
         OLED_ShowSignedNum(1,1,length,5);
  TIM3->CNT=0; //将TIM3计数寄存器的计数值清零
  Delay_ms(100);
  return length; //距离作为函数返回值
 }


  int main(void)
  {
        float length;//障碍物距离(cm)
	OLED_Init();
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	TIM3_Int_Init();
	GPIO_WriteBit(GPIOA, GPIO_Pin_7, (BitAction)(0)); 
	OLED_ShowString(3,1,"lenth");
	while(1)
	{
	 length = Senor_Using(); //调用测距函数
	 overnum = 0;
	 Delay_ms(5000);
	 GPIO_WriteBit(GPIOA, GPIO_Pin_6, (BitAction)(1));
         Delay_us(20); //高电平信号超过10us
         GPIO_WriteBit(GPIOA, GPIO_Pin_6, (BitAction)(0)); //等待回响信号
//		if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)==RESET)
//			OLED_ShowString(1,1,"gua");
//		else
//			OLED_ShowString(2,1,"hhh");
//	}
//	 Delay_ms(5000);
//	 OLED_Clear();
	}
}