STM32F1的PWM端口复用顺序问题

文章讨论了STM32F1中使用TIM4的PWM端口时,传统配置能正常工作,但当使用封装函数进行定时器参数设置时,代码失效。作者怀疑是复用顺序或对封装函数理解不足导致,强调了理解数据手册和深入思考的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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的情况来看都是能进入寄存器的。以前以为只要进入了寄存器就可以了,现在看来还是要多看数据手册和多思考理解问题和记录问题。

以后可以会再次遇到这样的问题,所以会记录一下。当下没有解决,以后可能会有思路。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值