STM32F1的PWM端口复用顺序问题#
#STM32F1的PWM端口复用顺序问题
按照传统的从上到下的顺序配置下来代码能够正常运行,但是在定时器配置哪里使用了封装函数,代码就不能正常运行,寄存器通过debug查看是在重装载的。
正常配置
就是大多数例程中的正常配置
/*************************************************
Function: PWM_config
Description: tim4定时器通道四 PD12 复用(重映射)输出PWM波
Input:
Output:
Return:
*************************************************/
void PWM_config(u16 arr , u16 psc)
{
GPIO_InitTypeDef GPIO_Motorinit;//配置GPIO结构体初始化
TIM_TimeBaseInitTypeDef TIM_Motorinit;//配置定时器结构体初始化
TIM_OCInitTypeDef TIMPWM_Motorinit;//配置舵机定时器结构体初始化
//1.打开时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);//配置GPIO时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);//配置定时器时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//配置引脚复用时钟
GPIO_PinRemapConfig(GPIO_Remap_TIM4,ENABLE);//配置重映射模式为部分重映射
//2.配置GPIO结构
GPIO_Motorinit.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
GPIO_Motorinit.GPIO_Pin = GPIO_Pin_12;//pin口配置为5
GPIO_Motorinit.GPIO_Speed = GPIO_Speed_50MHz;//速度配置为50Mhz
GPIO_Init(GPIOD,&GPIO_Motorinit);//配置GPIO初始化函数
//3.配置通用定时器结构体
TIM_Motorinit.TIM_ClockDivision = TIM_CKD_DIV1;//设置时钟不分频
TIM_Motorinit.TIM_CounterMode = TIM_CounterMode_Up;//设置计数方式为向上计数
TIM_Motorinit.TIM_Period = arr-1;//设置在下一个更新事件装入活动的自动重装载值为199
TIM_Motorinit.TIM_Prescaler = psc-1;//TIM时钟频率预分频值为7199
TIM_TimeBaseInit(TIM4,&TIM_Motorinit); //配置定时器初始化函数
//4.配置定时器输出PWM结构体
TIMPWM_Motorinit.TIM_OCMode = TIM_OCMode_PWM1;//配置PWM定时器模式为1
TIMPWM_Motorinit.TIM_OutputState = TIM_OutputState_Enable;//使能PWM比较输出
TIMPWM_Motorinit.TIM_OCPolarity = TIM_OCNPolarity_Low;//选择有效输出的极性
TIM_OC1Init(TIM4,&TIMPWM_Motorinit);//配置初始化函数
TIM_Cmd(TIM4,ENABLE);//使能PWM输出
TIM_OC1PreloadConfig(TIM4,TIM_OCPreload_Enable);//自动加载的预装载寄存器使能
}
不正常配置
采用了封装函数
/*************************************************
Function: vTIM_TimeBase_Init
Description: 定时器参数设置
Input:
Output:
Return:
*************************************************/
void vTIM_TimeBase_Init(TIM_TypeDef* TIMx,u16 Period,u16 Prescaler )
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = Period-1;//重载值
TIM_TimeBaseStructure.TIM_Prescaler = Prescaler-1;//预分频系数
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructure);
}
/*************************************************
Function: vTIM4_Config
Description: 开启基本定时功能
Input:
Output:
Return:
*************************************************/
void vTIM4_Init(TIM_TypeDef* TIMx,u16 Period,u16 Prescaler )
{
TIM_OCInitTypeDef TIM4PWM_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
GPIO_InitTypeDef GPIO_Motorinit;//配置GPIO结构体初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//配置引脚复用时钟
//1.打开时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);//配置GPIO时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);//配置定时器时钟
GPIO_PinRemapConfig(GPIO_Remap_TIM4,ENABLE);//配置重映射模式为部分重映射
GPIO_Motorinit.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
GPIO_Motorinit.GPIO_Pin = GPIO_Pin_12;//pin口配置为5
GPIO_Motorinit.GPIO_Speed = GPIO_Speed_50MHz;//速度配置为50Mhz
GPIO_Init(GPIOD,&GPIO_Motorinit);//配置GPIO初始化函数
vTIM_TimeBase_Init(TIMx,Period,Prescaler);
//PWM初始化
TIM4PWM_InitStructure.TIM_OCMode = TIM_OCMode_PWM1; //定时器模式1
TIM4PWM_InitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较模式输出使能
TIM4PWM_InitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //选择有效输出极性
TIM_OC1PreloadConfig(TIMx, TIM_OCPreload_Enable);
TIM_OC1Init(TIMx, &TIM4PWM_InitStructure); //配置PWM通道
TIM_Cmd(TIMx, ENABLE);
}
最后
简单记录一下在项目中的玄学的问题,可能是经验太少 ,自己也尝试过修改代码顺序,发现第一种顺序就可以正常 运行,第二种就不可以。但是两种配置的情况通过debug的情况来看都是能进入寄存器的。以前以为只要进入了寄存器就可以了,现在看来还是要多看数据手册和多思考理解问题和记录问题。
以后可以会再次遇到这样的问题,所以会记录一下。当下没有解决,以后可能会有思路。