基于STM32的智能循迹避障小车实验(超声波部分)

这篇具有很好参考价值的文章主要介绍了基于STM32的智能循迹避障小车实验(超声波部分)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

接上一篇基于STM32的智能循迹避障小车实验(舵机旋转部分)

最后这部分我们实现超声波部分和最后代码的整合

实验所用器件及其介绍

本部分实验采用的是超声波模块HC-SR04,它长这样:

基于STM32的智能循迹避障小车实验(超声波部分)

 

买这个的时候最好再买一个支架,可以直接架在舵机上,探查周围的距离。

超声波模块有4个引脚,分别为Vcc Trig(控制端)、 Echo(接收端)、 GND;其中VCCGND接上电源和地, Trig(控制端)控制发出的超声波信号,Echo(接收端)接收反射回来的超声波信号。

控制端的控制原理:通过Trig引脚发一个 10US 以上的高电平,就可以在Echo接收口等待高电平输出;一有输出就可以开定时器计时,当此口变为低电平时就可以读定时器的值,此时就为此次测距的时间,方可算出距离.如此不断的周期测,就可以达到你移动测量的值了。(这个时间最好大于60us,以防检测和发送的声波冲突)。

基于STM32的智能循迹避障小车实验(超声波部分)

 

了解了超声波模块的基本工作原理后就可以完成程序设计了。

程序实现

和之前操作一样,我们在之前代码的基础上直接打开CobeMX。

代码实现顺序:先设置触发信号,这里我们使用一个普通的GPIO口输出一个高电平,等待Echo发出脉冲,然后启动定时器,等待Echo变为低电平即为一次定时时间,根据数学公式我们可以将这个时间转化为距离。

CubeMX设置

这里我们还是设置一个普通的GPIO口为输出模式,再使用通用定时器作为测量时间的工具。

这里使用PG11作为GPIO输出口和Trig引脚相连,然后打开TIM4通道1设置为Input Capture direct mode模式,然后再在NVIC中配置主优先级为1次优先级为0,具体配置如图:基于STM32的智能循迹避障小车实验(超声波部分)

 

配置完成后生成代码,

代码实现

和之前实现定时器的中断相似的步骤,但是我们这里要实现另外的中断回调函数:

uint8_t TIM4CH1_CAP_STA = 0;                        // 输入捕获状态

uint16_t TIM4CH1_CAP_VAL;                           // 输入捕获值

// 中断服务函数里面会自动调用这个回调函数,这个是定时器更新中断处理的函数(更新时间回调函数,这里更新溢出的时间)

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

{

    if(htim->Instance == TIM4)       // 判断定时器4是否发生中断

    {

        if((TIM4CH1_CAP_STA & 0X80) == 0)           // 还未成功捕获

        {

            if(TIM4CH1_CAP_STA & 0X40)   // 已经捕获到高电平

            {         

                if((TIM4CH1_CAP_STA & 0X3F) == 0X3F)// 高电平时间太长了,做溢出处理

                { 

                    TIM4CH1_CAP_STA |= 0X80;   // 标记为完成一次捕获

                    TIM4CH1_CAP_VAL += 1;       // 计数器值

                }

                else

                {

                    TIM4CH1_CAP_STA++;    // 若没有溢出,就只让TIM5CH1_CAP_STA自加

                }               

            }  

        }

    }

}



// 定时器输入捕获中断处理回调函数,该函数在 HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim) 中会被调用(通道输入捕获)

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)

{

    if((TIM4CH1_CAP_STA & 0X80) == 0)               // 还未成功捕获

    {

         if(TIM4CH1_CAP_STA & 0X40)         // 捕获到一个下降沿

        {          

                     TIM4CH1_CAP_STA |= 0X80;   // 标记成功捕获到一次高电平脉宽

                     TIM4CH1_CAP_VAL = HAL_TIM_ReadCapturedValue(&htim4, TIM_CHANNEL_1); // 获取当前的计数器值

                     TIM_RESET_CAPTUREPOLARITY(&htim4, TIM_CHANNEL_1);                 // 清除原来的设置        

                     TIM_SET_CAPTUREPOLARITY(&htim4,TIM_CHANNEL_1, TIM_ICPOLARITY_RISING);// 设置上升沿捕获

              }

              else

        {

                     TIM4CH1_CAP_STA = 0;     // 清空自定义的状态寄存器

                     TIM4CH1_CAP_VAL = 0;        // 清空捕获值

                     TIM4CH1_CAP_STA |= 0X40;        // 标记捕获到上升沿

                     __HAL_TIM_DISABLE(&htim4);    // 关闭定时器

                     __HAL_TIM_SET_COUNTER(&htim4, 0);   // 计数器值清零

                     TIM_RESET_CAPTUREPOLARITY(&htim4,TIM_CHANNEL_1);  // 一定要先清除原来的设置   !!              

                 TIM_SET_CAPTUREPOLARITY(&htim4,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);   // 设置下降沿捕获

                     __HAL_TIM_ENABLE(&htim4);         // 使能定时器     

              }     

       }

}

完成中断回调函数之后,就可以在主函数中启动中断了,最后我这里使用了串口输出相关的距离、时间,也可以使用其他的方式输出,因为最后整合代码时不需要串口输出,所以我对串口配置没有说明。

主函数部分

int main(void)

{

  /* USER CODE BEGIN 1 */

//    uint8_t i = 0;

      

       uint8_t length_res[10];  // 定义一个数组存放前方的距离

//    uint8_t Car_Command= 4;

  /* USER CODE END 1 */



  /* MCU Configuration--------------------------------------------------------*/



  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */

  HAL_Init();



  /* USER CODE BEGIN Init */



  /* USER CODE END Init */



  /* Configure the system clock */

  SystemClock_Config();



  /* USER CODE BEGIN SysInit */



  /* USER CODE END SysInit */



  /* Initialize all configured peripherals */

  MX_GPIO_Init();

  MX_TIM2_Init();

  MX_USART1_UART_Init();

  MX_TIM3_Init();

  MX_TIM4_Init();

  /* USER CODE BEGIN 2 */

      

       printf("这是智能小车方向控制测试程序");

       HAL_TIM_Base_Start_IT(&htim3);  // 这个中断是之前的舵机中断

       HAL_TIM_PWM_Start_IT(&htim3, TIM_CHANNEL_1);

       HAL_TIM_IC_Start_IT(&htim4,TIM_CHANNEL_1);  // 一定要开启TIM4通道1的捕获中断,这个是超声波中断

  __HAL_TIM_ENABLE_IT(&htim4,TIM_IT_UPDATE);  // 一定要开启TIM4的更新中断

  printf("This is TIM_CAP test...\n");   

  /* USER CODE END 2 */



  /* Infinite loop */

  /* USER CODE BEGIN WHILE */

  while (1)

  {

              HAL_GPIO_WritePin(GPIOG, GPIO_PIN_12, GPIO_PIN_SET);

              HAL_Delay(1);

              HAL_GPIO_WritePin(GPIOG, GPIO_PIN_12, GPIO_PIN_RESET);

             

              HAL_Delay(500);

   if(TIM4CH1_CAP_STA & 0X80)    // 完成一次高电平捕获

   {

     temp = TIM4CH1_CAP_STA & 0X3F;

      temp *= 1000;            // 溢出总时间

     temp = (temp+TIM4CH1_CAP_VAL)/58.0; // temp+TIM4CH1_CAP_VAL是总的时间,除以58是距离

      printf("High level duration:%lld cm\r\n",temp);  // 输出每次测出的距离,单位是cm

      TIM4CH1_CAP_STA = 0;             // 准备下一次捕获

       }

             

    /* USER CODE END WHILE */

             

    /* USER CODE BEGIN 3 */

  }

                    

  /* USER CODE END 3 */

}

这样就完成了超声波部分的测试,最后我们将代码整合,就可以完成小车自动识别障碍物然后前进

代码整合

在整合之前,我们需要修改之前的代码,现在我们要实现的目的是:超声波模块测量前面的距离,如果距离大于30cm,就让小车直走,距离小于30cm,停车,测量左侧和右侧45°的距离,然后比较这两个数,向距离大的一侧前进。

// 小车停止代码

void Car_Stop(void)

{

       HAL_GPIO_WritePin(IN1_GPIO_Port, IN1_Pin, GPIO_PIN_RESET);

       HAL_GPIO_WritePin(IN3_GPIO_Port, IN3_Pin, GPIO_PIN_RESET);



}

Uint8_t a;

// 上节中我们有个关于舵机旋转方向的表格,在这里我们定义90°为正前方

// 右转45°

void SG90_Right_45(void)

{

       a = 1;

}

// 舵机转向前方

void SG90_Front(void)

{

       a = 2;

}

// 左转45°

void SG90_Left_45(void)

{

       a = 3;

}

// 这里我们之前的回调函数也得重新实现,以保证我们可以调整想要的角度

/* TIM3 init function */

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)

{

       // 舵机的回调函数,使舵机转向

       if(htim->Instance == TIM3)  // 判断是否是定时器3引起的中断

       {

              if(a == 1)  // 判断是具体是哪个转向

              {

                     __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,10);

              }

              if(a == 2)

              {

                     __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,15);

              }

              if(a == 3)

              {

                     __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,20);

              }

       }

}

剩下的就是主函数部分的重新实现:

int main(void)

{

  /* USER CODE BEGIN 1 */

//    uint8_t i = 0;

      

       uint8_t length_res[10];  // 定义一个数组存放前方的距离

//    uint8_t Car_Command= 4;

  /* USER CODE END 1 */



  /* MCU Configuration--------------------------------------------------------*/



  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */

  HAL_Init();



  /* USER CODE BEGIN Init */



  /* USER CODE END Init */



  /* Configure the system clock */

  SystemClock_Config();



  /* USER CODE BEGIN SysInit */



  /* USER CODE END SysInit */



  /* Initialize all configured peripherals */

  MX_GPIO_Init();

  MX_TIM2_Init();

  MX_USART1_UART_Init();

  MX_TIM3_Init();

  MX_TIM4_Init();

  /* USER CODE BEGIN 2 */

      

       printf("这是智能小车方向控制测试程序");

       HAL_TIM_Base_Start_IT(&htim3);

       HAL_TIM_PWM_Start_IT(&htim3, TIM_CHANNEL_1);

//    Car_Dir_Com(Car_Command);            

//    Car_Go();

       HAL_TIM_IC_Start_IT(&htim4,TIM_CHANNEL_1);  // 一定要开启TIM4通道1的捕获中断

  __HAL_TIM_ENABLE_IT(&htim4,TIM_IT_UPDATE);  // 一定要开启TIM4的更新中断

  printf("This is TIM_CAP test...\n");

             

  /* USER CODE END 2 */



  /* Infinite loop */

  /* USER CODE BEGIN WHILE */

  while (1)

  {

              SG90_Front();   //舵机摆正

              HAL_Delay(100);

              length_res[0] =Senor_Using();  //测前方距离放在数组里

              HAL_Delay(100);

              if(length_res[0]>30.00)       //如果前方距离大于30cm  前进

              {

                     Car_Go();

              }     

                           

              if(length_res[0]<30.00)     //如果前方距离小于30厘米  停车测左右距离

              {

                     Car_Stop(); 

                     SG90_Left_45();      //舵机左转45度测距

                     HAL_Delay(700);       

                     length_res[1] =Senor_Using();    //把测量结果放进数组

                    

                     SG90_Right_45();     //舵机右转45度测距

                     HAL_Delay(700);

                     length_res[4] =Senor_Using();     //把测量结果放进数组                    

                           

                     SG90_Front();           //舵机摆正

                     HAL_Delay(100);

                     if(length_res[1]>length_res[4])    //如果左边的距离大于右边的距离

                     {

                            do                        //舵机摆正

                            {

                            SG90_Front();

                            HAL_Delay(10);

                            length_res[0] =Senor_Using(); //重复测前方的距离同时左转

                            HAL_Delay(10);                                     

                            Car_Left();

                            }

                            while(length_res[0]<30.00);           //一直转到前方距离大于30cm             

                     }

                     if(length_res[1]<length_res[4])    //如果右边的距离大于左边的距离

                     {

                            do

                            {

                            SG90_Front();

                            HAL_Delay(10);

                            length_res[0] =Senor_Using();  //重复测前方的距离同时右转

                            HAL_Delay(10);                                     

                            Car_Right();

                            }

                            while(length_res[0]<30.00);           //一直转到前方距离大于30cm

                     }

                           

              }

// 这部分函数是之前测试超声波的函数,现在不需要

//           HAL_GPIO_WritePin(GPIOG, GPIO_PIN_12, GPIO_PIN_SET);

//           HAL_Delay(1);

//           HAL_GPIO_WritePin(GPIOG, GPIO_PIN_12, GPIO_PIN_RESET);

//          

//           HAL_Delay(500);

//    if(TIM4CH1_CAP_STA & 0X80)    // 完成一次高电平捕获

//    {

//      temp = TIM4CH1_CAP_STA & 0X3F;

//      temp *= 1000;            // 溢出总时间

//      temp = (temp+TIM4CH1_CAP_VAL)/58.0;  // 总的高电平时间

//      printf("High level duration:%lld cm\r\n",temp);

//      TIM4CH1_CAP_STA = 0;          // 准备下一次捕获

//           }

             

    /* USER CODE END WHILE */

             

    /* USER CODE BEGIN 3 */

  }

                    

  /* USER CODE END 3 */

}

这样就完成了整个项目的书写,最后附上整个项目的HAL库源码:

百度网盘 请输入提取码

提取码:1234文章来源地址https://www.toymoban.com/news/detail-471685.html

到了这里,关于基于STM32的智能循迹避障小车实验(超声波部分)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32循迹避障小车(颜色识别)

    主控采用stm32F103C8T6,三个循迹模块,超声波模块,openmv,降压模块,锂电池组,TT马达四个,L298n。可以实现循迹,避障,颜色识别等功能。 1、循迹模块 红外循迹模块通常包含一组红外线发射管和一组红外线接收器,发射管发出红外线,接收器接收地面反射的红外线信号。

    2024年02月07日
    浏览(46)
  • STM32蓝牙小车、红外循迹小车、超声波避障小车项目设计

    本文旨在分享我学习STM32的过程中,为了强化学习成果,试着制作一些实训项目。最开始做的就是STM32蓝牙小车、STM32红外循迹小车、STM32超声波避障小车。 相信看完本文的你,一定可以亲手制作一辆属于自己的智能小车! 注:文末附源码工程,需要的读者可以至文末下载 如

    2024年01月20日
    浏览(43)
  • 基于51单片机的多功能智能语音循迹避障小车

    目录 一.功能介绍及硬件准备 二.电机控制及调速 三.小车循迹方案 四.跟随功能实现 五.测速功能实现 六.OLED显示车速 七.摇头避障功能实现 八.SU-03T语音模块介绍 九.语音切换小车模式+OLED显示模式 这是一款基于51单片机开发的智能小车,通过这篇文章我会记录下来开发这款小

    2024年02月03日
    浏览(51)
  • 基于stm32的智能小车(远程控制、避障、循迹)

    学完stm32,总是想做点东西“大显身手”一下,智能小车就成了首选项目,其核心只是就是PWM输出,I/O口引脚电平判断。 制作智能小车的硬件名单: 由于我们做的控制功能可以使用2.4G控制,也可以使用蓝牙进行控制, 两种传输方式所需购买的模块不同,已在硬件名单中加以

    2024年02月03日
    浏览(50)
  • 基于FPGA的蓝牙遥控,超声波避障,红外循迹的智能小车

            闲来无事整个小车玩玩,设想的小车可以有蓝牙模块来控制模式切换,通过发送指令来更改相对应的功能,当避障的时候可以自动规避障碍物,当处于红外循迹时,可以跟随规划的轨迹前线,当手动遥控时可以控制前进后退左右转向停止等功能。         先介绍一下

    2024年02月07日
    浏览(50)
  • [STM32F103C8T6]基于stm32的循迹,跟随,避障智能小车

    目录 1.小车驱动主要是通过L9110S模块来驱动电机 motor.c 2.我们可以加入串口控制电机驱动(重写串口接收回调函数,和重定向printf) Uart.c main.c  3.点动功能 uart.c main.c 为什么使用的是HAL_Delay()要设置滴答定时器的中断优先级呢? 4.小车PWM调速,  6.跟随功能 7.避障功能 超声波测距

    2024年02月13日
    浏览(57)
  • 机器人制作开源方案 | 智能循迹避障小车

    作者: 刘元青、邹海峰、付志伟、秦怀远、牛文进 单位: 哈尔滨信息工程学院 指导老师: 姚清元       智能小车是移动式机器人的重要组成部分,而移动机器人不仅能够在经济、国防、教育、文化和生活中起到越来越大的作用,也是研究复杂智能行为的产生、探索人类思

    2024年01月16日
    浏览(60)
  • 基于单片机的智能循迹避障小车STC89C52红外对管L298N驱动PWM波控制速度

    wx供重浩:创享日记 对话框发送:单片机小车 免费获取完整无水印报告等 利用红外对管检测黑线与障碍物,并以STC89C52单片机为控制芯片控制电动小汽车的速度及转向,从而实现自动循迹避障的功能。其中小车驱动由L298N驱动电路完成,速度由单片机输出的PWM波控制。 1.1智能

    2023年04月22日
    浏览(53)
  • STM32F103C8T6智能小车舵机超声波避障

    目录 一、定时器 计数和定时器中断  输出比较(PWM) 二、 舵机 三、超声波测距 四、主函数 总结 推荐的STM32学习链接:  [6-1] TIM定时中断_哔哩哔哩_bilibili [6-1] TIM定时中断是STM32入门教程-2022持续更新中的第13集视频,该合集共计29集,视频收藏或关注UP主,及时了解更多相关视

    2024年02月15日
    浏览(48)
  • 【IoT】红外循迹避障小车

    随着生产自动化的发展需要,机器人已经越来越广泛地应用到生产自动化上,随着科学技术的发展,机器人的传感器种类也越来越多,其中红外传感器已经成为自动行走和驾驶的重要部件。 红外的典型应用领域为自主式智能导航系统,机器人要实现自动避障功能就必须要感知

    2024年02月04日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包