STM32F407 三路巡线模块 PID控制舵机转向标准库函数代码
时间: 2024-03-30 22:26:15 浏览: 189
库函数版本的IMU901代码-适用STM32F407
以下是使用STM32F407标准库函数进行三路巡线模块PID控制舵机转向的代码:
```
#include "stm32f4xx.h"
#define KP 2.0 // 比例系数
#define KI 0.5 // 积分系数
#define KD 0.2 // 微分系数
int main(void)
{
// 初始化GPIO口和PWM输出
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; // 模拟输入
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; // 输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_TIM5);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF_TIM5);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM5, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM5, DISABLE);
TIM_TimeBaseStructure.TIM_Period = 19999; // PWM周期为20ms
TIM_TimeBaseStructure.TIM_Prescaler = 419; // 分频系数为420
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM5, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM5, TIM_OCPreload_Enable);
TIM_OC2Init(TIM5, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM5, TIM_OCPreload_Enable);
TIM_Cmd(TIM5, ENABLE);
// 初始化PID控制参数
float error[3] = {0, 0, 0}; // 误差数组
float integral = 0; // 积分项
float derivative = 0; // 微分项
int lastError = 0; // 上一次误差值
float pwm = 0; // PWM占空比
while(1)
{
// 读取三路巡线模块的输入
uint16_t sensor[3];
sensor[0] = ADC_GetConversionValue(ADC1);
sensor[1] = ADC_GetConversionValue(ADC2);
sensor[2] = ADC_GetConversionValue(ADC3);
// 计算误差值
error[2] = error[1];
error[1] = error[0];
error[0] = (sensor[0] * 2 + sensor[1] - sensor[2] * 2) / 100;
integral += error[0];
derivative = error[0] - lastError;
lastError = error[0];
// 计算PWM占空比
pwm = KP * error[0] + KI * integral + KD * derivative;
// 控制舵机转向
int angle = 90 - pwm; // 转动角度为90°减去PWM占空比
if(angle < 0)
{
angle = 0;
}
else if(angle > 180)
{
angle = 180;
}
TIM_SetCompare1(TIM5, angle * 111 + 500); // 将角度转换为PWM脉宽输出
// 等待一段时间再进行下一次循环
for(int i = 0; i < 100000; i++);
}
}
```
在这个代码中,我们使用了STM32F407的定时器5作为PWM输出,GPIOB的0、1、2引脚作为舵机控制信号输出,GPIOA的0、1、2引脚作为三路巡线模块的输入。我们使用了PID控制算法来控制舵机的转向,其中KP、KI、KD分别是比例系数、积分系数和微分系数,可以根据具体情况进行调整。最后我们将角度转换为PWM脉宽输出,控制舵机转向。
阅读全文