定时器中断
今天看了看定时器中断,感觉和systick有一点像既然有了systick的经验,TIMx的中断应该能手到擒来吧。
下面是参考手册给出的TIMx简介
通用定时器是一个通过可编程预分频器驱动的16位自动装载计数器构成。 它适用于多种场合,包括
- 测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和PWM)。
- 使用定时器预分频器和RCC时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。
每个定时器都是完全独立的,没有互相共享任何资源。它们可以一起同步操作。
TIMx主要功能通用TIMx (TIM2、TIM3、TIM4和TIM5)定时器功能包括:
- 16位向上、向下、向上/向下自动装载计数器
- 16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65536之间的任意数值
- 4个独立通道:
- 输入捕获
- 输出比较
- PWM生成(边缘或中间对齐模式)
- 单脉冲模式输出
- 使用外部信号控制定时器和定时器互连的同步电路
- 如下事件发生时产生中断/DMA:
- 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
- 触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
- 输入捕获
- 输出比较
- 支持针对定位的增量(正交)编码器和霍尔传感器电路
- 触发输入作为外部时钟或者按周期的电流管理
下图是通用定时器框图
![image]()
![image]()
![image]()
![image]()
大家可以看到,时钟一般用的是来自RCC的TIMxCLK,那它是多少的速度呢?我们可以参考一下下面的时钟树。
![image]()
![image]()
![image]()
![image]()
![image]()
大家可以看到,在图的右边,有两组定时器,TIM2~7和TIM1和8分别挂接在APB1和APB2总线上,我们设置的SYSCLK通常为上限即72M但APB1的最大速度仅为36M,所以预分频器得为2分频,这样的话,TIMXCLK则为36M×2=72M,TIMxCLK同理为72M。
又到了我们的保留环节————程序编写
我们来想一下,我们需要使用TIM4,所以就要使能他的时钟,还要对TIM4的参数进行配置,然后应用于TIM4,既然使用了中断,NVIC的设置肯定是少不了的了,最后使能TIM4就好了。
点击查看代码
void TIM4_Init(u16 per,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);//使能TIM4时钟
TIM_TimeBaseInitStructure.TIM_Period=per; //自动装载值
TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //分频系数
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //设置向上计数模式
TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);
TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE); //开启定时器中断
TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;//定时器中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //子优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM4,ENABLE); //使能定时器
}
然后在主函数中这样初始化
TIM4_Init(3000,36000-1); //定时1500ms
3000是自动重装载值,36000是分频系数,但是为什么要填入35999呢?原来分配系数是1~65536,但在单片机里面是从0开始算的,所以我们填35999就相当于36000了。
下面是中断服务函数的代码了
点击查看代码
void TIM4_IRQHandler(void)
{
if(TIM_GetITStatus(TIM4,TIM_IT_Update))
//上面的就是为了判断是不是更新中断
{
LED1=1;
delay_ms(50);
LED1=0;
}
TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
}
TIM_IT_Update:更新中断,计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
TIM_IT_CC1~4:都是捕获/比较中断,即输入捕获,输出比较
TIM_IT_Trigger:触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)










浙公网安备 33010602011771号