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