STM32CubeMX PID差速循迹小车

简介: STM32CubeMX PID差速循迹小车

在之前TB6612驱动中,主要实现了固定速度下小车的循迹,在车身偏转使用默认的速度进行纠偏,使车身恢复正常状态。接线图和之前TB6612一样STM32Cubemx TB6612直流电机驱动-CSDN博客


今天要做的是,两路循迹判断车身偏的情况下,使用PID进行差速调节最后将误差分别给到左右电机,实现自动调速。


实现两路循迹PID控制差速的关键在于根据循迹模块的读数来计算出控制差速的误差,然后再利用PID控制算法来调节左右两侧驱动轮的转速。


一、CubeMX配置


SYS



RCC    选则外部高速晶振



GPIO 配置



T6612PWM配置



时钟树配置



freertos配置




二、Keil代码配置

在freertos.c添加代码

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "tim.h"
/* USER CODE END Includes */
 
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
uint16_t base_speed=120;
/* USER CODE END PTD */
 
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define Kp 15   // 比例参数
#define Ki 0.1   // 积分参数
#define Kd 0.05  // 微分参数
/* USER CODE END PD */


/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
void motorControlL(uint8_t direction, uint16_t speed) {//左电机驱动
  HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3);
    /* 根据方向设置 IN1 和 IN2 引脚 */
    HAL_GPIO_WritePin(GPIOA, BIN1_Pin, (direction & 0x01));
    HAL_GPIO_WritePin(GPIOA, BIN2_Pin, ((direction & 0x01) ^ 0x01));
 
    /* 设置 PWM 引脚以控制速度 */
    __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, speed);
}
void motorControlR(uint8_t direction, uint16_t speed) {//右电机驱动
     HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);
    /* 根据方向设置 AIN1 和 IN2 引脚 */
    HAL_GPIO_WritePin(GPIOA, AIN2_Pin, (direction & 0x01));
    HAL_GPIO_WritePin(GPIOA, AIN1_Pin, ((direction & 0x01) ^ 0x01));
 
    /* 设置 PWM 引脚以控制速度 */
    __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, speed);
}
 
// 读取左右循迹传感器数据
int read_left_trace_sensor() {
    // 返回左侧循迹传感器的读数
  uint16_t a=0;
  if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_8)==1){a=10;}
  else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_8)==0){a=6;}
  return a;
}
 
int read_right_trace_sensor() {
    // 返回右侧循迹传感器的读数
  uint16_t a=0;
  if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_9)==1){a=10;}
  else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_9)==0){a=6;}
  return a;
}
 
// 设置左右电机转速
void set_motor_speed(float left_speed, float right_speed) {
    motorControlL(1, left_speed); //第一个参数 0反向转  1正向转  第二个参数控制小车速度
    motorControlR(1, right_speed); // 控制左右电机的转速
}
 
// PID控制差速
void pid_control_diff() {
    int left_sensor_reading = read_left_trace_sensor();
    int right_sensor_reading = read_right_trace_sensor();
    
    // 计算误差
    float error = left_sensor_reading - right_sensor_reading;
    
    // 计算PID输出
    float output = Kp * error;
    
    // 根据输出值调整左右电机的转速
    float left_speed = base_speed + output;
    float right_speed = base_speed - output;
    
    // 将PID输出应用到电机控制
    set_motor_speed(right_speed, left_speed);
}
 
void BEEP(){
      HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_SET);
      osDelay(500);
      HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_RESET);
      osDelay(500);
      HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_SET);
      osDelay(500);
      HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_RESET);
}
/* USER CODE END FunctionPrototypes */


默认任务

/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void const * argument)
{
  /* USER CODE BEGIN StartDefaultTask */
  /* Infinite loop */
  uint8_t start=0;
  for(;;)
  {
    HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);
    osDelay(300);
  }
  /* USER CODE END StartDefaultTask */
}


主任务

/* USER CODE END Header_MainTask */
void MainTask(void const * argument)
{
  /* USER CODE BEGIN MainTask */
  /* Infinite loop */
  for(;;)
  {
 
    // 执行PID控制差速
    pid_control_diff();  
    
    if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_8)==1 && HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_9)==1){//stop
      motorControlL(0, 0); 
      motorControlR(0, 0);
      BEEP();
    }
   
  }
  /* USER CODE END MainTask */
}


链接: https://pan.baidu.com/s/1Pz_WwB-WyBlk_gm2Gab3xg?pwd=9yjh 提取码: 9yjh

目录
相关文章
|
6月前
|
物联网 程序员 语音技术
STM32智能小车(循迹、跟随、避障、测速、蓝牙、wife、4g、语音识别)总结-3
STM32智能小车(循迹、跟随、避障、测速、蓝牙、wife、4g、语音识别)总结
STM32智能小车(循迹、跟随、避障、测速、蓝牙、wife、4g、语音识别)总结-3
|
6月前
|
传感器 语音技术
STM32智能小车(循迹、跟随、避障、测速、蓝牙、wife、4g、语音识别)总结-1
STM32智能小车(循迹、跟随、避障、测速、蓝牙、wife、4g、语音识别)总结
STM32智能小车(循迹、跟随、避障、测速、蓝牙、wife、4g、语音识别)总结-1
|
6月前
|
传感器
STM32循迹小车原理介绍和代码示例
STM32循迹小车原理介绍和代码示例
|
5月前
使用STM32F103标准库实现定时器控制LED点亮和关闭
通过这篇博客,我们学习了如何使用STM32F103标准库,通过定时器来控制LED的点亮和关闭。我们配置了定时器中断,并在中断处理函数中实现了LED状态的切换。这是一个基础且实用的例子,适合初学者了解STM32定时器和中断的使用。 希望这篇博客对你有所帮助。如果有任何问题或建议,欢迎在评论区留言。
431 2
|
4月前
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
700 0
|
6月前
|
传感器
STM32标准库ADC和DMA知识点总结-1
STM32标准库ADC和DMA知识点总结
|
5月前
|
IDE 开发工具
使用STM32F103标准库实现自定义键盘
通过本文,我们学习了如何使用STM32F103标准库实现一个简单的自定义键盘。我们首先初始化了GPIO引脚,然后实现了一个扫描函数来检测按键状态。这个项目不仅能够帮助我们理解STM32的GPIO配置和按键扫描原理,还可以作为进一步学习中断处理和低功耗设计的基础。希望本文对你有所帮助,祝你在嵌入式开发的道路上不断进步!
506 4
|
5月前
|
传感器
【经典案例】STM32F407使用HAL库配置I2C详解
STM32F407是一个强大的微控制器,广泛应用于嵌入式系统中。在许多应用中,我们需要使用I2C总线来与传感器、EEPROM、显示屏等外设进行通信。本文将详细介绍如何使用STM32 HAL库来配置和使用I2C接口。
676 2