#include "stm32f10x.h" // Device header
#include
#include "Steer.h"
#include "Kinematics.h"
#include "PID.h"
extern float Given_Angle;
void Steer_PWM_Init(void)//PWM初始化
{
GPIO_InitTypeDef GPIO_Initstructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;//初始化TIMx的时间基数单位
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);
//GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);
GPIO_Initstructure.GPIO_Pin=GPIO_Pin_3 ;
GPIO_Initstructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
GPIO_Initstructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_Initstructure);
// TIM_InternalClockConfig(TIM5);
TIM_TimeBaseInitStructure.TIM_ClockDivision =TIM_CKD_DIV1;//设置时钟分频系数:不分频
TIM_TimeBaseInitStructure.TIM_CounterMode =TIM_CounterMode_Up;//向上计数模式
TIM_TimeBaseInitStructure.TIM_Period = 20000-1; //0-19999 计数20000次一个定时周期 20ms
TIM_TimeBaseInitStructure.TIM_Prescaler = 72-1; //72*20 -1; //设置预分频 1M Hz 1us计数一次
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//每次PWM 溢出中断
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//初始化TIM5的时基
//输出模式配置
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;;//PWM模式1
TIM_OCInitStructure.TIM_Pulse = 0; //占空比=配置占空比的值/TIM_TImeBaseStructure.TIM_Period
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//当定时器计数值小于CCR1_Val时为高电平
TIM_OC4Init(TIM2,&TIM_OCInitStructure);//初始化tim2通道4配置
TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);//使能预装功能
TIM_CtrlPWMOutputs(TIM2,ENABLE);
TIM_ARRPreloadConfig(TIM2, ENABLE); // 使能TIM2重载寄存器ARR
TIM_Cmd(TIM2,ENABLE);//使能TIM2
}
void PWM_SetCompare4(uint16_t Compare)//角度转换为比较寄存器的值
{
TIM_SetCompare4(TIM2,Compare);
}
void Steering_position(float angle)//angle为转向角度
{
float PWM_Output = 0;
angle = Given_Angle; //用于上传前轮的转向角度
angle = angle * P_STEER_WHEEL;// 舵机转角和前轮相对转角的比率,本质为将给定的前轮转角转化为舵机的转角
angle = LIMIT_MIN_MAX_FUN(angle, -STEERING_MAX_ANGLE, STEERING_MAX_ANGLE);
//左右角度限制 -STEERING_MAX_ANGLE
PWM_Output = 1500 - 100 / 9 * angle; //925 + 5 / 9 * angle;
PWM_SetCompare4(PWM_Output);
//(angle>0)?(TIM_SetCompare3(TIM5,Num)):(TIM_SetCompare3(TIM5,1500 + PWM_Output));
}
检查GPIO和TIMx的初始化是否正确
检查占空比计算公式是否正确
检查周期和预分频是否正确设置
检查输出极性是否正确设置
检查是否正确使能预装载功能和PWM输出
既TIM1_CCRx寄存器CCRi[15:0]
根据参考资料,可以找到解决方案如下:
针对该问题,可能存在的解决方案如下(仅供参考,具体实现需要根据具体情况进行调整):
// 1.配置定时器
TIM_HandleTypeDef htim;
htim.Instance = TIMx; // 定时器选型
htim.Init.Prescaler = 83; // 预分频设置
htim.Init.Period = 41999; // 自动重载值设置,计算公式:84Mhz/2/1000*20-1=41999
htim.Init.CounterMode = TIM_COUNTERMODE_UP; //计数模式
htim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; //时钟分割
if (HAL_TIM_PWM_Init(&htim) != HAL_OK) // 初始化PWM输出通道
{
// 初始化出错,进行错误处理
}
// 2.配置PWM输出
TIM_OC_InitTypeDef sConfigOC;
sConfigOC.OCMode = TIM_OCMODE_PWM1; // PWM输出模式1
sConfigOC.Pulse = 2099; // PWM脉冲宽度,计算公式:(1.5/20)*42000-1=2099
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; // PWM输出极性
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; // PWM快速模式禁用
if (HAL_TIM_PWM_ConfigChannel(&htim, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) // 配置PWM输出通道
{
// 配置出错,进行错误处理
}
// 3.设置GPIO复用输出功能
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = GPIO_PIN_X; // PWM输出引脚
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; // 复用推挽输出
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF_Y; // 定时器与引脚关联
HAL_GPIO_Init(GPIOx, &GPIO_InitStruct); // 初始化GPIO引脚
// 4.启用PWM输出
HAL_TIM_PWM_Start(&htim, TIM_CHANNEL_1); //启动通道1的PWM输出
HAL_TIM_Base_Start(&htim); // 启动定时器