超声波测距+OLED显示

超声波测距+OLED显示

  • 超声波模块使用的是HC-SR04模块,单片机使用的是STM32F407

超声波

  • 超声波时序图

在这里插入图片描述

  • 以上时序图表明你只需要提供一个 10uS 以上脉冲触发信号,该模块内部将发出 8 个 40kHz 周期电平并检测回波。一旦检测到有回波信号则输出回响信号 。回响信号的脉冲宽度与所测的距离成正比。由此通过发射信号到收到的回响信号时间间隔可以计算得到距离。
  • 公式:uS/58=厘米或者 uS/148=英寸;或是:距离=高电平时间*声速(340M/S)/2;建议测量周期为 60ms 以上,以防止发射信号对回响信号的影响。
  • 模块需要和STM32工地

STM32引脚配置

  • Trig引脚使用的是PE0,使用推挽输出即可

在这里插入图片描述

  • Echo引脚,就是回传信号的引脚,使用的是TIM10的输入通道1,就是PF6引脚。因为要测量输入高电平的时长,直接使用定时计数器的输入捕获的功能会比较方便。STM32F407ZEt6的TIM10的输入通道一,只对应一路捕获通道

在这里插入图片描述

  • 不要忘记打开中断

在这里插入图片描述

  • 输入捕获的原理和计数的原理差不多,先规定捕获通道是上升沿触发,还是下降沿触发,还是双边都触发;
  • 触发之后,申请一次捕获中断,同时将CNT的数值锁存到捕获寄存器CCR中,我们可以把此时的CCR的数值记录到value1中,还要清楚捕获中断标志
  • 然后等待第二次触发,又会将CNT的数值锁存到CCR中,再把此时的数值记录到value2中,还要清楚中断标志位,把两个数值相减,再乘计一个数的时间,就是电平持续的时间或者周期等。

代码

启动超声波模块
  • 根据上面超声波的时序,写出启动信号,即向Trig引脚发送一段不低于10微秒的高电平

    void Ultrasonic_start(void)
    {
    	HAL_TIM_Base_Start(&htim10);//启动定时计数器10
        HAL_TIM_IC_Start_IT(&htim10,TIM_CHANNEL_1);/* 启动定时计数器捕获通道1,并开启中断 */
    	
    	HAL_GPIO_WritePin(Tr1g_1_GPIO_Port,Tr1g_1_Pin,GPIO_PIN_RESET);
    	delay_us(50);
    	HAL_GPIO_WritePin(Tr1g_1_GPIO_Port,Tr1g_1_Pin,GPIO_PIN_SET);
    	delay_us(50);
    	HAL_GPIO_WritePin(Tr1g_1_GPIO_Port,Tr1g_1_Pin,GPIO_PIN_RESET);
    	TIM10->CNT=0;  //可以不对CNT进行清零,此处清零是为了不再后面处理计数溢出的情况
    }
    
接收超声波数据回传
  • 在硬件上Echo引脚连接的是TIM10的通道1,并在捕获通道1进行输入捕获,初始化时极性设置的是上升沿有效;

  • 所以在第一次捕获时,捕获的是上升沿,说明回传信号的高电平开始;

  • 在第一次捕获中断的中断函数中应该读取CCR中的数值并把捕获通道的极性进行修改为下降沿有效,用来检测高电平的结束

  • 在第二次捕获中断到来时也要读取CCR中的数值,并将捕获通道的极性设置为上升沿有效,准备检测下一阶段的高电平信号

  • 在第二次捕获完成后,可以先关闭计数器,等待计算完成再打开,避免这次还没有计算完,下一次的就已经到了

  • 最重要的是不要忘记清除中断标志位,如果使用的是HAL库的回调函数,那么就不需要手动清除了,HAL库会帮你完成

  • 计算的函数如下,会使用OLED显示:

    uint16_t flag=0;  //第二次捕获结束,即高电平已经结束了
    /*capture[0]用来存放第一次捕获的数值;capture[1]用来存放第二次捕获的数值,capture[2]存放差值*/
    uint16_t capture[3]={0}; 
    /*使用OLED来进行输出的数组*/
    char shuchu0[12]={0};
    unsigned char shuchu[12]={0};
    void Ultrasonic_Receive_Display(void)
    {
    	float data=0;
    	if(flag==1)
    		{
    			flag=0;
    			capture[2]=capture[1]-capture[0];
                /*计算数值*/
    			data=((capture[2])*1.0)/58.0;
    
    			for(int k1=0;k1<3;k1++)
    			{
    				capture[k1]=0;
    			}
    			/*进行显示*/
    			int m=0;
    			sprintf(shuchu0,"%0.2f cm",data);  //保留小数点后两位
    
    			for(m=0;shuchu0[m]!='\0';m++)
    			{
    				shuchu[m]=(unsigned char)shuchu0[m];
    			}
    			shuchu[m]='\0';
    			
    			OLED_CLS();
    			OLED_ShowStr(0,3,"distance:",1);
    			OLED_ShowStr(0,4,shuchu,1);
    			HAL_Delay(100);
    			
    		}
    	else
    		{
    			OLED_CLS();
    			OLED_ShowStr(0,4,"please wait",2);
    			HAL_Delay(100);
    		}
    	
    }
    
  • 捕获中断的回调函数如下:

    void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
    {
        uint16_t cnt=1; //用来区分是第一次还是第二次的数值
    	if(TIM10==htim->Instance)
    	{
    		
    		switch (cnt)
    		{
    			case 1:
                    /*第一次通道捕获触发,高电平信号开始*/
                    capture[0]= HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);
                    /*用HAL库时要先清除通道的极性,再更改通道的极性*/
                    TIM_RESET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1);   
                    TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1, TIM_ICPOLARITY_FALLING);   
                
                    cnt++;
                    Start_Flag=0; //外部定义,发送超声波启动信号的标志,此时还不能启动
                    break;
    			case 2:
                    /*第二次表示高电平的结束*/
                    capture[1]=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);
                    cnt=1;
                     flag=1;  //外部定义,开始进行就算并发送给LED显示的标志
                     Start_Flag=1; 
                     /*关闭定时计数器,防止下次的干扰*/
                     HAL_TIM_IC_Stop_IT(htim, TIM_CHANNEL_1);
                     HAL_TIM_Base_Stop(htim);
                    /*清除通道极性,并设置为上升沿触发,为下次做准备*/
                     TIM_RESET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1);               
                     TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1, TIM_ICPOLARITY_RISING);	
                    break;
    		}
    	}
    }
    
  • 主体部分写入一个循环里面就可以了

    for(;;)
      {
    		while(Start_Flag==1)
    		{
    			Ultrasonic_start();
    			osDelay(100);
    			Ultrasonic_Receive_Display();
    		}
    		
      }
    
  • 1
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值