基于STM32F103C8T6定时器的PWM通道的重映射

在我们平时的的使用中,我们最常使用的是TIM2和TIM3的PWM通道,但是由于C8T6的IO口有限,所以可能会出现PWM通道的资源不够的情况,从而我们可能会使用PWM4的PWM通道,但是TIM4的PWM通道并不能直接使用,它需要进行一个重映射,不然可能会导致PWM波不能正常发送。以下就是对PWM4的PWM通道进行一个重映射

#include "stm32f10x.h"                  // Device header


void PWM_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);//选择时基单元
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

	//重映射 若无此函数会导致TIM4的PWM通道不能正常使用
	GPIO_PinRemapConfig(GPIO_Remap_TIM4 ,ENABLE);
		
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	TIM_InternalClockConfig(TIM4);//选择内部时钟
	
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitSturcture;
	TIM_TimeBaseInitSturcture.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInitSturcture.TIM_CounterMode=TIM_CounterMode_Up;//选择计时器计数模式
	TIM_TimeBaseInitSturcture.TIM_Period=720-1;//周期设置		
	TIM_TimeBaseInitSturcture.TIM_Prescaler=2000-1;//频率设置	
	TIM_TimeBaseInitSturcture.TIM_RepetitionCounter=0;
	
	TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitSturcture);//初始化时基单元
		
	TIM_OCInitTypeDef TIM_OCInitStructrue;
	TIM_OCStructInit(&TIM_OCInitStructrue);
	TIM_OCInitStructrue.TIM_OCMode=TIM_OCMode_PWM1;
	TIM_OCInitStructrue.TIM_OCPolarity=TIM_OCPolarity_High;
	TIM_OCInitStructrue.TIM_OutputState=TIM_OutputState_Enable;
	TIM_OCInitStructrue.TIM_Pulse=0;			//占空比	//CCR
	TIM_OC1Init(TIM4,&TIM_OCInitStructrue);
	TIM_OC2Init(TIM4,&TIM_OCInitStructrue);
	TIM_OC3Init(TIM4,&TIM_OCInitStructrue);
	TIM_OC4Init(TIM4,&TIM_OCInitStructrue);
	
	TIM_Cmd(TIM4,ENABLE);
			 										

}

void PWM_SetCompare(uint16_t Compare)
{
	TIM_SetCompare1(TIM4,Compare);
	TIM_SetCompare2(TIM4,Compare);
	TIM_SetCompare3(TIM4,Compare);
	TIM_SetCompare4(TIM4,Compare);
}

当使用重映射函数之后,PWM波才能正常发送。

GPIO_PinRemapConfig(GPIO_Remap_TIM4 ,ENABLE);

此重映射功能我查了许多资料都并未有很好的解释,以及为什么TIM4的PWM通道需要重映射我也没有求证到,我是在C8T6的PA15上得到的重映射的灵感,PA15是一个特殊的引脚,它也需要重映射为正常的IO口使用,后来我直接去看了此重映射函数,我发现TIM4有重映射功能,后来试了一下才能解决此问题。

不仅是TIM4的通道,TIM2的通道3和通道4也需要重映射,此通道3和4指的是PB10和PB11,这两个IO口也需要用重映射函数映射为PWM波输出的IO口,以下是TIM2通道3和4重映射的初始化示例

#include "stm32f10x.h"                  // Device header


void PWM_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//选择时基单元
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); 
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10|GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	GPIO_PinRemapConfig(GPIO_PartialRemap2_TIM2, ENABLE);
	
	TIM_InternalClockConfig(TIM2);//选择内部时钟
	
	TIM_TimeBaseInitTypeDef TIM2_TimeBaseInitSturcture;
	TIM2_TimeBaseInitSturcture.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM2_TimeBaseInitSturcture.TIM_CounterMode=TIM_CounterMode_Up;//选择计时器计数模式
	TIM2_TimeBaseInitSturcture.TIM_Period=720-1;//周期设置		
	TIM2_TimeBaseInitSturcture.TIM_Prescaler=2000-1;//频率设置	
	TIM2_TimeBaseInitSturcture.TIM_RepetitionCounter=0;
	
	TIM_TimeBaseInit(TIM2,&TIM2_TimeBaseInitSturcture);//初始化时基单元
		
	TIM_OCInitTypeDef TIM2_OCInitStructrue;
	TIM_OCStructInit(&TIM2_OCInitStructrue);
	TIM2_OCInitStructrue.TIM_OCMode=TIM_OCMode_PWM1;
	TIM2_OCInitStructrue.TIM_OCPolarity=TIM_OCPolarity_High;
	TIM2_OCInitStructrue.TIM_OutputState=TIM_OutputState_Enable;
	TIM2_OCInitStructrue.TIM_Pulse=0;			//占空比	//CCR
	TIM_OC3Init(TIM2,&TIM2_OCInitStructrue);
	TIM_OC4Init(TIM2,&TIM2_OCInitStructrue);
	TIM_Cmd(TIM2,ENABLE);
}

与TIM4的重映射不同,TIM2的重映射需要加上

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); 

TIM2的重映射只能用GPIO_PartialRemap2_TIM2,你可以自己去看一下这个的定义,他这个是把PB10和PB11映射为了通道3和4。我之前也试过用GPIO_FullRemap_TIM2,但是发现这个都不能正常的映射,所以只能用GPIO_PartialRemap2_TIM2。

以上代码我都以测试过能正常使用,读者可以自己写一个设置占空比的测试函数来验证一下是否能发波。如果此文章你觉得对你有帮助的话,请一键三连。

你可能感兴趣的:(stm32,嵌入式硬件,单片机)