文章目录
- 1.输出比较
- 2.PWM 介绍
- 3.配置PWM
1.输出比较
OC: 输出比较。
- 输出比较可以通过比较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模式选择改变极性;结构体配置选择极性时,也可改变)
2.PWM 介绍
-
脉冲宽度调制(PWM), 简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。
-
PWM 的频率: 是指1秒钟内信号从高电平到低电平再回到高电平的次数(一个周期)。也就是说一秒钟PWM有多少个周期。单位是HZ。
-
PWM 的周期: T=1/f, 50HZ=20ms, 如果频率为50Hz ,也就是说一个周期是20ms 那么一秒钟就有 50次PWM周期。
-
占空比: 是一个脉冲周期内,高电平的时间与整个周期时间的比例。脉宽时间占周期的比例。脉宽时间就是高电平的时间。
-
周期的时间是10ms,脉宽时间是8ms 那么低电平时间就是2ms 总的占空比 8/(8+2)= 80%。
PWM的参数:
- 频率: 1/Ts
- 占空比: TON/Ts
- 分辨率: 占空比变化步距
红线为CCR值,黄线为ARR,蓝线为CNT。
以PWM1为例,当CNT< ARR时为高电平,CNT > ARR时,为低电平。
3.配置PWM
第一步:RCC开启时钟,打开我们要用的TIM,GPIO外设的时钟打开。
第二步:配置时基单元。
第三步:配置输出比较单元,包括CCR的值,输出比较模式,极性选择,输出使能这些参数
第四步:配置GPIO位复用推挽输出。
第五步:运行控制。启动计数器。
初始化TIM输出比较功能:
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_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寄存器的预装功能:
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);
TIM:
#include "stm32f10x.h" void Timer_Init(void)
{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;//ARRTIM_TimeBaseInitStruct.TIM_Prescaler=7200-1;//PSCTIM_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模式1TIM_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
}
产生一个频率为1KHZ,占空比50%,分辨率为1%PWM波形:
CCR = 50, PSC = 720, ARR = 100
若两个引脚冲突,可使用重定义功能(引脚重映射),如图中TIM2的CH3,只能重映射到指定位置的引脚。
#include "stm32f10x.h" void Timer_Init(void)
{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);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;//ARRTIM_TimeBaseInitStruct.TIM_Prescaler=7200-1;//PSCTIM_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模式1TIM_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
}