当前位置:   article > 正文

基于stm32cubeMX的的HAL库开发的智能小车------变速和红外寻迹小车_l298n小车hal库

l298n小车hal库

我的第一辆智能小车

提示:小编也是初学者,本文适用于想完成一个基础智能四轮车的初学者,大佬还请勿喷,欢迎各位指出错误的地方

暑假在家无聊,刚好也在学习STM32的HAL库,就想着做个小车巩固自己学到的知识,顺便记录自己所遇到的错误

小编也是现学现写,现已学会变速和红外寻迹,准备做一个蓝牙遥控红外寻迹超声波避障小车

这篇博客讲述的就是如何去制作变速和寻迹小车,

1,相关传感器的介绍

1.1TCRT5000红外寻迹模块的介绍

TCRT5000红外寻迹模块是一种基于红外反射原理的传感器,用于检测和跟踪目标物体的位置。

红外对管传感器
其原理很简单:

// 未碰到黑线(接收到红外光):对应状态 = 0
 // 碰到黑线(未接收到红外光):对应状态 = 1

                                                                                                           

1.2L298N直流电机驱动板

L298N直流电机驱动板是一种常用的双H桥驱动器,可控制直流电机的转动方向和速度,适用于机器人、小车等电机驱动应用。

具体的用法:上一期博客

                                                                                                           
                                                            

 2.stm32f103c8t6对应功能的引脚分配

具体的引脚分配要根据STM32F103C8T6引脚定义表来分配,这个我会放在文末的资源包里面

可以和我的不一样,这里注意了具有PWM输出比较功能的定时器只有通用和高级定时器,基本定时器是没有这个功能的。

STM32F103C8T6微控制器的定时器资源包括:
- 3个通用定时器(TIM2、TIM3、TIM4)
- 1个高级定时器(TIM1)
- 2个基本定时器(TIM6、TIM7)

总共有6个定时器可供使用。

选用控制电极速度的引脚是PB6/7/8/9
分别对应的是TIM4_CH1/CH2/CH3/CH4
都在一起,方便调试
选择控制正反转的引脚是PA0/1/2/3/4/5/6/7  选择GPIO_Output
 轮子          EN           IN1  IN2       IN3   IN4
左前轮        PB6       PA0    PA1
右前轮        PB7                            PA2    PA3
左后轮        PB8                            PA6    PA7
右后轮        PB9       PA4    PA5 

寻迹模块的使用引脚是PB0/1/3/4                选择GPIO_input
                                     IN1/2/3/4 

3.stm32cubeMX的配置

1.引脚的功能分配

                                       

2,RCC外部时钟的配置

这里选择的是外部高速晶振HSE

3,时钟树的配置

这里不懂的强烈推荐去看原子哥的时钟树讲解

点击这里跳转

 4,GPIO的设置以及器宏名

5,SYS的配置,我用的是ST-Link烧录器,这里选择的是Serial Wire

6,Timer的配置

这里是使用了TIM4的四个通道,并将对应的ARR和PSC的值分别设置,不懂的可以看看下面这张图片,这里的ARR的值最好设置为100,使得我们调整CCR(0-100)的值就等同于调整占空比

直流电机的PWM(脉宽调制)频率通常会根据具体的应用和需求而有所不同。然而,一般来说,对于直流电机的PWM控制,频率在几千赫兹到几万赫兹之间是常见的范围。

较高的PWM频率可以提供更精确的控制和速度调节,同时减少噪音和振动。然而,较高的频率可能需要更高的计算和驱动能力。

一般来说,对于直流电机的PWM控制,建议选择频率在5kHz到20kHz之间。这个范围通常能够提供良好的控制性能和较低的噪音水平。我这里设置的是20KHZ,对应的PSC+1=36,ARR+1=100。

 7,工程文件夹的配置

上面那个Project的配置就不细说了,这里推荐勾选这个,将.C和.H文件分开管理

最后点击创建文件

观看了上面的内容还是不会配置的建议下载文件资源包,里面有具体的配置文件

 4,代码展示部分

注意: 因为大部分代码都是软件生成的,里面有很多注释,这里为了直观就都删除了

需要改动的部分都贴出来了

软件生成的代码别乱删

main.c

  1. #include "main.h"
  2. #include "tim.h"
  3. #include "gpio.h"
  4. #include "motor.h"
  5. void SystemClock_Config(void);
  6. int main(void)
  7. {
  8. HAL_Init();
  9. SystemClock_Config();
  10. MX_GPIO_Init();
  11. MX_TIM4_Init();
  12. /* USER CODE BEGIN 2 */
  13. HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_1);
  14. HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_2);
  15. HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_3);
  16. HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_4);
  17. Change_speed(62);//初始速度:速度区间0-100
  18. while (1)
  19. {
  20. /* USER CODE END WHILE */
  21. Sensor(7065);//寻迹
  22. /* USER CODE BEGIN 3 */
  23. }
  24. }

main.h

  1. #include "stm32f1xx_hal.h"
  2. #include "sensor.h"

motor.c

  1. #include "motor.h"
  2. /* 小车轮子转动驱动代码*/
  3. void Forward(void)
  4. {/* 直行 */
  5. HAL_GPIO_WritePin(motorF1_GPIO_Port,motorF1_Pin,GPIO_PIN_SET);//前左轮-IN1 1
  6. HAL_GPIO_WritePin(motorF2_GPIO_Port,motorF2_Pin,GPIO_PIN_RESET);//前左轮-IN2 0 正转
  7. HAL_GPIO_WritePin(motorF3_GPIO_Port,motorF3_Pin,GPIO_PIN_SET);//前右轮-IN3 1
  8. HAL_GPIO_WritePin(motorF4_GPIO_Port,motorF4_Pin,GPIO_PIN_RESET);//前右轮-IN4 0 正转
  9. /* 因为L298N驱动模块是对相安装 */
  10. HAL_GPIO_WritePin(motorR1_GPIO_Port,motorR1_Pin,GPIO_PIN_RESET);//后左轮-IN3 0
  11. HAL_GPIO_WritePin(motorR2_GPIO_Port,motorR2_Pin,GPIO_PIN_SET);//后左轮-IN4 1 反转
  12. HAL_GPIO_WritePin(motorR3_GPIO_Port,motorR3_Pin,GPIO_PIN_RESET);//后右轮-IN1 0
  13. HAL_GPIO_WritePin(motorR4_GPIO_Port,motorR4_Pin,GPIO_PIN_SET);//后右轮-IN2 1 反转
  14. }
  15. void Backward()
  16. {/* 后行 */
  17. HAL_GPIO_WritePin(motorF1_GPIO_Port,motorF1_Pin,GPIO_PIN_RESET);//前左轮-IN1
  18. HAL_GPIO_WritePin(motorF2_GPIO_Port,motorF2_Pin,GPIO_PIN_SET);//前左轮-IN2
  19. HAL_GPIO_WritePin(motorF3_GPIO_Port,motorF3_Pin,GPIO_PIN_RESET);//前右轮-IN3
  20. HAL_GPIO_WritePin(motorF4_GPIO_Port,motorF4_Pin,GPIO_PIN_SET);//前右轮-IN4
  21. /* 因为L298N驱动模块是对相安装 */
  22. HAL_GPIO_WritePin(motorR1_GPIO_Port,motorR1_Pin,GPIO_PIN_SET);//后左轮-IN3
  23. HAL_GPIO_WritePin(motorR2_GPIO_Port,motorR2_Pin,GPIO_PIN_RESET);//后左轮-IN4
  24. HAL_GPIO_WritePin(motorR3_GPIO_Port,motorR3_Pin,GPIO_PIN_SET);//后右轮-IN1
  25. HAL_GPIO_WritePin(motorR4_GPIO_Port,motorR4_Pin,GPIO_PIN_RESET);//后右轮-IN2
  26. }
  27. void Turn_Left()
  28. {/* 左转 */
  29. HAL_GPIO_WritePin(motorF1_GPIO_Port,motorF1_Pin,GPIO_PIN_RESET);//前左轮-IN1 0
  30. HAL_GPIO_WritePin(motorF2_GPIO_Port,motorF2_Pin,GPIO_PIN_SET);//前左轮-IN2 1 反转
  31. HAL_GPIO_WritePin(motorF3_GPIO_Port,motorF3_Pin,GPIO_PIN_SET);//前右轮-IN3 1
  32. HAL_GPIO_WritePin(motorF4_GPIO_Port,motorF4_Pin,GPIO_PIN_RESET);//前右轮-IN4 0正转
  33. /* 因为L298N驱动模块是对相安装 */
  34. HAL_GPIO_WritePin(motorR1_GPIO_Port,motorR1_Pin,GPIO_PIN_RESET);//后左轮-IN3 0
  35. HAL_GPIO_WritePin(motorR2_GPIO_Port,motorR2_Pin,GPIO_PIN_SET);//后左轮-IN4 1反转
  36. HAL_GPIO_WritePin(motorR3_GPIO_Port,motorR3_Pin,GPIO_PIN_SET);//后右轮-IN1 1
  37. HAL_GPIO_WritePin(motorR4_GPIO_Port,motorR4_Pin,GPIO_PIN_RESET);//后右轮-IN2 0 正转
  38. }
  39. void Turn_Right()
  40. {/* 右转 */
  41. HAL_GPIO_WritePin(motorF1_GPIO_Port,motorF1_Pin,GPIO_PIN_SET);//前左轮-IN1 1
  42. HAL_GPIO_WritePin(motorF2_GPIO_Port,motorF2_Pin,GPIO_PIN_RESET);//前左轮-IN2 0 正转
  43. HAL_GPIO_WritePin(motorF3_GPIO_Port,motorF3_Pin,GPIO_PIN_RESET);//前右轮-IN3 0
  44. HAL_GPIO_WritePin(motorF4_GPIO_Port,motorF4_Pin,GPIO_PIN_SET);//前右轮-IN4 1反转
  45. /* 因为L298N驱动模块是对相安装 */
  46. HAL_GPIO_WritePin(motorR1_GPIO_Port,motorR1_Pin,GPIO_PIN_SET);//后左轮-IN3 1
  47. HAL_GPIO_WritePin(motorR2_GPIO_Port,motorR2_Pin,GPIO_PIN_RESET);//后左轮-IN4 0 正转
  48. HAL_GPIO_WritePin(motorR3_GPIO_Port,motorR3_Pin,GPIO_PIN_RESET);//后右轮-IN1 0
  49. HAL_GPIO_WritePin(motorR4_GPIO_Port,motorR4_Pin,GPIO_PIN_SET);//后右轮-IN2 1 反转
  50. }
  51. void Stopward()
  52. {/* 停止 */
  53. HAL_GPIO_WritePin(motorF1_GPIO_Port,motorF1_Pin,GPIO_PIN_SET);//前左轮-IN1
  54. HAL_GPIO_WritePin(motorF2_GPIO_Port,motorF2_Pin,GPIO_PIN_SET);//前左轮-IN2
  55. HAL_GPIO_WritePin(motorF3_GPIO_Port,motorF3_Pin,GPIO_PIN_SET);//前右轮-IN3
  56. HAL_GPIO_WritePin(motorF4_GPIO_Port,motorF4_Pin,GPIO_PIN_SET);//前右轮-IN4
  57. /* 因为L298N驱动模块是对相安装 */
  58. HAL_GPIO_WritePin(motorR1_GPIO_Port,motorR1_Pin,GPIO_PIN_SET);//后左轮-IN3
  59. HAL_GPIO_WritePin(motorR2_GPIO_Port,motorR2_Pin,GPIO_PIN_SET);//后左轮-IN4
  60. HAL_GPIO_WritePin(motorR3_GPIO_Port,motorR3_Pin,GPIO_PIN_SET);//后右轮-IN1
  61. HAL_GPIO_WritePin(motorR4_GPIO_Port,motorR4_Pin,GPIO_PIN_SET);//后右轮-IN2
  62. }

motor.h

  1. #ifndef __MOTOR_H_
  2. #define __MOTOR_H_
  3. #include "main.h"
  4. void Forward(void);
  5. void Backward(void);
  6. void Turn_Left(void);
  7. void Turn_Right(void);
  8. void Stopward(void);
  9. #endif

sensor.c

这里做出了一些改动,现在小车可以寻直线/曲线/直角转弯

  1. #include "sensor.h"
  2. #include "motor.h"
  3. void Change_speed(uint16_t speed)
  4. {/* 变速 */
  5. // 设置电机速度范围(60-100),越大越快
  6. __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1, speed);
  7. __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_2, speed);
  8. __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_3, speed);
  9. __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_4, speed);
  10. }
  11. void Sensor(uint16_t value,uint16_t pos)
  12. {//value是小车正常行驶时候的速度,POS是转弯时候的速度
  13. if(L1==0&&L2==0&&R1==0&&R2==0)//如果4个全部没有读取黑线,直走; Forward();
  14. {
  15. Change_speed(value);
  16. Forward();
  17. HAL_Delay(5);
  18. }
  19. if(L1==0&&L2==1&&R1==1&&R2==0)//如果2,3读取黑线,直走; Forward();
  20. {
  21. Change_speed(value);
  22. Forward();
  23. HAL_Delay(5);
  24. }
  25. if(L1==0&&L2==1&&R1==0&&R2==0)//如果2读取黑线,左转; Turn_Left();
  26. {
  27. Change_speed(pos);
  28. Turn_Left();
  29. HAL_Delay(5);
  30. }
  31. if(L1==0&&L2==0&&R1==1&&R2==0)//如果3读取黑线,右转; Turn_Right();
  32. {
  33. Change_speed(62);
  34. Turn_Right();
  35. HAL_Delay(5);
  36. }
  37. //大左转
  38. if(L1==1&&(L2==1)&&(R1==0)&&R2==0)
  39. {
  40. HAL_Delay(20);//等待响应
  41. while(1)
  42. {
  43. Change_speed(65);
  44. Turn_Left();
  45. HAL_Delay(40);//等待响应
  46. if(L1==0&&(L2==0)&&(R1==1)&&R2==0)
  47. break;
  48. }
  49. }
  50. //大右转
  51. if(L1==0&&(L2==0)&&(R1==1)&&R2==1)
  52. {
  53. HAL_Delay(20);//等待响应
  54. while(1)
  55. {
  56. Change_speed(65);
  57. Turn_Right();
  58. HAL_Delay(40);//等待响应
  59. if(L1==0&&(L2==1)&&(R1==0)&&R2==0)
  60. break;
  61. }
  62. }
  63. }

sensor.h

  1. #ifndef __SENSOR_H_
  2. #define __SENSOR_H_
  3. #include "main.h"
  4. #include "tim.h"
  5. extern void Sensor(uint16_t value,uint16_t pos);
  6. void Change_speed(uint16_t speed);
  7. #define L1 HAL_GPIO_ReadPin(sensor4_GPIO_Port,sensor4_Pin)//左 IN4 B4
  8. #define L2 HAL_GPIO_ReadPin(sensor3_GPIO_Port,sensor3_Pin)//左 IN3 B3
  9. #define R1 HAL_GPIO_ReadPin(sensor2_GPIO_Port,sensor2_Pin)//右 IN2 B2
  10. #define R2 HAL_GPIO_ReadPin(sensor1_GPIO_Port,sensor1_Pin) //右 IN1 B1
  11. #endif

5,总结

代码总体是由stm32cubeMX一键生成的,需要改动和添加的地方都在上面了,源码和资源包我也上传了,需要的自提

工程代码:点击这里

6,效果展示

下一篇博客预知-----蓝牙小车

寻迹小车演示视频

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/46505?site
推荐阅读
相关标签
  

闽ICP备14008679号