STM32定时器输出比较模式

               OCx与OCxREF和CCxP之间的关系

初学STM32,我这个地方卡了很久,现在终于有些明白了,现在把我的理解写下与大家共享,如果有不对的地方,还请指出。

-----------------------------------------------------------------------------------------------------------------------

TIM_OCMode选择定时器模式。该参数取值见下表:


TIM_OCInitStructure.TIM_Pulse = CCR1_Val; //设置跳变值,当计数器计数到这个值时,电平发生跳变

TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIMx在CCR1上的预装载寄存器 
  TIM_ARRPreloadConfig(TIM3, ENABLE); //使能TIMx在ARR上的预装载寄存器 

-----------------------------------------------------------------------------------------------------------------------

OCxREF就是一个参考信号,并且约定:
OCxREF=1,称OCxREF有效。反之,OCxREF=0,称OCxREF无效;
 ‘1’电平(高电平)称为OCxREF的有效电平,‘0’ 电平(低电平)称为OCxREF的无效电平。
——依据参考手册:The output stage generates an intermediate waveform which is then used for reference:OCxRef (active high). The polarity acts at the end of the chain.
(翻译)输出阶段产生一个中间波形OCxRef(高有效)作为参考。输出信号的极性体现在信号链的末端。

现在解释几个名词之间的关系:



然后来理解输出比较的几个模式(PWM模式是输出比较模式的特例)
查看TIMx_CCMR1寄存器的OC1M域,有如下定义(摘自最新版的参考手册


翻译如下:
000:冻结——输出比较寄存器TIMx_CCR1中的内容与计数器TIMx_CNT中的内容之间的比较对输出无影响。(此模式用于时基的生成)
001:当匹配时,设置通道1为有效电平。当计数器TIMx_CNT中的内容与捕捉/比较寄存器1(TIMx_CCR1)中的内容相匹配时,强行拉高OC1REF 信号。
010:当匹配时,设置通道1为无效电平。当计数器TIMx_CNT中的内容与捕捉/比较寄存器1(TIMx_CCR1)中的内容相匹配时,强行拉低OC1REF 信号。
011:翻转——当TIMx_CNT= TIMx_CCR1时,OC1REF信号取反。
100:强制无效电平——强行拉低OC1REF 信号。
101:强制有效电平——强行拉高OC1REF 信号。
110:PWM模式1——向上计数模式中,只要TIMx_CNT< TIMx_CCR1,通道1有效,反之无效。向下计数模式中,只要TIMx_CNT> TIMx_CCR1,通道1无效(OC1REF=0),反之有效(OC1REF=1)。
110:PWM模式2——向上计数模式中,只要TIMx_CNT< TIMx_CCR1,通道1无效,反之有效。向下计数模式中,只要TIMx_CNT> TIMx_CCR1,通道1有效,反之无效。
我用红色标出了提到有效、无效的地方。不难发现,有效与无效分别对应OC1REF=1和OC1REF=0。这正是我们先前约定的结果。
到此,不同模式下输出比较的结果对OC1REF信号的影响已经很清楚了,但是最终的输出信号是OC1,并不是OC1REF。而且前面有一句话(输出信号的极性体现在信号链的末端)还未做解释。
到底OC1REF与OC1之间有何秘密呢?我们来看下面这个图:


显然,我们只关心红色圈内的信号与方框内的寄存器位以及信号在它们之间是如何传播的。
oc1ref从输出模式控制器(Output mode controller)开始,分为两路,上面一路至主模式控制器(To the master mode controller),这里我们不关心它的去向,我们关心的是下面一路,下面一路在进入双路开关之前又被分成了两路——一路是原信号,一路是原信号的非。显然TIMx_CCER中的CC1P位用来控制这个开关,CC1E位控制着整条信号链的通断。
当CC1P=0时(CC1E=1):


当CC1P=1时(CC1E=1):


很显然,OC1与OC1REF的关系只受CC1P的影响(CC1E=1)


然而参考手册上对CC1P位是这么描述的:


CC1P=0时:OC1高电平有效
CC1P=1时:OC1低电平有效
根据本文开篇的名词解释,可以这么理解:
CC1P=0时:OC1有效电平是高电平
CC1P=1时:OC1有效电平是低电平
这时就迷惑了,这个高电平有效和低电平有效是啥意思呢?
我们从头分析(整个过程CC1E=1,OC1的输出是允许的):
①假定OC1REF有效(OC1REF=1),那么从OC1REF到OC1的整条信号链上的信号都是有效信号,我们称OC1输出了有效信号。
那这个有效信号是高电平还是低电平呢?
这就是由CC1P决定的:


②假定OC1REF无效(OC1REF=0),那么从OC1REF到OC1的整条信号链上的信号都是无效信号,我们称OC1输出了无效信号。
无效信号的高电平和低电平也是由CC1P决定:

用一张表来总结上述过程:

OC1REF

CC1P

功能

OC1

描述

0

0

OC1高电平有效

0(低电平)

无效

1

OC1低电平有效

1(高电平)

无效

1

0

OC1高电平有效

1(高电平)

有效

1

OC1低电平有效

0(低电平)

有效







显然,OC1REF决定了OC1输出电平是否有效,而CC1P决定了有效电平的极性。
我们抽出上表的后四列

CC1P

功能

OC1

描述

0

OC1高电平有效

0(低电平)

无效

1

OC1低电平有效

1(高电平)

无效

0

OC1高电平有效

1(高电平)

有效

1

OC1低电平有效

0(低电平)

有效







我们将表按1、2列合并:

CC1P

功能

OC1

描述

0

 

OC1高电平有效

0(低电平)

无效

OC1高电平有效

1(高电平)

有效

1

 

OC1低电平有效

0(低电平)

有效

OC1低电平有效

1(高电平)

无效







现在很清楚了,从上表中可以清楚地看到CC1P对OC1有效极性的控制。即,OC1的极性只有与CC1P指定的有效极性一致,OC1才能是有效的(绿色部分)。这样就解释了“输出信号的极性体现在信号链的末端”这句话。
然而这条链还未结束,还有个CC1E呢。当然,它就是一个OC1输出使能位而已。
但细心的你可能会发现,参考手册上对CC1E位有这样的描述:


OCx = OCxREF + Polarity
这个式子告诉我们OCx与OCxREF和Polarity(极性,即CCxP位)的关系。
我们上面提到了它们的关系,是分了两种情况(CC1P=0和CC1P=1)表示的,这个式子帮我们将上面关系归纳成了一个。这个式子怎么得来的?
回忆一下数字电路里面的半加器(就是不进位的加法),真值表如下:

OCxREF

Polarity

OCx

0无效

0(高有效)

0无效

0无效

1(低有效)

1无效

1有效

0(高有效)

1有效

1有效

1(低有效)

0有效

我们写逻辑函数(按黄色部分写):



注意:前面的“+”号表示半加运算(不进位加法),其实是逻辑上的“异或”。


OC1连接到TIMx_CH1上,而TIMx_CH1是复用的。可在参考手册上定时器功能复用部分找到。
下面给出一些定时器功能复用的表格:

http://blog.sina.com.cn/s/blog_3ba262a10101esd1.html

  • 22
    点赞
  • 110
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
STM32中,定时器输出比较模式可以通过以下步骤进行配置: 1. 初始化定时器的时钟和基本设置,如定时器模式、预分频器和计数器方向等。 2. 配置定时器输出比较模式。这可以通过设置定时器输出比较寄存器(CCR)来完成。每个CCR寄存器控制一个输出通道。 3. 配置CCR寄存器的比较值(CCRx)和比较模式(OCxM)。比较值是一个16位的数字,用于与计数器的当前值进行比较比较模式定义了何时输出比较结果。 4. 配置CCR寄存器的输出模式(OCxPE和OCxFE)。OCxPE用于使能CCR寄存器的预装载功能。OCxFE用于使能CCR寄存器的快速输出模式。 下面是一个示例代码,用于配置定时器TIM1的输出比较通道1(CH1): ``` // 初始化定时器TIM1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructure.TIM_Period = 999; // 计数器重载值 TIM_TimeBaseStructure.TIM_Prescaler = 719; // 预分频器,得到1ms的计数周期 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 时钟分频 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 计数器向上计数 TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); // 配置TIM1的输出比较通道1 TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // 输出比较模式为PWM1 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 使能输出 TIM_OCInitStructure.TIM_Pulse = 500; // 比较值 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // 输出极性为高电平 TIM_OC1Init(TIM1, &TIM_OCInitStructure); // 使能TIM1 TIM_Cmd(TIM1, ENABLE); ``` 在这个示例中,定时器TIM1被初始化为一个1kHz的计数器。输出比较通道1被配置为PWM1模式比较值为500(占空比50%),输出极性为高电平。最后,定时器被使能并开始计数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值