1、TIM简介
•TIM(Timer)定时器
•定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断
•16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s(1/(72/2^16*2^16)) [2^16=65536]的定时
•不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能
•根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型
2、定时器类型
类型 |
编号 |
总线 |
功能 |
高级定时器 |
TIM1、TIM8 |
APB2 |
拥有通用定时器全部功能,并额外具有重复计数器、死区生成、互补输出、刹车输入等功能 |
通用定时器 |
TIM2、TIM3、TIM4、TIM5 |
APB1 |
拥有基本定时器全部功能,并额外具有内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等功能 |
基本定时器 |
TIM6、TIM7 |
APB1 |
拥有定时中断、主模式触发DAC的功能 |
高级定时器主要应用:三相无刷电机驱动设计。
STM32F103C8T6定时器资源:TIM1、TIM2、TIM3、TIM4
3、基本定时器结构图
实际分频系数=预分频器的值+1
UI(更新中段)触发中断 U↓(更新事件)不触发中断,但触发内部其他电路工作
硬件自己操作不需要中断,把更新事件通过主模式映射到TRGO,然后通过TRGO直接触发DAC
4、通用定时器结构图
5、高级定时器
6、定时器中断基本结构
运行控制:控制寄存器的一些位,启动停止、向上或向下计数等。主要控制时基单元
内外时钟源选择:时基单元左边的图块。
7、预分频器时序图
•计数器计数频率:CK_CNT = CK_PSC / (PSC + 1)
预分频缓存器(影子寄存器)作用:当突然改变分频值,必须等到更新事件之后,预分频寄存器的值才会被传到缓冲寄存器里面,才能生效。
8、计数器时序
•计数器溢出频率:CK_CNT_OV = CK_CNT / (ARR + 1) = CK_PSC / (PSC + 1) / (ARR + 1)
其中当更新中断标志为1,申请中断,然后响应后,手动清0;
溢出时间取频率倒数。
9、计数器无预装时序
10、计数器有预装时序
11、RCC时钟树
以72MHZ为界限,左边都是时钟产生的电路,右边是时钟分配的电路
其中外部比内部RC振荡器稳定
定时器中断(内部时钟)
12、主函数
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"
uint16_t Num;
int main(void)
{
OLED_Init();
Timer_Init();
while (1)
{
OLED_ShowNum(1, 1, Num, 5);
OLED_ShowNum(2,1,TIM_GetCounter(TIM2),5);
}
}
void TIM2_IRQHandler ()
{
if (TIM_GetITStatus(TIM2,TIM_IT_Update)==SET )//获取中断标志位
{
Num++;
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清楚TIM2中断标志位
}
}
Timer.c
#include "stm32f10x.h" // Device header
void Timer_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//开启APB1时钟函数
TIM_InternalClockConfig(TIM2);//选择时基单元的时钟
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructInit;
TIM_TimeBaseStructInit.TIM_ClockDivision=TIM_CKD_DIV1 ;//选择1分频,主要作用,滤波处理
TIM_TimeBaseStructInit.TIM_CounterMode=TIM_CounterMode_Up;//向上计数
TIM_TimeBaseStructInit.TIM_Period = 1000 -1;//周期,ARR自动重装器的值(同PSC取值范围0~65535)
TIM_TimeBaseStructInit.TIM_Prescaler= 7200 -1;//PSC预分频器的值
TIM_TimeBaseStructInit.TIM_RepetitionCounter=0;//重复计数器的值(高级定时器才有用)
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructInit);//初始化时基单元
TIM_ClearFlag(TIM2,TIM_IT_Update);//清除标志位,防止一上电就进入中断
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//开启更新中断到NVIC
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//优先级分组
NVIC_InitTypeDef NVIC_Initstructure;
NVIC_Initstructure.NVIC_IRQChannel= TIM2_IRQn ;//中断通道
NVIC_Initstructure.NVIC_IRQChannelCmd= ENABLE;
NVIC_Initstructure.NVIC_IRQChannelPreemptionPriority= 2;
NVIC_Initstructure.NVIC_IRQChannelSubPriority= 1;
NVIC_Init(&NVIC_Initstructure);
//启动定时器
TIM_Cmd(TIM2,ENABLE);
}
//中断函数
//void TIM2_IRQHandler ()
//{
// if (TIM_GetITStatus(TIM2,TIM_IT_Update)==SET )//获取中断标志位
// {
// TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清楚TIM2中断标志位
// }
//}
13、Proteus仿真