STM32学习15--定时器3输出比较(OC) 一、核心概念定时器内部有两个关键寄存器1、CNT计数器向上/向下/中心模式不断自增自减2、CCRx捕获比较寄存器x1/2/3/4输出比较定时器不停把CNT与CCRx做对比当CNTCCRx时通道引脚自动执行预设动作电平翻转、置高、置低用于输出一定频率和占空比的PWM波形全程不需要CPU干预硬件自动输出波形属于硬件PWM的底层基础。3、每个高级定时器和通用定时器拥有4个输出比较通道。4、PWM简介PWMPlus Width Modulation脉冲宽度调制数字量在具有惯性的系统中可以通过对一系列脉冲的宽度进行调制来等效的输出所需要的模拟参量常用于电机控速等领域。PWM参数频率f1/Ts占空比Ton/Ts 分辨率占空比变化步距二、输出比较工作模式共计8种工作模式寄存器CCCMRx和OCxM其中PWM模式最常用分模式1和模式2其实模式1取反就是模式2。三、关键寄存器1、PSC预分频器对定时器时钟分频2、ARR自动重装值计数器最大值CNT涨到ARR清零3、CCRx比较值决定什么时候动作4、CCMRx选择输出比较模式OC1M位见手册5、CCER使能通道输出、设置有效电平极性定时器计数频率定时器时钟/(PSC1)PWM频率计数器频率/(ARR1)即定时器溢出频率定时器时钟/(PSC1)/(ARR1)PWM频率CCRx/(ARR1)四、使用方式1、普通输出比较OC toggle翻转模式功能每当CNT计数到CCR引脚电平翻转。该模式波形频率固定占空比50%适合做高精度方波时钟。配置逻辑1TIM向上计数2OC1M011翻转模式3开启通道输出使能4不用中断硬件自动翻转方式2PWM输出模式模式1工程上常用这个电机驱动、LED调光、电源调压。ARR周期CCR高电平时间五、配置步骤练习1普通输出比较翻转电平无中断。功能CNT等于CRR时引脚自动翻转产生标准方波不进中断。步骤如下1、打开时钟TIM时钟GPIO时钟2、GPIO配置复用推挽输出3、配置时基单元PSC、ARR、向上计数4、配置通道CCMROC模式翻转模式OCxM0x11此时使用TIM1故x15、CCER设置极性打开通道输出6、使能TIM计数器六、代码1、使用TIM1的1通道复用在PA8上。设PSC7200-1ARR1000-1计数频率72M/720010kHz翻转周期0.1s一秒闪烁5次。OutToggle.c文件#include stm32f10x.h // Device header void OCToggle_Init() { TIM_TimeBaseInitTypeDef TIM_BaseInitStructure; GPIO_InitTypeDef GPIO_InitStructure; TIM_OCInitTypeDef OC_Config; //开启时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); //初始化GPIO GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin GPIO_Pin_8; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOA,GPIO_InitStructure); //初始化时基单元 TIM_BaseInitStructure.TIM_ClockDivision TIM_CKD_DIV1; TIM_BaseInitStructure.TIM_CounterMode TIM_CounterMode_Up; TIM_BaseInitStructure.TIM_Period 1000-1; TIM_BaseInitStructure.TIM_Prescaler 7200-1; TIM_TimeBaseInit(TIM1,TIM_BaseInitStructure); //配置OC OC_Config.TIM_OCMode TIM_OCMode_Toggle; OC_Config.TIM_OutputState TIM_OutputState_Enable; OC_Config.TIM_OCPolarity TIM_OCPolarity_High; TIM_OC1Init(TIM1,OC_Config); TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Disable); //使能 TIM_CtrlPWMOutputs(TIM1,ENABLE); TIM_Cmd(TIM1,ENABLE); }.h文件#ifndef __OUTTOGGLE_H #define __OUTTOGGLE_H void OCToggle_Init(); #endifmain函数#include stm32f10x.h // Device header #include Delay.h #include OLED.h #include OutToggle.h int main() { OLED_Init(); OCToggle_Init(); while(1) { } }注意点如使用TIM1高级定时器则TIM_CtrlPWMOutputs(TIM1,ENABLE)要开启其他通用定时器不需要。2、工作逻辑1CNT从0往上累加2CNTCCR1的一瞬间硬件自动把PA8电平翻转3全程没有进入任何中断函数CPU空闲4调用TIM_SetCompare1(TIM1,xxx可以修改翻转点控制波形频率3、参数解析1TIM_OCInitTypeDef 结构体a)TIM_OCMode一共6个枚举分成两类普通输出比较PWM。普通OC非PWM①TIM_OCMode_Frozen匹配引脚不动冻结几乎不用②TIM_OCMode_ActiveCNT CCRx输出有效电平高电平③TIM_OCMode_InactiveCNT CCRx输出无效电平低电平④TIM_OCMode_ToggleCNT CCRx电平翻转定时电平自动翻转⑤TIM_OCMode_PM1/TIM_OCMode_PM2PWM专用LED调光、电机驱动b)TIM_OutputState通道输出使能开关TIM_OutputState_Enable通道打开引脚有波形不管哪种模式必须EnableTIM_OutputState_Disable通道关闭引脚不受定时器控制(Diable引脚无动作c)TIM_OCPolarity电平极性定义什么电平叫“有效电平”TIM_OCPolarity_High高电平就是有效电平TIM_OCPolarity_Low低电平就是有效电平在Toggle模式下这个极性参数不影响翻转功能高低都会翻转。在Active和PWM模式下才起作用比如OCModeActive极性HighCNTCCR输出高电平极性LowCNTCCR输出低电平。d)TIM_OutputNState互补输出高级定时器TIM1/TIM8才有Enable是打开互补Disable是关闭互补只有驱动H桥、三相电机、MOS管上下桥才开启。七、PWM模式1、核心计算公式PWM频率Freq72M/(PSC1/ARR1占空比Duty CCR/(ARR1)2、代码实现使用TIM2实现呼吸灯效果开启定时器及GPIO时钟输出引脚配置为复用推挽输出模式TIM2通道1对应PA0。TIM_TimeBaseInitTypeDef TIM_BaseInitStructure; GPIO_InitTypeDef GPIO_InitStructure; TIM_OCInitTypeDef OC_Config; //开启时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //初始化GPIO GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin GPIO_Pin_0; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOA,GPIO_InitStructure);配置时基单元、PWM模式、输出比较单元。//初始化时基单元 TIM_BaseInitStructure.TIM_ClockDivision TIM_CKD_DIV1; TIM_BaseInitStructure.TIM_CounterMode TIM_CounterMode_Up; TIM_BaseInitStructure.TIM_Period 100-1; TIM_BaseInitStructure.TIM_Prescaler 720-1; TIM_TimeBaseInit(TIM2,TIM_BaseInitStructure); //配置OC OC_Config.TIM_OCMode TIM_OCMode_PWM1; OC_Config.TIM_OutputState TIM_OutputState_Enable; OC_Config.TIM_OCPolarity TIM_OCPolarity_High; OC_Config.TIM_Pulse 0; TIM_OC1Init(TIM2,OC_Config);启动PWM输出和定时器TIM_OC1PreloadConfig(TIM2,TIM_OCPreload_Enable);//使能CCR预装载 TIM_ARRPreloadConfig(TIM2,ENABLE);//使能ARR预装载 TIM_Cmd(TIM2,ENABLE); //使能定时器设置CCR函数void SetCompare(uint16_t Compare) { TIM_SetCompare1(TIM2,Compare); }头文件#ifndef __OUTTOGGLE_H #define __OUTTOGGLE_H void PWM_Init(); void SetCompare(uint16_t Compare); #endifmain函数#include stm32f10x.h // Device header #include Delay.h #include OLED.h #include OutToggle.h int main() { OLED_Init(); OLED_ShowChar(1,1,A); PWM_Init(); while(1) { uint16_t i 0; for(i0 ;i100;i) { SetCompare(i); Delay_ms(10); } for(i0; i100;i) { SetCompare(100-i); Delay_ms(10); } } }八、常用参数1、常用频率与ARR、PSC定时器时钟72MHz目标频率(Hz)PSCARR占空比调节精度应用场景5072-120000-10.005%舵机控制、交流电过零检测100720-1100-11%继电器/低频开关控制1k72-11000-10.1%LED呼吸灯、常规音频信号20k72-150-12%电机调速40k01800-1≈0.05%超声波模块2、占空比与CCR值假设ARR1000-1即一个周期被分成1000份以下是CCR值目标占空比计算公式CCR值备注0%1000*0%0持续输出低电平10%1000*10%100低亮度LED/电机低速50%1000*50%500标准方波75%1000*75%750高亮度LED/电机中高速100%1000*100%1000持续输出高电平3、预装载 TIM_OC1PreloadConfig(TIM2,TIM_OCPreload_Enable)CRR动态调整占空比和TIM_ARRPreloadConfig(TIM2,ENABLE)ARR,动态调整周期/频率要开启保证在运行中动态修改CCR或ARR时波形不会畸变或毛刺使能预装载CCR/ARR会延迟生效直到当前周期结束才会更新新的值。本文完