赞
踩
OC(Output Compare)输出比较
输出比较可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形。
每个高级定时器和通用定时器都拥有4个输出比较通道
高级定时器的前3个通道额外拥有死区生成和互补输出的功能
工作流程
最左边是寄存器CNT和CCR1的捕获比较寄存器,CNT≥CCR1时(需提前配置好CCR1中的值,使用结构体变量配置CCR1,也可函数单独配置)
给输出模式控制器传递信号,控制器再给OC1ref(reference即参考信号)传递高低电平;
REF主要走下路,通过极性选择后(写0,走上路保持原电平;写1,走下路电平取反;故配置OC模式时,需选择极性,使用结构体变量配置极性);
输出使能电路选择是否输出(CC1E给输出使能电路写值;故配置OC模式时,需使能OC电路,使用结构体变量使能电路);
最后到达OC1引脚,到达GPIO口。
冻结:CNT和CCR无效,REF保持原状态。
匹配时置有效电平和无效电平,分别是指高低电平。(信号是一次性的,不适合输出连续变化的波形;如置配置时置有效电平模式,满足条件后,信号一直保持有效电平)
配置时电平翻转:可以形成一个50占空比的PWM波形。
强制为无效或有效电平,和冻结模式类似,只是指定了冻结后的高低电平,如果想暂停输出波形,并且在暂停期间置高低电平,可以选择此模式。
PWM1和PWM2,一般使用向上计数,二者只是极性不同,通常使用PWM1。
输出模式和选择极性都可以配置信号极性,非常灵活。(即PWM模式选择改变极性;结构体配置选择极性时,也可改变)
PWM(Pulse Width Modulation)脉冲宽度调制
在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速等领域。
PWM参数:
频率 = 1 / TS
占空比 = TON / TS
分辨率 = 占空比变化步距
红线为CCR值,黄线为ARR,蓝线为CNT。
以PWM1为例,当CNT<ARR时高电平,>时,为低电平。
第一步:RCC开启时钟,打开我们要用的TIM,GPIO外设的时钟打开。
第二步:配置时基单元。
第三步:配置输出比较单元,包括CCR的值,输出比较模式,极性选择,输出使能这些参数
第四步:配置GPIO位复用推挽输出。
第五步:运行控制。启动计数器。
承接上节函数介绍,将继续介绍,与TIM输出比较相关的函数的作用。
初始化TIM输出比较功能 (OC1-4分别为定时器的四个通道)
void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);//重要 参数1:选择定时器;参数2:结构体配置具体功能
void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
结构体赋默认值
void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct);
配置强制输出模式
void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
配置CCR寄存器的预装功能(预装功能上节有讲,不在叙述;OC1-4分别表示4个输出/捕获通道)
void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
配置快速使能
void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
外部事件时清除REF信号
void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
单独设置输出比较极性的(N是指高级定时器的互补通道,结构体初始化也可以设置极性,一般来说结构体里的参数都可以用函数来单独修改的)。
void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
来单独修改输出使能参数的
void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx);//
void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN);
单独修改输出比较模式的
void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode);//
单独配置CCR的值的
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);
void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);
void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4);
仅高级定时器使用,当高级定时器输出PWM时,调用此函数,使能主输出,否则无法正常输出PWM。
void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState);
TIM配置代码
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); TIM_InternalClockConfig(TIM2); TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInitStruct.TIM_Period=10000;//ARR TIM_TimeBaseInitStruct.TIM_Prescaler=7200-1;//PSC TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct); //以上为配置时基单元的部分,详看上节 TIM_OCInitTypeDef TIM_OCInitStructure;//结构体赋初值,下面再更改我们需要用的值,结构体变量中有很多高级定时器的功能,我们暂不需要,调用函数设默认值即可 TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;//配置为PWM模式1 TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;//极性选择 TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//配置使能 TIM_OCInitStructure.TIM_Pulse=;//配置CCR的值(可提前配置,PWM则保持一个固定的占空比;也可后续调用函数更改,改变PWM的占空比) TIM_OC1Init(TIM2, &TIM_OCInitStructure);//将TIM2中OC1配置为上述模式 TIM_Cmd(TIM2,ENABLE );//打开定时器2
PWM频率 Freq=CK_PSC/(PSC+1)/(ARR+1)
PWM占空比 Duty=CCR/(ARR+1)
PWM分辨率Reso=1/(ARR+1)
产生一个频率为1KHZ,占空比50%,分辨率为1%PWM波形
得:ARR=100;CCR=50;PSC=720;
配置OC1借用的GPIO口
再STM32最小系统板中,TIM2的CH1和ETR都复用在PA0引脚上,故使用TIM2的CH1只能在PA0输出。
若两个引脚冲突,可使用重定义功能(引脚重映射),如图中TIM2的CH3,只能重映射到指定位置的引脚。
GPIO配置代码
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出模式,将控制权转交给片上外设。
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
void PWM_SetCompare1(uint16_t n) { TIM_SetCompare1(TIM2,n);//单独更改PWM占空比 } //主程序 while中 for (i = 0; i <= 100; i++) { PWM_SetCompare1(i); //依次将定时器的CCR寄存器设置为0~100,PWM占空比逐渐增大,LED逐渐变亮 Delay_ms(10); //延时10ms } for (i = 0; i <= 100; i++) { PWM_SetCompare1(100 - i); //依次将定时器的CCR寄存器设置为100~0,PWM占空比逐渐减小,LED逐渐变暗 Delay_ms(10); //延时10ms }
延时函数的作用是,防止LED变化过快,人眼无法捕捉现象(呈现出一平均值,设置为0-100占空比,若没有延时函数,平均值为50),故暂定一段时间。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。