计时器基本上是一种**“数数量游戏”**的概念!
设想一个场景,你前面有一个回转寿司的小火车,你的工作是把盘子放到小火车上,或是从小火车上把盘子拿下来,
那么这个游戏会有三种基本玩法:
- 给你一堆**”固定数量“的盘子,我说“开始”**,然后你把盘子连续放到小火车上,放完的时候要 “打开完成讯号” 告诉我!
- 从小火车上连续拿盘子下来;我说 “开始” 的时候,你从小火车上连续拿盘子,直到我说 “停” ,你就把 “拿到的数量” 告诉我。
- 红绿灯:连续拿盘子,第 “0~ A ” 个数盘子时,你把 ”红灯“ 打开,第“A+1~B” 个盘子时红灯切到 ”绿灯“,然后再 ”重新开始数“。
这个”小火车“ 就是 ”时脉“ clock。
从这个基本玩法可以加入变化,就形成 timer 的一些特殊功能了!
附件程式是用 PA 4 pin 脚 搭配 TIM14 组成的 PWM 功能。
#include <stdio.h>
#include "stm32f0xx.h" // File name depends on device used
#include "RTE_Components.h" // Component selection
//---------------------
void PWMPA4_init(void)
{
RCC->AHBENR |= 0x1ul <<17;
GPIOA->AFR[0] &= ~(0xful <<4*4);
GPIOA->AFR[0] |= 0x4ul <<4*4;
GPIOA->MODER &= ~(0x33ul << 4*2);
GPIOA->MODER |= 0x2ul << 4*2 ;
}
//-----------------------
void Config_timer14(void)
{
RCC->APB1ENR |= 0x1ul <<8;
TIM14->PSC = 480-1;
TIM14->ARR =100-1;
TIM14->CCR1 =80;
TIM14->CNT =0;
TIM14->CCMR1 |= 0x6ul << 4;
TIM14->CR1 |= (0x1ul << 7) | 0x1ul;
}
//--------------------
void PWMPA4_enable(void)
{
TIM14->CNT =0;
TIM14->CR1 |= 0x1ul;
TIM14->CCER |= 0x1ul;
}
//--------------------
void PWMPA4_disable(void)
{
TIM14->CCER &= ~ 0x1ul;
TIM14->CR1 &= ~0x1ul;
TIM14->CNT =0;
}
TIM14->CR1 像一个游戏规则设定器,设定火车速度、是否自动重数、设定向外中断提示
(TIM14->CCMR1) 捕获/比较 模式下,PWM 会用到。这个是设定时候使用。
(TIM14->CCER)捕获/比较模式 开关,这个是 PWM 操作中使用。
PSC 与 ARR
从网络查到的资料,大部分的人都被 PSC 与 ARR 困扰;仔细研究后,我的看法是:
- PSC 原本是为了后面的 counter做前处理的,只是,在算式上会变成系统时脉的因子。譬如,我们要counter 做完后产生 1 ms,而系统是 48M。原则上 PSC 要给 48-1 这个数字,counter 就要数 1000;有人就花式玩法, PSC 给 12-1,那么 counter 就要数4000 了。
- 回到最上一开始我描述的游戏,”给固定数量“ 和 ”拿到多少盘子“ 这两个过程是需要空间存放盘子(资料)的;如果是第一个游戏,那么还需要不断提供固定数量,这个就是 ARR 的工作。所以, ARR 在某些时刻可以被看成是counter 的分身。但是 CNT 还是有他独立的一面,主要是开始计数的过程,都是 CNT 在表演。
- 由于是实际的数数,在数字系统里的数字是从0 开始数的,如果数 10, 那么 就是从 0 开始 到 9. 所以, PSC 和 ARR 的设定值是要减一的。才会有
TIM14->PSC = 480-1;
TIM14->ARR =100-1; - 由于 CNT 就只是一个 register, 里面放着数字,所以,下面这个动作就只是把 CNT 清零,从 0 开始计数。
TIM14->CNT =0;
PSC 被称作 ”预除频“ ,在方块图里是放在 Counter 的前面,系统时脉进来后的第一个逻辑电路。原则上就是替 counter 预先处理不同的频率。
STMSTM32F072RB 的 Timer_ 1 做了一个整理,把英文用谷歌翻译成中文,参考一下!
TIM14 各种暂存器功能简述
下面我列出 TIM14 各个暂存器的简单描述,方便编程时参考:
TIM14 control register 1 (TIM14_CR1) – bit 0.1.2.7.8.9(TIMx 的主开关)
-CKD[1:0] Clock division(时脉选择)
-ARPE - Auto-reload preload enable(自动预载开关)
-URS -Update request source(更新的来源,1.– Counter overflow /2.– Setting the UG bit)
-UDIS - Update disable(关掉 更新(UEV)操作)
-CEN - Counter enable (计数器开始 --主要操作)
TIM14 interrupt enable register (TIM14_DIER)(各种中断开关)
-UIE: Update interrupt enable (来自 UEV 的中断要求)
-CC1IE: Capture/Compare 1 interrupt enable(来自 CC1 的中断要求)
TIM14 status register (TIM14_SR) – bit 0.1.9(各种状态指标)
-UIF: Update interrupt flag (UEV 中断)
-CC1IF: Capture/compare 1 interrupt flag(CC 1 中断)
-CC1OF: Capture/Compare 1 overcapture flag(CC1 重复获取)
TIM14 event generation register (TIM14_EGR) – bit 0.1(编程控制事件产生)
-UG: Update generation (产生UEV)
-CC1G: Capture/compare 1 generation(产生 CC1)
TIM14 capture/compare mode register 1 (TIM14_CCMR1) –bit 0~7(捕获和比较模式的设定)
-CC1S: Capture/Compare 1 selection(CC1 输出/输入 选择)
-CC1FE: Output compare 1 fast enable (加速 输出 比较的 开关)
-CC1PE: Output compare 1 preload enable (输出比较 的预载开关)
-OC1M: Output compare 1 mode (输出 比较的 模式选择 有 3 bit是 8 种模式)
-IC1F: Input capture 1 filter (输入捕获的波形过虑/整形)
-IC1PSC: Input capture 1 prescaler (输入捕获的预载)
TIM14 capture/compare enable register (TIM14_CCER) – bit 0.1.3(捕获和比较功能的开关)
-CC1NP: Capture/Compare 1 complementary output Polarity. (CC1 输出极性补偿)
-CC1P: Capture/Compare 1 output Polarity.(CC1 的输出极性选择)
-CC1E: Capture/Compare 1 output enable.(CC1 的输出极性开关)
TIM14 counter (TIM14_CNT)–16bit
TIM14 prescaler (TIM14_PSC)–16bit
TIM14 auto-reload register (TIM14_ARR)–16bit
TIM14 capture/compare register 1 (TIM14_CCR1) – 16bit
TIM14 option register (TIM14_OR) --bit0
TI1_RMP [1:0]: Timer Input 1 remap