本节我们介绍通用定时器的定时中断功能,通用定时器就是在基本定时器的定时功能上加上了时钟源选择,看下面两幅框图即可一目了然
通用定时器的2和基本定时器一样,只是多了一个时钟源选择1,2这一部分被称为时基单元,那我们就先对时基单元展开描述
时基单元
时基单元由16位的预分频器,16位的计数器,16位的重装寄存器,操作步骤大概为时钟经过分频器分频,然后每来一个时钟计数器计数,当计数器溢出产生中断请求和更新事件,重装寄存器给计数器赋初值(向上计数不存在),那么我们就具体来论述每一个部分。
分频器
分频器本质上是一个计数器,可以看下图预分频计数器,当你赋值给1时,实际上是对时钟源二分频也就是对半分,因为给1之后计数从0~1循环,因为是16位的寄存器,所以分频系数PSC可以给的很大,最大65535
计数器
先介绍三种计数方式
- 向上计数,从0一直加到重装寄存器的值(常用)
- 向下计数,从重装寄存器的值一直减到0
- 中央对齐,像个三角波,从0到寄存器-1,从寄存器值到1
重装寄存器
重装寄存器在计数方式的介绍中可以看出有两种功能
- 给计数器赋初值
- 与计数器作比较
缓冲寄存器
重装寄存器和预分频寄存器都具有缓冲寄存器,缓冲寄存器可以让他们随时被写入,但生效的时机可以自由选择,是立刻生效还是等待更新事件之后,这个功能可以被函数开启或关闭,具体体会看下面的图
中断和更新事件
计数器计数溢出会产生一个中断(如果使能了)和一个更新事件,更新事件更新所有寄存器
时钟源的选择
我们主要讲内部时钟,外部时钟模式1和2,且只说调用方法
内部时钟
内部时钟由系统时钟提供,为72MHZ,内部时钟代码调用
TIM_InternalClockConfig(TIM2);内部时钟调用
外部时钟模式2
外部时钟只有一个时钟源,就是ETR引脚,我只知道TIM2的ETR引脚是PA0,其他的TIM就不知道了 ,由图看来,要配置外部时钟模式2,需要配置ETR引脚信号的极性选择,分频系数,滤波器
- 极性选择,就是接了一个非门,变相选择上升沿还是下降沿有效
- 分频系数,跟极性选择配合起来,就是来分频系数个边沿才作为一个脉冲
- 滤波器(不太懂)
配置代码
TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0x00);
*TIM2:TIMx
*TIM_ExtTRGPSC_OFF:不对外部信号分频
TIM_ExtTRGPSC_DIV2:2分频
TIM_ExtTRGPSC_DIV4:4分频
TIM_ExtTRGPSC_DIV8:8分频
*TIM_ExtTRGPolarity_NonInverted:上升沿有效
TIM_ExtTRGPolarity_Inverted:下降沿有效
*0x00:滤波器,0x00~0x0F
外部模式1
最后,我们配置定时器定时中断的步骤就清晰了
- 时钟源
- 时基单元
- 中断使能
- 总开关控制
差点忘记最重要的一点了,如何计算定时中断的时间
中断频率 = 时钟源频率 / 分频系数+1 / 重装值+1 (以内部时钟,向上计数为例)
中断时间 = 中断频率倒数
例如我想产生一个1s的中断信号,也就是中断频率为1HZ,可以给分频系数7200-1,重装值10000-1以此来产生1s的中断
TIM初始化代码
void MyTIM_Init(void)
{
开启时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
选择内部时钟
TIM_InternalClockConfig(TIM2);
选择外部时钟ETR,外部时钟模式2
TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0x00);
*TIM2:TIMx
*TIM_ExtTRGPSC_OFF:不对外部信号分频
TIM_ExtTRGPSC_DIV2:2分频
TIM_ExtTRGPSC_DIV4:4分频
TIM_ExtTRGPSC_DIV8:8分频
*TIM_ExtTRGPolarity_NonInverted:上升沿有效
TIM_ExtTRGPolarity_Inverted:下降沿有效
*0x00:滤波器,0x00~0x0F
选择外部时钟ETR,但是外部时钟模式1
TIM_ETRClockMode1Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0X00);
*TIM2:TIMx
*TIM_ExtTRGPSC_OFF:不对外部信号分频
TIM_ExtTRGPSC_DIV2:2分频
TIM_ExtTRGPSC_DIV4:4分频
TIM_ExtTRGPSC_DIV8:8分频
*TIM_ExtTRGPolarity_NonInverted:上升沿有效
TIM_ExtTRGPolarity_Inverted:下降沿有效
*0x00:滤波器,0x00~0x0F
TIM_SelectInputTrigger(TIM2,TIM_TS_ETR);时钟源选择
This parameter can be one of the following values:
* @arg TIM_TS_ITR0: Internal Trigger 0
* @arg TIM_TS_ITR1: Internal Trigger 1
* @arg TIM_TS_ITR2: Internal Trigger 2
* @arg TIM_TS_ITR3: Internal Trigger 3
* @arg TIM_TS_TI1F_ED: TI1 Edge Detector
* @arg TIM_TS_TI1FP1: Filtered Timer Input 1
* @arg TIM_TS_TI2FP2: Filtered Timer Input 2
* @arg TIM_TS_ETRF: External Trigger input
ETR引脚初始化
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
时基单元初始化
TIM_TimeBaseInitTypeDef TIM_InitStructure;
TIM_InitStructure.TIM_ClockDivision=TIM_CKD_DIV1;高级定时器的功能
TIM_InitStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_InitStructure.TIM_Period=7200-1;重装值
TIM_InitStructure.TIM_Prescaler=10000-1;分频系数
TIM_InitStructure.TIM_RepetitionCounter=0x00;高级定时器的功能
TIM_TimeBaseInit(TIM2,&TIM_InitStructure);
中断使能,计数器溢出中断是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=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStructure);
总开关
TIM_Cmd(TIM2,ENABLE);
}
中断服务函数
void TIM2_IRQHandler(void)
{
if(TIM_GetFlagStatus(TIM2,TIM_IT_Update)==SET)
{
执行内容
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
}
Time.h函数库中与这一节比较重要的函数
TIM_TimeBaseInit 时基单元初始化 |
TIM_Cmd 总开关控制 |
TIM _ITConfig 中断使能 |
TIM_InternalClockConfig 内部时钟 |
TIM_ETRClockMode1Config 外部时钟模式1 | |
TIM_ETRClockMode2Config 外部时钟模式2 |
TIM_SelectInputTrigger 外部时钟模式1的时钟源选择 |
TIM_PrescalerConfig 写分频系数,同时使能或失能预分频寄存器的缓冲功能 |
TIM_CounterModeConfig 计数模式选择 |
TIM_ARRPreloadConfig 使能或使能重装寄存器的缓冲功能 |
TIM_SetCounter | 设置 TIMx 计数器寄存器值 |
TIM_SetAutoreload 设置重装值 |
TIM_GetCounter | 获得 TIMx 计数器的值 |
TIM_GetPrescaler 获得分频系数 |
TIM_GetFlagStatus | 检查指定的 TIM 标志位设置与否 |
TIM_ClearFlag | 清除 TIMx 的待处理标志位 |
TIM_GetITStatus | 检查指定的 TIM 中断发生与否 |
TIM_ClearITPendingBit 清除中断标志位 |