stm32循迹小车如何控制转向的角度
时间: 2025-02-08 11:20:48 浏览: 59
### STM32 控制循迹小车转向角度实现方法
#### 1. PID控制器设计
为了使小车能够沿着预定轨迹行驶并保持稳定,通常会引入PID(比例-积分-微分)控制算法来调节转向角度。该算法依据传感器反馈的信息动态调整输出值,从而减小小车实际位置与期望路径之间的偏差。
对于基于STM32的智能循迹避障小车而言,在接收到由OpenMV相机传送过来的目标线路相对于车身中心轴线的位置偏移数据之后,可以将其作为输入信号送入PID控制器内部进行运算处理[^1]。
```c
// 定义PID参数结构体
typedef struct {
float Kp; // 比例系数
float Ki; // 积分系数
float Kd; // 微分系数
int prev_error;
long sum_error;
} pid_t;
void init_pid(pid_t *pid, float kp, float ki, float kd){
pid->Kp=kp;
pid->Ki=ki;
pid->Kd=kd;
pid->prev_error = 0;
pid->sum_error = 0;
}
float compute_pid_output(pid_t* pid, int current_error){
static unsigned long last_time = millis();
unsigned long present_time = millis();
double delta_time = (present_time - last_time)/1000.0f;
last_time=present_time;
// 计算误差变化率
int d_input=current_error-pid->prev_error;
pid->prev_error=current_error;
// 累加误差用于积分项计算
pid->sum_error+=current_error*delta_time;
// 返回最终输出结果
return (pid->Kp*current_error)+(pid->Ki*pid->sum_error)+(pid->Kd*d_input/delta_time);
}
```
#### 2. PWM调速机制
通过改变脉宽调制(PWM)波形占空比的方法可有效调控直流电动机的工作状态。具体来说就是根据PID控制器给出的方向修正指令相应增减两侧驱动马达所接收电能的比例关系,进而影响各自转速大小,以此达成精准操控车辆航向的效果[^2]。
例如当检测到当前姿态存在左侧偏离情况,则适当减少右侧轮子的动力供给使其减速慢行;反之亦然。这样就能让整个装置始终维持在一个较为理想的直行或转弯过程中。
```c
#define LEFT_MOTOR_PIN PB8
#define RIGHT_MOTOR_PIN PB9
TIM_HandleTypeDef htim3;
void setup_pwm(){
__HAL_RCC_TIM3_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct={};
HAL_NVIC_SetPriority(TIM3_IRQn, 0 , 0);
HAL_NVIC_EnableIRQ(TIM3_IRQn);
TIM_OC_InitTypeDef sConfigOC={};
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH ;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE ;
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9 ;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate=GPIO_AF2_TIM3;
HAL_GPIO_Init(GPIOB,&GPIO_InitStruct);
htim3.Instance = TIM3;
htim3.Init.Period = 999;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.ClockDivision= TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_DISABLE;
HAL_TIM_PWM_Init(&htim3);
HAL_TIM_PWM_ConfigChannel (&htim3, &sConfigOC,TIM_CHANNEL_1 );
HAL_TIM_PWM_ConfigChannel (&htim3, &sConfigOC,TIM_CHANNEL_2 );
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);
}
void set_motor_speed(int leftSpeed,int rightSpeed){
uint32_t duty_cycle_left=(uint32_t)((leftSpeed+100)*4.95);
uint32_t duty_cycle_right=(uint32_t)((rightSpeed+100)*4.95);
if(duty_cycle_left>1000)duty_cycle_left=1000;
if(duty_cycle_right>1000)duty_cycle_right=1000;
__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,duty_cycle_left);
__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_2,duty_cycle_right);
}
```
阅读全文
相关推荐


















