基本定时器__毫秒微秒延时
基本定时器介绍(STM32F40x)
STM32F40X芯片一共包含14个定时器,这14个定时器分为3大类:
通用定时器 | 10个 | TIM9-TIM1和TIM2-TIM5 具有基本定时器功能, 还具有输入捕获,输出比较功能 |
高级定时器 | 2个 | TIM1和TIM8 具有通用定时器和基本定时器功能, 还具有死区刹车功能。 |
基本定时器 | 2个 | TIM6和TIM7 能实现基本定时功能和DAC模块触发功能 |
注:若只存在6个定时器。TIM1一定为高级定时器,TIM6一定为基本定时器。其余为通用。
若存在10个定时器。TIM1&&TIM8为高级定时器,TIM6&&TIM7为基本定时器。其余为通用。
基本定时器概述(STM32F40x)
基本定时器TIM6和TIM7各包含一个16位的自动重载计数器(最大计数值是0~ 2^16-1),该计数器由可编程预分频器驱动(降低计数频率,达到更长的计时要求)。
可编程预分频器(降低计数频率): 一个脉冲计一次数;更长计时:十个脉冲计一次数。
基本定时器不仅能用来作为简单的计数功能,还可以用来作为通用定时器的时基单元,还可以用作驱动DAC模块。
基本定时器特征(STM32F40x)
①基本定时器的计数范围是:0-65535,计数方式为递增计数。
②可以对基本定时器的时钟源进行分频:分频系数介于1-65536之间,分频的目的是为了满足更长的计时时间要求。
③可以作为DAC模块的驱动时钟
④在基本定时器的计数器溢出的时候,可以产生一个更新事件,并同时可以产生一个中断/DMA请求。
定时器的时钟源
如下图,如果芯片的工作频率到此时钟总线的频率的分频系数为1,则频率不变。否则X2。
如果若使用的定时器的是时钟频率不是总频就要考虑是否要X2的问题,而且X2之后的频率绝对不会超过总频。
基本定时器内部框图(STM32F40x)
①CK_PSC为主频,通过“预分频器”得到定时器时钟(CK_CNT)。
预分频器:设置分频值,降低计数频率,增长计数时间。(一个脉冲计数一次,分频后:多个脉冲计数一次,时间增长)
预分频器有影子寄存器,且影子寄存器不可设置,长期自动开启。
内核只会读取影子寄存器的分频值。当更新事件UEV后,上层新的预分频值才会替换掉影子寄存器内的旧分频值。
②CNT COUNTER:计数器当前计数的值。计数器上溢。
事件更新UEV:当前计数的值到达计数周期。
③自动重载寄存器:设置计数周期(计数的最大值)。
新的自动重载寄存器的值,只能在事件更新UEV后,才会替换掉重载影子寄存器的值。
第一次开启计数器时,有UG位手动更新重载影子寄存器的值。
状态寄存器:产生事件更新UEV时,状态寄存器标志位变为1,只有重新清0,才可再次计数。手动设置UG位,引起UEV,也需要状态寄存器状态位清0。
定时器时基单元 (TIM6/TIM7)
可编程定时器的主要模块由一个 16 位递增计数器及其相关的自动重载寄存器组成。计数器的时钟可通过预分频器进行分频。
计数器、自动重载寄存器和预分频器寄存器可通过软件进行读写。即使在计数器运行时也可执 行读写操作。
定时器的时基单元是定时器最基本的寄存器
①计数器寄存器:定时器计数工作寄存器,从0开始(不一定是0,想从多少开始则将数值直接写给计数器寄存器即可)累积计数到自动重装载数值,从而产生溢出,重新开始从初始值计数。
②预分频寄存器:对输入的时钟源进行分频,降低计数频率,达到更长的计时要求。
③自动重装载寄存器:定时器的工作周期(决定了计数器一周期内计数的次数/最大范围)。
分频器分频1->2
计数器时序图
自动重载寄存器(ARR预装载)
基本定时器相关寄存器(STM32F40x)
总述:
自动重载寄存器是预装载的。每次尝试对自动重载寄存器执行读写操作时,都会访问预装载寄存器。预装载寄存器的内容既可以直接传送到影子寄存器,也可以在每次发生更新事件 UEV 时传送到影子寄存器,这取决于 TIMx_CR1 寄存器中的自动重载预装载使能位 (ARPE)。当计数器达到上溢值并且 TIMx_CR1 寄存器中的 UDIS 位为 0 时,将发送更新事件。该更新事件也可由软件产生。
计数器由预分频器输出 CK_CNT 提供时钟,仅当 TIMx_CR1 寄存器中的计数器启动位 (CEN) 置 1 时,才会启动计数器。
TIM6初始化
开启时钟。
控制寄存器TIMx_CR1(TIM6和TIM7)
计数器 TIMx_CNT (TIM6和TIM7)
预分频器 TIMx_PSC (TIM6和TIM7)
自动重载寄存器 TIMx_ARR (TIM6和TIM7)
状态寄存器 TIMx_SR (TIM6和TIM7)
事件生成寄存器 TIMx_EGR (TIM6和TIM7)
基本定时器编程思路(STM32F40x)
/************************************************
函数功能:定时器TIM6初始化
函数参数:
psc:分频值
arr:自动重载值
时间(s) = 计数周期(arr) / 计数频率
计数频率 = 定时器工作频率(hz 已知)/分频系数(psc)
定时器工作频率:42*2MHZ == 84000000HZ
设:psc == 8400 -----> 计数频率 == 10000
设:arr == 10000 ----> 时间 == 1s
************************************************/
void TIM6_Init(uint16_t psc,uint16_t arr)
{
RCC->APB1ENR |= 1<<4; //开启时钟
TIM6->CR1 |= 1<<7; //自动重载预装载使能
TIM6->CR1 &= ~(1<<3); //循环计数
TIM6->CR1 &= ~(1<<2); //选择事件更新源
TIM6->CR1 &= ~(1<<1); //事件发生后更新影子寄存器的值
//设置时基单元
TIM6->CNT = 0; //设置计数初始值
TIM6->PSC = psc -1; //设置分频值
TIM6->ARR = arr; //设置自动重载值
TIM6->EGR |= 1<<0; //手动更新UG位
TIM6->SR &= ~(1<<0); //状态寄存器,清除标志位
TIM6->CR1 |= 1<<0; //使能计数器
}
使能基本定时器时钟
- 配置基本定时器的功能模式:是否开启影子寄存器、计数模式。。。。。
- 写计数器初始值,预分频值、自动重装载值。
- 如果使用中断,则开启中断
- 手动产生更新事件(UG位)
- 清标志位
- 启动计数器
基本定时器实现毫秒微秒延时
公式:
时间(s) = 计数周期(arr) / 计数频率
计数频率 = 定时器工作频率(hz 已知)/分频系数(psc)
TIM7挂载在APB1(42MHZ)线上,不为时钟总频,所以定时器工作频率:42*2*1000000HZ
定时器工作频率:42*2MHZ == 84000000HZ
设:psc == 8400 -----> 计数频率 == 10000
设:arr == 10000 ----> 时间 == 1s
毫秒:
设:arr== 10 ------> 时间 == 1s/1000 == 1ms
微秒:
设:psc==84;arr==1 ------> 时间== 1ms/1000 == 1us
举例:
//毫米延时
void delay_ms(uint16_t num)
{
uint16_t i = 1;
//10000 -> 1s 10 -> 1ms
TIM7_Init(8400,10);
while(1)
{
if(TIM7->SR & 1<<0)
{
TIM7->SR &= ~(1<<0);
i++;
}
if(i == num)
break;
}
}
//微秒延时
void delay_us(uint16_t num)
{
uint16_t i = 1;
//10000 -> 1s 10 -> 1ms
TIM7_Init(84,1);
while(1)
{
if(TIM7->SR & 1<<0)
{
TIM7->SR &= ~(1<<0);
i++;
}
if(i == num)
break;
}
}