输出比较可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形;
CNT的数据变化,与CCR进行比较,如果CNT>=CCR时,会改变OCxREF的电平状态,OCxREF可以被设置成触发主模式,可以映射到主模式的TRGO;不过更多还是通过TIMx_CCER进行极性选择和输出使能控制后实现GPIO上的输出(TIMx_CHx);
输出/输入数据寄存器控制输入和输出指的是GPIO的控制
复用功能输入输出指的是GPIO的复用及重定义功能在GPIO上的实现,复用输入,当由数据传入时,虽然输入数据寄存器和复用功能输入都由信号,但是复用功能上的信号进入片上外设后,外设已经定义对应功能,可以实现;输出时,就要选择复用功能,将数据输出寄存器断开,由片上外设进行GPIO的控制;
即GPIO的复用功能,在对片上外设进行相应操作后,就可实现信号的输入输出在GPIO上的操作;除了重映射外,复用功能并不会对GPIO的功能再做单独申请;因为复用线路其实已经打通的;
就像TIM2_CH1已经被复用再PA0,则只要设定好CCR相关,再PWM需要输出时,就会再PA0上输出;这里由一个问题,会不会存在两个复用功能同时或者先后在一个GPIO上输出,怎么实现??
实现PWM灯:
void PWM_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//使能定时器2的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//TIM2的比较输出通道1在GPIOA上
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//重映射到PA15上,需要开启AFIO时钟
GPIO_PinRemapConfig(GPIO_FullRemap_TIM2,ENABLE);//开启TIM2全部重映射
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//由于PIN15默认功能不是PAx,需先使PIN15上默认复用的功能失效先
GPIO_InitTypeDef GPIO_InitStruct;//初始化GPIO
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;//因为此GPIO要受复用的定时器控制,所以断开GPIO线,选择复用开漏输出
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_15;//选择重定义点位
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
TIM_InternalClockConfig(TIM2);//选择时钟来源为系统内部时钟
TIM_TimeBaseInitTypeDef TIM2Struct;//初始化时基单元
TIM2Struct.TIM_ClockDivision=TIM_CKD_DIV1;
TIM2Struct.TIM_CounterMode=TIM_CounterMode_Up;
TIM2Struct.TIM_Period=100-1;
TIM2Struct.TIM_Prescaler=720-1;
TIM2Struct.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM2,&TIM2Struct);//初始化时基单元
TIM_OCInitTypeDef TIM2_OCStruct;//初始化比较输出模块
TIM_OCStructInit(&TIM2_OCStruct);//对比较输出结构体初始化,附默认值,若没有此操作,使用通用定时器只对部分成员赋值,未赋值变量可能导致异常
//TIM2_OCStruct.TIM_OCIdleState=;高级定时器用
TIM2_OCStruct.TIM_OCMode=TIM_OCMode_PWM1;//选择PWM1模式输出
//TIM2_OCStruct.TIM_OCNIdleState=;高级定时器用
//TIM2_OCStruct.TIM_OCNPolarity=;高级定时器用
TIM2_OCStruct.TIM_OCPolarity=TIM_OCPolarity_High;//选择极性正
//TIM2_OCStruct.TIM_OutputNState=;高级定时器用
TIM2_OCStruct.TIM_OutputState=TIM_OutputState_Enable;//输出使能
TIM2_OCStruct.TIM_Pulse=0;//CCR初始给0,后面调用TIM_SetCompare1函数时传递需要的值
TIM_OC1Init(TIM2,&TIM2_OCStruct);
TIM_Cmd(TIM2,ENABLE);
}
void SET_PWM(uint16_t i)
{
TIM_SetCompare1(TIM2,i);//手动输出CCR值,现在PWM的占空比可调
}