stm32hal库平衡小车pid
时间: 2025-01-29 21:08:07 浏览: 56
### 使用 STM32 HAL 库实现平衡小车 PID 控制
#### 初始化硬件资源
为了使能霍尔编码器用于测量电机的速度,初始化过程需要设置TIMx定时器作为计数器来读取来自编码器A相和B相信号。这部分可以通过STM32CubeMX工具自动生成大部分必要的初始化代码。
```c
// 定义全局变量保存当前速度值
int16_t currentSpeed = 0;
```
对于PID控制器而言,还需要定义一些参数:
```c
typedef struct {
float Kp; // 比例系数
float Ki; // 积分系数
float Kd; // 微分系数
int32_t prevError; // 上一次误差
int32_t integral; // 累积误差
} PID_Controller;
PID_Controller pidCtrl = { .Kp=1.2f, .Ki=0.05f, .Kd=0.8f };
```
#### 编码器中断服务函数
每当检测到位置变化时触发此ISR(中断服务程序),更新`currentSpeed`变量以反映最新的转速信息[^1]。
```c
void TIMx_IRQHandler(void){
/* 清除标志位 */
__HAL_TIM_CLEAR_IT(&htimX, TIM_IT_UPDATE);
static uint32_t lastCount = 0;
const uint32_t nowCount = __HAL_TIM_GET_COUNTER(&htimX);
if (nowCount >= lastCount) {
currentSpeed = nowCount - lastCount;
} else {
// 处理溢出情况
currentSpeed = ((uint16_t)(-lastCount)) + nowCount;
}
lastCount = nowCount;
}
```
#### 计算目标PWM占空比
根据期望速度与实际速度之间的差异调整施加给电机的电压水平,从而达到稳定行驶的目的。
```c
float ComputeDutyCycle(int targetSpeed) {
int error = targetSpeed - currentSpeed;
pidCtrl.integral += error * pidCtrl.Ki;
float derivative = (error - pidCtrl.prevError) * pidCtrl.Kd;
float output = pidCtrl.Kp * error + pidCtrl.integral + derivative;
pidCtrl.prevError = error;
return constrain(output, MIN_DUTY_CYCLE, MAX_DUTY_CYCLE); // 将输出限制在一个合理范围内
}
inline float constrain(float amt, float low, float high) {
return amt < low ? low : (amt > high ? high : amt);
}
```
最后一步是在主循环里持续调用上述方法,并将计算得到的结果应用至相应的PWM通道上,以此改变电机的工作状态[^2]。
```c
while(1){
float dutyCycle = ComputeDutyCycle(desiredSpeed);
__HAL_TIM_SET_COMPARE(&htimX, TIM_CHANNEL_Y, dutyCycle);
}
```
阅读全文
相关推荐


















