当前位置:   article > 正文

【平衡小车分享日记】(二)CubeMX配置+代码_cube 配置rcc sys

cube 配置rcc sys

接上文【平衡小车分享日记】(一)硬件部分

参考资料:(里面有源码)

​​​​​​STM32系列(HAL库)——F103C8T6通过MPU6050+DMP姿态解算读取角度及温度_嵌入式创客工坊的博客-CSDN博客_6050dmp

【STM32】HAL库 PWM控制电机转速与编码器读取(超详解)_鲁乎乎的博客-CSDN博客_hal库控制步进电机
两位博主的讲解非常详细,在此谢过!

目录

一、CubeMX配置

1、配置RCC、SYS、时钟树

2、配置串口1

3、MPU6050 

4、配置编码器模式

5、配置PWM模式

6、配置GPIO

7、配置FreeRTOS

8、导出工程

二、部分代码

1、串口1打印

2、freertos.c文件内代码

      入口MPU6050_Start()代码:

      入口Control_Start()代码:

3、control.c文件内代码

      control.h文件内代码

 三、代码下载


一、CubeMX配置

说明:

        咱们就不讲原理什么的了,太多了。我们直接上图。芯片选择咱们就不说了,附一张总图,小车功能实现到直立环、速度环

1、配置RCC、SYS、时钟树

2、配置串口1

3、MPU6050 

两个引脚都配置为开漏输出

4、配置编码器模式

5、配置PWM模式

6、配置GPIO

这里的PB12\PB13\PB14\PB15控制电机正反转,我备注了AIN1\2、BIN1\2,代码也会有修改,嫌麻烦的可以不用备注。

7、配置FreeRTOS

        这里我FreeRTOS配置了3个进程,分别是Task_MPU6050、Task_Control、Task_Oledshow,入口函数分别是MPU6050_200HZ、Control_100HZ、Oledshow_5HZ,这个自己设置就好,无关紧要。

        但是FreeRTOS的时钟我没有区别开,剩下的定时器可能留着有用。不然FreeRTOS的延时用定时器3来做。

8、导出工程

二、部分代码

1、串口1打印    //便于调试

  1. /* USER CODE BEGIN 0 */
  2. //加入头文件 #include "stdio.h"
  3. int fputc(int ch, FILE *fp)
  4. {
  5. while(!(USART1->SR & (1<<7)));
  6. USART1->DR = ch;
  7. return ch;
  8. }
  9. /* USER CODE END 0 */

2、freertos.c文件内代码

  1. void MPU6050_200HZ(void const * argument)
  2. {
  3. /* USER CODE BEGIN MPU6050_200HZ */
  4. //MPU6050数据采集
  5. MPU_Init(); //=====初始化MPU6050
  6. while(mpu_dmp_init()); //=====初始化MPU6050的DMP模式,用while等待
  7. printf("MPU6050初始化成功!\n");
  8. /* Infinite loop */
  9. for(;;)
  10. {
  11. MPU6050_Start();
  12. osDelay(5);
  13. }
  14. /* USER CODE END MPU6050_200HZ */
  15. }
  16. /* USER CODE BEGIN Header_Control_100HZ */
  17. /**
  18. * @brief Function implementing the Task_Control thread.
  19. * @param argument: Not used
  20. * @retval None
  21. */
  22. /* USER CODE END Header_Control_100HZ */
  23. void Control_100HZ(void const * argument)
  24. {
  25. /* USER CODE BEGIN Control_100HZ */
  26. /* Infinite loop */
  27. for(;;)
  28. {
  29. Control_Start();
  30. osDelay(10);
  31. }
  32. /* USER CODE END Control_100HZ */
  33. }

入口MPU6050_Start()代码:

  1. #include "mpu6050.h"
  2. #include "stdio.h"
  3. #include "inv_mpu.h"
  4. float pitch,roll,yaw; //欧拉角(姿态角)
  5. short aac_x,aac_y,aac_z; //加速度传感器原始数据
  6. short gyro_x,gyro_y,gyro_z; //陀螺仪原始数据
  7. void MPU6050_Start(void) //MPU6050数据采集
  8. {
  9. mpu_dmp_get_data(&pitch,&roll,&yaw);
  10. MPU_Get_Accelerometer(&aac_x,&aac_y, &aac_z); //得到加速度传感器数据
  11. MPU_Get_Gyroscope(&gyro_x, &gyro_y, &gyro_z); //得到陀螺仪数据
  12. /**********************测试*************************/
  13. // printf("acc_x = %d\n", aac_x);
  14. // printf("aac_y = %d\n", aac_y);
  15. // printf("aac_z = %d\n", aac_z);
  16. // printf("gyro_x = %d\n", gyro_x);
  17. // printf("gyro_y = %d\n", gyro_y);
  18. // printf("gyro_z = %d\n", gyro_z);
  19. // printf("X:%.2f° Y:%.2f° Z:%.2f°\r\n",pitch,roll,yaw);//串口1输出采集信息
  20. /***************************************************/

入口Control_Start()代码:

  1. #include "control.h"
  2. void Control_Start(void)
  3. {
  4. Encoder_Left = Read_Encoder(2); //===读取编码器的值
  5. Encoder_Right = -Read_Encoder(4); //===读取编码器的值
  6. /**********************测试*************************/
  7. // printf("Encoder_Left = %d Encoder_Right = %d\n",Encoder_Left,Encoder_Right);
  8. /***************************************************/
  9. // 1、确定直立环PWM
  10. Balance_Pwm = Balance_UP(pitch,gyro_y);
  11. // 2、确定速度环PWM
  12. Velocity_Pwm = velocity(Encoder_Left,Encoder_Right);
  13. // 3、确定转向环PWM
  14. // 4、确定最终左右电机PWM
  15. Moto1 = Balance_Pwm + Velocity_Pwm;
  16. Moto2 = Balance_Pwm + Velocity_Pwm;
  17. Xianfu_Pwm();
  18. Turn_Off(pitch);
  19. // 5、设置电机
  20. Set_Pwm(Moto1,Moto2);
  21. }

3、control.c文件内代码

  1. #include "control.h"
  2. #include "balance_car.h"
  3. int Dead_Zone = 200 ; //死区电压
  4. float Movement = 0 ; //速度调节
  5. float balance_UP_KP = 340 ; // 小车直立环KP
  6. float balance_UP_KD = 0.6 ;
  7. float velocity_KP = -60 ;
  8. float velocity_KI = -0.3 ;
  9. /**************************************************************************
  10. 函数功能:单位时间读取编码器计数
  11. 入口参数:定时器
  12. 返回 值:速度值
  13. **************************************************************************/
  14. int Read_Encoder(uint8_t TIMX)
  15. {
  16. int Encoder_TIM;
  17. switch(TIMX)
  18. {
  19. case 2: Encoder_TIM= (short)TIM2 -> CNT; TIM2 -> CNT=0;break;
  20. case 4: Encoder_TIM= (short)TIM4 -> CNT; TIM4 -> CNT=0;break;
  21. default: Encoder_TIM=0;
  22. }
  23. return Encoder_TIM;
  24. }
  25. /**************************************************************************
  26. 函数功能:直立PD控制
  27. 入口参数:角度、机械平衡角度(机械中值)、角速度
  28. 返回 值:直立控制PWM
  29. 作 者:大鱼电子
  30. **************************************************************************/
  31. int Balance_UP(float Angle,float Gyro)
  32. {
  33. float Bias;
  34. int Balance;
  35. Bias=Angle-Mechanical_balance; //===求出平衡的角度中值和机械相关
  36. Balance=balance_UP_KP*Bias+balance_UP_KD*Gyro; //===计算平衡控制的电机PWM PD控制 kp是P系数 kd是D系数
  37. return Balance;
  38. }
  39. /**************************************************************************
  40. 函数功能:速度PI控制
  41. 入口参数:电机编码器的值
  42. 返回 值:速度控制PWM
  43. **************************************************************************/
  44. int velocity(int encoder_left,int encoder_right)
  45. {
  46. static float Velocity,Encoder_Least,Encoder,Movement;
  47. static float Encoder_Integral;
  48. //==================速度PI控制器=============================================================//
  49. Encoder_Least =(Encoder_Left+Encoder_Right)-0; //===获取最新速度偏差==测量速度(左右编码器之和)-目标速度(此处为零)
  50. Encoder *= 0.8f; //===一阶低通滤波器
  51. Encoder += Encoder_Least*0.2f; //===一阶低通滤波器
  52. Encoder_Integral +=Encoder; //===积分出位移 积分时间:10ms
  53. Encoder_Integral=Encoder_Integral-Movement; //===接收遥控器数据,控制前进后退
  54. if(Encoder_Integral>10000) Encoder_Integral=10000; //===积分限幅
  55. if(Encoder_Integral<-10000) Encoder_Integral=-10000; //===积分限幅
  56. Velocity=Encoder*velocity_KP+Encoder_Integral*velocity_KI; //===速度控制
  57. if(pitch<-40||pitch>40)
  58. Encoder_Integral=0; //===电机关闭后清除积分
  59. return Velocity;
  60. }
  61. /**************************************************************************
  62. 函数功能:赋值给PWM寄存器
  63. 入口参数:左轮PWM、右轮PWM
  64. 返回 值:无
  65. **************************************************************************/
  66. void Set_Pwm(int moto1,int moto2)
  67. {
  68. if(moto1<0) AIN2(0), AIN1(1);
  69. else AIN2(1), AIN1(0);
  70. PWMA=Dead_Zone + myabs(moto1);
  71. if(moto2<0) BIN1(1), BIN2(0);
  72. else BIN1(0), BIN2(1);
  73. PWMB=Dead_Zone + myabs(moto2);
  74. }
  75. /**************************************************************************
  76. 函数功能:绝对值函数
  77. 入口参数:int
  78. 返回 值:unsigned int
  79. 目 的:经过直立环和速度环以及转向环计算出来的PWM有可能为负值
  80. 而只能赋给定时器PWM寄存器只能是正值。故需要对PWM进行绝对值处理
  81. **************************************************************************/
  82. int myabs(int a)
  83. {
  84. int temp;
  85. if(a<0) temp=-a;
  86. else temp=a;
  87. return temp;
  88. }
  89. /**************************************************************************
  90. 函数功能:限制PWM赋值
  91. 入口参数:无
  92. 返回 值:无
  93. **************************************************************************/
  94. void Xianfu_Pwm(void)
  95. {
  96. //===PWM满幅是7200 限制在7000
  97. if(Moto1<-7000 ) Moto1=-7000 ;
  98. if(Moto1> 7000 ) Moto1= 7000 ;
  99. if(Moto2<-7000 ) Moto2=-7000 ;
  100. if(Moto2> 7000 ) Moto2= 7000 ;
  101. }
  102. /**************************************************************************
  103. 函数功能:异常关闭电机
  104. 入口参数:倾角和电压
  105. 返回 值:无
  106. **************************************************************************/
  107. void Turn_Off(float angle)
  108. {
  109. if(angle<-40||angle>40) //===倾角大于40度关闭电机
  110. {
  111. AIN2(0), AIN1(0);
  112. BIN1(0), BIN2(0);
  113. }
  114. }

control.h文件内代码

  1. #ifndef __CONTROL_H
  2. #define __CONTROL_H
  3. #include "main.h"
  4. #define Mechanical_balance 0 //机械零点,无超声波、电池平躺着的小车机械中值
  5. #define AIN1(PinState) HAL_GPIO_WritePin(AIN1_GPIO_Port,AIN1_Pin,(GPIO_PinState)PinState)
  6. #define AIN2(PinState) HAL_GPIO_WritePin(AIN2_GPIO_Port,AIN2_Pin,(GPIO_PinState)PinState)
  7. #define BIN1(PinState) HAL_GPIO_WritePin(BIN1_GPIO_Port,BIN1_Pin,(GPIO_PinState)PinState)
  8. #define BIN2(PinState) HAL_GPIO_WritePin(BIN2_GPIO_Port,BIN2_Pin,(GPIO_PinState)PinState)
  9. #define PWMA TIM1->CCR4
  10. #define PWMB TIM1->CCR1
  11. //extern float Angle_Balance,Gyro_Balance; //平衡倾角 平衡陀螺仪 转向陀螺仪
  12. int Read_Encoder(uint8_t TIMX); //读取编码器计数
  13. int Balance_UP(float Angle,float Gyro); //直立环
  14. int velocity(int encoder_left,int encoder_right); //速度环
  15. void Set_Pwm(int moto1,int moto2);
  16. int myabs(int a);
  17. void Xianfu_Pwm(void);
  18. void Turn_Off(float angle);
  19. #endif

 三、代码下载

链接:https://pan.baidu.com/s/1zgqSLyWcIFV6QdJP-k0Mug 
提取码:DT99

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

闽ICP备14008679号