STM32F103ZE(精英版、战舰版)有8个16位的定时器,其中有4个通用定时器,2个高级定时器,2个基本定时器。
具体区别如下图:
STM32F103的通用定时器是TIM2、TIM3、TIM4、TIM5.
▶位于低速APB1总线上(时钟可以来源于APB1的时钟)
▶16位向上、向下、中心对齐 的计数模式,自动装载计数器(TIMx_CNT)。
▶16位可实时修改的预分频器(TIMx_PSC),计数器时钟频率的分频系数位1~65535之间的任意数值。(分频之后计数器的时钟频率变小,因此可以计数更长的周期)
▶每一个定时器都有4个独立通道(TIMx_CH1~4),这些道路可以用来作为:
①输入捕获
②输出比较
③PWM生成
④单脉冲模式输出
通用定时器可以向上计数、向下计数、向上向下双向计数模式。
①向上计数模式:
计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件。
②向下计数模式:
计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。
③中央对齐模式(向上/向下计数):
计数器从0开始计数到自动装入的值,产生一个计数器溢出事件;然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。
▶图中红圈内是对定时器的时钟选择配置;
▶蓝色圈内是定时器作为计时器、定时的相关配置;
▶左下绿色区域是用来“输入捕获”,也就是测量脉冲的宽度;
▶右下黄色区域是输出比较寄存器,例如,比某个设定的值大时输出为1,比它小时输出为0,可用作PWM
定时器的时钟可来自内部时钟(CK_INT)
定时器时钟由内部时钟的来由过程:
✦首先由AHB的时钟经过APB1时钟的预分频系数产生ABP1的时钟,如果ABP1的预分频为1,那么定时器的时钟(CK_INT)为ABP1的时钟乘以1;如果ABP1的预分频不为1,则为ABP1乘以2。
✦又由于定时器的时钟选择来源于内部时钟,因此CK_PSC等于CK_INT;之后CK_PSC再除以PSC寄存器的值N(预分频系数)则得到计数器的时钟CK_CNT。
例如在默认情况下SYSCLK=72M;AHB时钟=72M;APB1时钟=36M;所以APB1的分频系数为2;因此通用定时器的时CK_INT=2*36M=72M,也就是说CK_PSC=72M,之后再除以PSC寄存器的值,就得到CK_CNT的频率。
实际上走的是这一条路线:
实现用定时器控制led在500ms闪烁一次
▶定时器参数初始化:
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
第二个参数的结构体定义如下:
typedef struct
{
uint16_t TIM_Prescaler; 初始化预分频系数
uint16_t TIM_CounterMode; 计数模式
uint16_t TIM_Period; 自动装载值
uint16_t TIM_ClockDivision; 在输入捕获模式才用
uint8_t TIM_RepetitionCounter; 在高级定时器才使用
} TIM_TimeBaseInitTypeDef;
▶定时器使能函数:
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
第一个参数是哪个定时器;第二个参数是ENABLE/DISABLE
▶定时器中断使能函数:
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
第一个参数是哪个定时器;第二个参数是中断源;第三个参数是ENABLE/DISABLE
▶状态标志位获取和清楚函数:
FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);
RCC_APB1PeriphClockCmd();
实例中为:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
TIM_TimeBaseInt();
实例中为:
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up; 向上计数模式
TIM_TimeBaseInitStruct.TIM_Period=arr; 自动装载值
TIM_TimeBaseInitStruct.TIM_Prescaler=psc; 预分频系数
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);
void TIM_ITConfig();
NVIC_Init();
实例中:
NVIC_InitTypeDef NVIC_InitStruct;
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); 使能定时器中断3
NVIC_InitStruct.NVIC_IRQChannel=TIM3_IRQn; 选择初始化定时器中断3
NVIC_InitStruct.NVIC_IRQChannelCmd= ENABLE; 使能
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0; 抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority=3; 响应优先级
NVIC_Init(&NVIC_InitStruct);
TIM_Cmd();
实例中:
TIM_Cmd(TIM3,ENABLE);
TIMx_IRQHandler();
实例中:
void TIM3_IRQHandler()
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)
{
LED1=!LED1;
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
}
}