定时器中断

今天看了看定时器中断,感觉和systick有一点像既然有了systick的经验,TIMx的中断应该能手到擒来吧。
下面是参考手册给出的TIMx简介
通用定时器是一个通过可编程预分频器驱动的16位自动装载计数器构成。 它适用于多种场合,包括

  • 测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和PWM)。
  • 使用定时器预分频器和RCC时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。

每个定时器都是完全独立的,没有互相共享任何资源。它们可以一起同步操作。
TIMx主要功能通用TIMx (TIM2、TIM3、TIM4和TIM5)定时器功能包括:

  1. 16位向上、向下、向上/向下自动装载计数器
  2. 16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65536之间的任意数值
  3. 4个独立通道:
    • 输入捕获
    • 输出比较
    • PWM生成(边缘或中间对齐模式)
    • 单脉冲模式输出
  4. 使用外部信号控制定时器和定时器互连的同步电路
  5. 如下事件发生时产生中断/DMA:
    • 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
    • 触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
    • 输入捕获
    • 输出比较
  6. 支持针对定位的增量(正交)编码器和霍尔传感器电路
  7. 触发输入作为外部时钟或者按周期的电流管理
    下图是通用定时器框图
    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:触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)

posted @ 2022-07-06 20:33  CottonTAT  阅读(432)  评论(0)    收藏  举报