OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4542|回复: 2

分享"通用定时器 预装载 Preload"的一点理解

[复制链接]

12

主题

72

帖子

0

精华

高级会员

Rank: 4

积分
504
金钱
504
注册时间
2015-9-9
在线时间
59 小时
发表于 2016-5-10 05:19:09 | 显示全部楼层 |阅读模式
本帖最后由 WM_CH 于 2016-5-10 05:23 编辑

关于通用定时器的预装载机制的问题,把自己的一点心得分享一下。
要是说的不对,还请大家指正。



首先就是影子寄存器,看这个链接:影子寄存器存在的作用
影子寄存器在这里实际上才是在比较的时候真正起作用的,目的是为了当预装载寄存器中的值更新后,影子寄存器仍然保持原来的值(这是在ARPE=1的情况下),参与比较操作的是影子寄存器,所以这样不会影响到计数器的工作误差。它在更新事件发生之后影子寄存器的值才从预装载寄存器那里获得更新。
当ARPE为0时,影子寄存器是立即更新的,不等待更新事件 的发生。

定时器框图中:预分频器寄存器自动重载寄存器捕捉/比较寄存器下面有一个阴影
这表示物理上这个寄存器对应2个寄存器:一个是我们可以可以写入或读出的寄存器,称为预装载寄存器,另一个是我们看不见的、无法真正对其读写操作的,但在使用中真正起作用的寄存器,称为影子寄存器.
设计预装载寄存器和影子寄存器的好处是,所有真正需要起作用的寄存器(影子寄存器)可以在同一个时间(发生更新事件时)被更新为所对应的预装载寄存器的内容,这样可以保证多个通道的操作能够准确地同步。如果没有影子寄存器,软件更新预装载寄存器时,则同时更新了真正操作的寄存器,因为软件不可能在一个相同的时刻同时更新多个寄存器,结果造成多个通道的时序不能同步,如果再加上例如中断等其它因素,多个通道的时序关系有可能会混乱,造成是不可预知的结果。


这是我找到的两个关于这方面的解释,基本上解释清楚了。记住:
预分频器寄存器PSC、自动重载寄存器ARR、捕捉/比较寄存器CCR
这三种寄存器在物理上是分为两个寄存器的即可。








之后是
三个库函数,3.5版
TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode)                           
  *     @arg TIM_PSCReloadMode_Update: The Prescaler is loaded at the update event.(更新事件到来时更新)
  *     @arg TIM_PSCReloadMode_Immediate: The Prescaler is loaded immediately(随时、立即更新).

TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState)
  *     @arg Enable  ||  Disable
TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload)
  *     @arg TIM_OCPreload_Enable  ||  TIM_OCPreload_Disable


读一下函数名就知道,这三个函数就是针对预装载开启与否的!如果不开启,修改的就是实际用于比较的影子寄存器了!!!
开启的话,只在更新事件到来时(即计数器=重装载寄存器溢出、定时器初始化时触发的事件),更新实际用于比较的影子寄存器。



由于开发手册里只针对PWM输出这一种模式进行了介绍。其实定时器输出有好几种模式。后边说。
PWM实验的代码中,只开启了捕获比较寄存器预装载功能
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
而在输入捕获实验的代码中,同时开启了捕获比较寄存器预装载功能;和自动重装载寄存器预装载功能
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM3, ENABLE);


搞的我顿时懵逼了。。。不知道这些个函数到底起什么作用。不懂机制的话,即使翻到函数实体处看具体操作了什么寄存器,也看不懂的!!!
这里,重点来了,我找了几个程序看了看,又试着调试了一下,符合我的判断。。。【大家看我总结的对不哈,讨论一下

我在《STM32自学笔记》中,看他的程序,对于输出模式,他列举了三种:
计数模式Timing、比较触发模式Toggle、PWM模式,其实还有几个其他的模式,我也不知道咋用
比较Toggle和PWM模式,发现,Toggle模式禁止了OC2Preload!!!


目的:引脚电平间隔固定时间翻转。假设定时器时钟为100us。
思想是:CNT计数比较寄存器CCR(CCR可随意定一个起始值N)的值,触发中断TIM_IT_CC。
在中断服务函数中获取CCR值,并将CCR值加上固定值(比如4000的话,就是固定间隔时间为0.4s)(N+4000),清中断标志后继续。
再次进入中断再次加上固定值,此时CCR值为(N+4000+4000),肯定超了CCR最大值65535(16bits)。
所以应该对65535取模再赋给CCR,即(N+4000+4000)%65535【他书里没取模
这样定时器某个通道的引脚电平就会以固定时间间隔翻转了。


附上书的内容截图:
无标题.jpg
这里为什么禁止了预装载。他的解释,我又没看懂。于是又懵逼了,我擦。。。。


后来琢磨了一下,应该是这样的:
假如开启了比较捕获寄存器的预装载功能,则比较捕获寄存器真正起作用的影子寄存器只能在计数器溢出的时候才能更新。
然而他的机制是每次固定间隔的CCR值是不同的,需要实时、立即更新到影子寄存器中起作用。以之用于和计数器的值进行比较。不能总是等到更新事件来才修改CCR的影子寄存器。
无标题2.jpg




说到这里,估计大家都明白我的意思了吧。。。
其他的两个ARR和PSC的预装载都是这个意思,就是修改生效的时刻。。。


而只要你的程序里不修改PSC、ARR、CCR,那么就不用管开启不开启预装载了!!





背景颜色在编辑的时候看着都一样,发布出来成这样了。。。大家凑合看吧

毕业两年才学STM32...
这些都没关系,重点是自己到底成长了没有
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2016-5-10 10:00:07 | 显示全部楼层
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

0

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
171
金钱
171
注册时间
2016-3-16
在线时间
48 小时
发表于 2016-5-11 16:04:06 | 显示全部楼层
顶一个
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-30 22:08

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表