向上计数模式
在递增计数模式下 , 计数器从0计数到自动重载值(寄存器的内容) , 然后从0重新开始计数 , 并产生一个计数器溢出事件 。
如果使用重复计数器 , 则在递增计数器重复了重复计数器寄存器()中所编程的次数后 , 会产生更新事件(UEV) 。否则 , 每次计数器溢出时都会产生更新事件 。
设置寄存器的 UG 位(通过软件或从机模式控制器)也会产生一个更新事件 。
UEV 事件可以通过软件将寄存器的UDIS位置位来禁用 。这是为了避免在预载寄存器中写入新值时更新影子寄存器 。那么在UDIS位被写入0之前 , 不会发生更新事件 。然而 , 计数器会从0重新开始 , 预分频器的计数器也是如此(但预分频率不变) 。此外 , 如果寄存器中的URS位(更新请求选择)被置位 , 则置位UG位会产生一个更新事件UEV , 但不会置位UIF标志(因此不会发送中断或DMA请求) 。这是为了避免在清除捕获事件计数器时同时产生更新和捕获中断 。
发生更新事件时 , 所有寄存器都会更新 , 更新标志(寄存器中的UIF位)也会被置位(取决于URS位):
下面的这两张图至关重要 , 涉及到寄存器动态改变后 , 计数器时序图如何变化 。这里面 , 前面的文章(高级定时器简介)中多次提到的中的ARPE位 , 将发挥重要作用 。
图47 , 计数器时序图 , 当ARPE=0时更新事件(未预加载)
先看图47 , 的值更新后 , 自动重载预装载寄存器的值立即更新(最后一行) 。原来的值是0xff , 那么第四行的寄存器应该计数到0xff才产生溢出 , 但是在计数器计数到0x32的时候 , 被更新到了0x36 , 图中这个设置是立即生效的 , 因为接下来第五行的定时器的溢出事件并没有计数到原来的0xff , 而是直接在计数到0x36这个新设置的值后就重新开始跑了 。这要归功于最重要的一项设置 , 就是ARPE=0 , 意思就是不要预加载 , 改动立即生效(其实前面的文章已经讲过 , 就是让ARR的预加载寄存器立即更新到影子寄存器) 。
图48 , 计数器时序图 , 当ARPE=1时更新事件(预加载)
再看图48 , 最重要的一项改动 , 就是ARPE=1 。原先的值为0xf5 , 但在第四行定时器的计数器跑到0xf1的时候 , ARR被改到了0x36 , 请看图 , 这个改动立即生效了吗?这时的值(0xf1)大于了ARR的预加载值(0x36) , 但时序图中的第五行并没有在这个时刻发生定时器溢出事件 , 第四行的计数器也没有被复位 , 而是继续跑 。同时自动重装载影子寄存器也没有被更新 , 还是0xf5 。而是要等到什么时候?等到计数器跑到原先值0xf5后这一切才被更新!
所以 , ARPE是干啥的?之前网上搜了大量文章硬是没搜出个名堂 , 现在终于解惑了!它就是对ARR预加载 , 不让改动立即生效 , 而是等到下一个更新事件到来 , 再把这个值传输到影子寄存器 。
向下计数模式
在递减计数模式下 , 计数器从自动重载值(寄存器的内容)递减计数至0 , 然后从自动重载值重新开始计数 , 并产生一个计数器下溢事件 。
【STM32F0x定时器之计数器模式】如果使用重复计数器 , 则在递减计数重复了重复计数器寄存器()中设置的次数后 , 会产生更新事件(UEV) 。否则 , 在每次计数器下溢时产生更新事件 。
设置寄存器的UG位(通过软件或从机模式控制器)也会产生一个更新事件 。
UEV更新事件可以被软件禁用 , 通过设置寄存器的UDIS位 。这是为了避免在预载寄存器中写入新值时更新影子寄存器 。那么在UDIS位被写入0之前 , 不会发生更新事件 。然而 , 计数器从当前自动重载值重新启动 , 而预分频器的计数器从0重新启动(但预分频率不变) 。
此外 , 如果寄存器中的URS位(更新请求选择)被置位 , 则置位UG位会产生一个更新事件UEV , 但不会置位UIF标志(因此不会发送中断或DMA请求) 。这是为了避免在清除捕获事件计数器时同时产生更新和捕获中断 。
发生更新事件时 , 所有寄存器都会更新 , 更新标志(寄存器中的UIF位)也会置位(取决于URS位):
中心对齐模式(向上/向下计数)
在中心对齐模式下 , 计数器从0计数到自动重载值(寄存器的内容)–1 , 产生一个计数器溢出事件 , 然后从自动重载值倒计数到1 , 并产生一个计数器下溢事件 。然后它从0开始重新计数 。
当寄存器中的CMS位不等于'00'时 , 中心对齐模式生效 。输出中配置的通道的输出比较中断标志在以下情况下置位:计数器递减计数(中心对齐模式1 , CMS = "01") , 计数器递增计数(中心对齐模式2 , CMS = "10") , 计数器递增计数和递减计数(中心对齐模式3 , CMS = "11") 。这里千万别被这个CMS位的这三种模式误解 , 虽然有三种模式 , 但计数器都是交替地向上和向下计数 , 只是输出比较中断标志什么时候被置位的区别 , 可以看寄存器手册中的相关定义 , 如下:
CMS[1:0]: 居中对齐模式选择
注意:只要计数器使能(CEN=1) , 就不允许从边缘对齐模式切换到中心对齐模式 。
在这种模式下 , 寄存器中的DIR方向位不能写入 。它由硬件更新并给出计数器的当前方向 。
每次计数器上溢和下溢时都会产生更新事件 , 或者通过设置寄存器中的UG位(通过软件或使用从机模式控制器)也会产生更新事件 。这种情况下 , 计数器从0开始重新计数 , 预分频器的计数器也是如此 。
通过设置寄存器的UDIS位 , 软件可以禁用UEV更新事件 。这是为了避免在预载寄存器中写入新值时更新影子寄存器 。那么在UDIS位被写入0之前 , 不会发生更新事件 。但是 , 计数器会根据当前的自动重装载值继续上下计数 。
此外 , 如果寄存器中的URS位(更新请求选择)被置位 , 则置位UG位会产生UEV更新事件 , 但不会置位UIF标志(因此不会发送中断或DMA请求) 。这是为了避免在清除捕获事件计数器时同时产生更新和捕获中断 。
发生更新事件时 , 所有寄存器都会更新 , 更新标志(寄存器中的UIF位)也会置位(取决于URS位):
图54 , 计数器时序图 , 内部时钟除以1 , = 0x6
图中使用的是中心对齐模式1 , UIF仅在计数器递减到1的时候产生中断 。且可以看出 , 计数器是交替上下计数的 。
- STM32F0x高级定时器简介
- STM32F0xx_DAC输出电压配置详细过程
- 【阿里云IoT+YF3300】4.Alink物模型之事件触发
- Day1 软件测试之自动化测试
- 深度学习之微表情识别
- 【阿里云IoT+YF3300】3. Alink物模型之属性上传和下发
- Kubernetes K8S之CPU和内存资源限制详解
- 【阿里云IoT+YF3300】5. Alink物模型之服务下发
- Ubuntu上可视化调试前端软件之VScode
- 落雨敏 Android的Okhttp框架之post、get用法讲解