当前位置:   article > 正文

STM32——定时器——输出比较

STM32——定时器——输出比较

一、输出比较简介

OCOutput 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

PWM简介

PWM(Pulse Width Modulation)脉冲宽度调制
具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速等领域。
在这里插入图片描述
在这里插入图片描述

PWM参数:
频率 = 1 / TS
占空比 = TON / TS
分辨率 = 占空比变化步距

PWM基本结构

在这里插入图片描述
红线为CCR值,黄线为ARR,蓝线为CNT。
以PWM1为例,当CNT<ARR时高电平,>时,为低电平。
在这里插入图片描述

三、配置PWM

第一步: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);
  • 1
  • 2
  • 3
  • 4

结构体赋默认值

void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct);
  • 1

配置强制输出模式

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);
  • 1
  • 2
  • 3
  • 4

配置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);
  • 1
  • 2
  • 3
  • 4

配置快速使能

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);
  • 1
  • 2
  • 3
  • 4

外部事件时清除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);
  • 1
  • 2
  • 3
  • 4

单独设置输出比较极性的(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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

来单独修改输出使能参数的

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);
  • 1
  • 2

单独修改输出比较模式的

void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode);//
  • 1

单独配置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);
  • 1
  • 2
  • 3
  • 4

仅高级定时器使用,当高级定时器输出PWM时,调用此函数,使能主输出,否则无法正常输出PWM。

void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState);
  • 1

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

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;

配置PWM波形输出端口

配置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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
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
		}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

延时函数的作用是,防止LED变化过快,人眼无法捕捉现象(呈现出一平均值,设置为0-100占空比,若没有延时函数,平均值为50),故暂定一段时间。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/309907
推荐阅读
相关标签
  

闽ICP备14008679号