STM32通用定时器中断详解——想要分享的小白(以c8t6定时器为例)

本次博客以正点原子战舰资料以及STM32中文参考资料为主要参考。
本次博客主要讲解通用定时器中断,先讲解一下相关概念,然后在进行代码的实现。

**

通用定时器工作过程:

**(在定时器中断中,我们只是用到了定时器的时基单元)
STM32通用定时器中断详解——想要分享的小白(以c8t6定时器为例)_第1张图片
**

时钟源

**
在介绍时基单元之前,我们还需要了解时钟源。从通用定时器的工作过程图我们可以看到,定时器的时钟来源有很多。而我们常用的便是来自RCC的TIMxCLK。
通用定时器是挂载在APB1总线上的,APB1的时钟最高为36MHZ。
STM32通用定时器中断详解——想要分享的小白(以c8t6定时器为例)_第2张图片
这里的 CK_INT时钟是从 APB1 倍频的来的,除非 APB1 的时钟分频数设置为 1,否则通用定时器 TIMx 的时钟是 APB1时钟的2倍。
STM32通用定时器中断详解——想要分享的小白(以c8t6定时器为例)_第3张图片
STM32通用定时器中断详解——想要分享的小白(以c8t6定时器为例)_第4张图片
由STM32时钟系统框图以及默认调用SystemInit函数情况下,我们可以得出:CK_INT时钟为72MHz。即通用定时器的时钟频率是 72MHz。
**

时基单元

**

知道了时钟源后我们在来看时基单元。(大家在看下面概念的时候结合上面的图会更好的理解。)
时基单元包含:
● 预分频器寄存器 (TIMx_PSC)
● 计数器寄存器(TIMx_CNT)
● 自动装载寄存器 (TIMx_ARR)

1.TIMx_PSC预分频器可以将计数器的时钟频率按1到65536之间的任意值分频。
2.计数器由预分频器的时钟输出CK_CNT驱动 。
3.自动装载寄存器是预先装载的, 当计数器达到溢出条件(向下计数时的下溢条件) 产生更新事件。Arr的重装周期是1~65535。
**

计数器模式

**
计数器模式有三种,分别是:向上计数,向下计数,向上向下计数
STM32通用定时器中断详解——想要分享的小白(以c8t6定时器为例)_第5张图片
**

定时器中断时间计算

**

最后再来介绍进入定时器中断的时间,它的计算公式为:
STM32通用定时器中断详解——想要分享的小白(以c8t6定时器为例)_第6张图片
附上小白个人理解:
STM32通用定时器中断详解——想要分享的小白(以c8t6定时器为例)_第7张图片
以上便是关于定时器中断的相关理论知识,接下来通过库函数来配置代码。

**

代码实现

**

void TIM3_Int_Init(u16 arr,u16 psc)
{
     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
     NVIC_InitTypeDef NVIC_InitStructure;
     
     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
     //定时器TIM3初始化
     TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 
     TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
     TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
     
     TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断
     //中断优先级NVIC设置
     NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
     NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器
     
     TIM_Cmd(TIM3, ENABLE);  //使能TIMx      
 }
 //定时器3中断服务程序
void TIM3_IRQHandler(void)   //TIM3中断
{
     if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
    {
          TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx更新中断标志 
          LED1=!LED1;
    }
}

1) TIM3 时钟使能。 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
配置 STM32 外设的时候,任何时候都要先使能该外设的时钟。
2) 初始化定时器参数,设置自动重装值, 分频系数,计数方式等。
这里主要说一下TIM_ClockDivision与TIM_Prescaler这两个参数。 STM32通用定时器中断详解——想要分享的小白(以c8t6定时器为例)_第8张图片在本实验中,我们并没有用到这个参数。所以我们通常把他设置为TIM_CKD_DIV1

3) 设置 TIM3_DIER 允许更新中断。
如果不设置的话,无法进入进入定时器中断
4) TIM3 中断优先级设置。
关于中断优先级的详细讲解,小白在外部中断讲过,附上链接,有兴趣可以去看一下。
https://blog.csdn.net/weixin_44221205/article/details/107516171
5) 允许 TIM3 工作,也就是使能 TIM3。
定时器的配置完成后,必须使能定时器,否则定时器不运行。
6) 编写中断服务函数。
需要注意的是,定时器中断函数要与定时器名字对应。比如上面定时器3的中断函数TIM3_IRQHandler,小白没有在函数中找到,如果有知道大佬,帮忙评论一波,学习一下。

这次的实验现象就不演示了,它就是通过定时器来使灯进行亮灭操作。

需要源码的朋友,评论留下邮箱,我发给你

你可能感兴趣的:(stm32)