stm32f103双电机PID
时间: 2025-01-01 07:32:13 浏览: 8
### STM32F103 双电机 PID 控制
#### 一、硬件配置
STM32F103微控制器具备多种外设资源,能够支持复杂的电机控制任务。对于双电机PID控制而言,主要涉及如下几个部分:
- **UART通信**:用于上位机与STM32之间的参数设置及状态监控。
- **PWM输出**:通过TIM14定时器生成两路独立的PWM波形来驱动两个直流电机。
- **ADC采样**:利用ADC1采集电机编码器反馈回来的角度信息以及电流值,以便于计算误差并调整PWM占空比。
这些外设共同作用实现了对双电机的速度和位置精确调控[^1]。
#### 二、软件设计思路
为了实现高效的PID算法,在程序结构方面建议采用RTOS(实时操作系统),这样不仅可以提高系统的响应速度还可以简化多任务处理逻辑。具体来说就是创建多个线程分别负责不同职责比如读取传感器数据、执行PID运算、更新PWM脉宽等操作。
另外需要注意的是,由于存在两个电机因此需要维护两套相互独立却又同步工作的PID控制器实例;同时考虑到实际应用场景可能会有外部干扰因素影响测量精度所以还需要加入滤波机制以提升鲁棒性[^2]。
#### 三、代码示例
下面给出一段简单的C语言伪代码片段展示如何初始化上述提到的相关外设,并编写基本框架下的PID调节函数。
```c
#include "stm32f1xx_hal.h"
// 定义全局变量存储当前目标值和实际测量到的位置/转速
float target_position_motor_1, measured_position_motor_1;
float target_position_motor_2, measured_position_motor_2;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM14_Init(void); // 初始化PWM通道
static void MX_ADC1_Init(void); // 初始化AD转换器
/* 用户自定义的PID类 */
typedef struct {
float kp; /*比例系数*/
float ki; /*积分系数*/
float kd; /*微分系数*/
} pid_t;
pid_t motor_pid_1 = {8.0f, 0.5f, 0.1f}; // 设置第一个电机对应的PID参数
pid_t motor_pid_2 = {7.5f, 0.4f, 0.1f}; // 设置第二个电机对应的PID参数
/**
* @brief 计算单个电机所需的PWM占空比
*
* @param[in] setpoint 设定的目标值
* @param[in] feedback 实际测得的反馈量
* @return 返回经过PID计算后的PWM百分比
*/
float calculate_pwm_duty_cycle(float setpoint, float feedback, pid_t* pid){
static float prev_error = 0.0f;
static float integral_sum = 0.0f;
float error = setpoint - feedback;
integral_sum += error;
float derivative = (error - prev_error);
float output = pid->kp * error + pid->ki * integral_sum + pid->kd * derivative;
prev_error = error;
return constrain(output, MIN_PWM_DUTY_CYCLE, MAX_PWM_DUTY_CYCLE);
}
int main(){
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM14_Init();
MX_ADC1_Init();
while(true){
// 获取来自编码器或者其他形式的位置传感装置的数据
measured_position_motor_1 = read_encoder_value_for_motor_1();
measured_position_motor_2 = read_encoder_value_for_motor_2();
// 调用calculate_pwm_duty_cycle() 函数得到新的PWM占空比设定值
float duty_cycle_1 = calculate_pwm_duty_cycle(target_position_motor_1, measured_position_motor_1,&motor_pid_1);
float duty_cycle_2 = calculate_pwm_duty_cycle(target_position_motor_2, measured_position_motor_2,&motor_pid_2);
// 更新相应的PWM通道输出水平
update_pwm_output(TIM_CHANNEL_1,duty_cycle_1);
update_pwm_output(TIM_CHANNEL_2,duty_cycle_2);
osDelay(LOOP_DELAY_MS); // 使用FreeRTOS延时一定时间再进入下一个循环周期
}
}
```
此段代码展示了基于STM32平台上的双电机PID闭环控制系统的核心要素,包括但不限于硬件抽象层(HAL)库调用方式、PID公式的具体表达形式等内容。
阅读全文