STM32的定时中断,就是你定一个时间,STM32会每隔这个时间去打断主函数的运行,去干其他事情

 

1、定时器

需要实现定时中断,肯定是使用定时器啦

STM32F10x系列总共最多有8个定时器:

                         

esp32定时器延时 esp32 定时器中断_esp32定时器延时

          

esp32定时器延时 esp32 定时器中断_初始化_02

2、通用定时器:

平时使用的大多数为通用定时器:

STM32 的通用定时器是一个通过可编程预分频器(PSC)驱动的 16 位自动装载计数器(CNT)构成。STM32 的通用定时器可以被

用于:测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和 PWM)等。 使用定时器预分频器和 RCC 时钟控制器预分频

器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。STM32 的每个通用定时器都是完全独立的,没有互相共享的任何资源。

STM3 的通用 TIMx (TIM2、TIM3、TIM4 和 TIM5)定时器功能包括:

1)16 位向上、向下、向上/向下自动装载计数器(TIMx_CNT)。

2)16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数为 1~65535 之间的任意数值。

3)4 个独立通道(TIMx_CH1~4),这些通道可以用来作为:
      A.输入捕获
      B.输出比较
      C.PWM 生成(边缘或中间对齐模式)
      D.单脉冲模式输出

4)可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外一个定时器)的同步电路。

5)如下事件发生时产生中断/DMA:
       A.更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
      B.触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
      C.输入捕获
      D.输出比较
      E.支持针对定位的增量(正交)编码器和霍尔传感器电路
      F.触发输入作为外部时钟或者按周期的电流管理

3、计数器模式


通用定时器可以向上计数、向下计数、向上向下双向计数模式。

①向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件。

②向下计数模式:计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。

③中央对齐模式(向上/向下计数):计数器从0开始计数到自动装入的值-1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。

                                     

esp32定时器延时 esp32 定时器中断_esp32定时器延时_03

4、定时器中断实验相关寄存器

就讲几个主要的寄存器

1)控制寄存器 1(TIMx_CR1)

主要看位0吧,其他为比较少用到,位0是使能位

    

esp32定时器延时 esp32 定时器中断_优先级_04

                       

esp32定时器延时 esp32 定时器中断_寄存器_05

2)DMA/中断使能寄存器(TIMx_DIER)

主要关注第 0 位,该位是更新中断允许位,其他位,可以自己看一下

                 

esp32定时器延时 esp32 定时器中断_优先级_06


3)预分频寄存器(TIMx_PSC)

该寄存器用设置对时钟进行分频,然后提供给计数器,作为计数器的时钟

定时器的时钟来源有 4 个:
1)内部时钟(CK_INT)

2)外部时钟模式 1:外部输入脚(TIx)

3)外部时钟模式 2:外部触发输入(ETR)

4)内部触发输入(ITRx):使用 A 定时器作为 B 定时器的预分频器(A 为 B 提供时钟)。这些时钟,具体选择哪个可以通过TIMx_SMCR 寄存器的相关位来设置。这里的 CK_INT时钟是从 APB1 倍频的来的,除非 APB1 的时钟分频数设置为 1,否则通用定时器 TIMx 的时钟是 APB1 时钟的 2 倍,当 APB1 的时钟不分频的时候,通用定时器 TIMx 的时钟就等于 APB的时钟。这里还要注意的就是高级定时器的时钟不是来自 APB1,而是来自 APB2 的。

              

esp32定时器延时 esp32 定时器中断_初始化_07

4) TIMx_CNT 寄存器,

该寄存器是定时器的计数器,该寄存器存储了当前定时器的计数值。

           

esp32定时器延时 esp32 定时器中断_esp32定时器延时_08

5)自动重装载寄存器(TIMx_ARR),

该寄存器在物理上实际对应着 2 个寄存器。一个是程序员可以直接操作的,另外一个是程序员看不到的,这个看不到的寄存器在《STM32中文参考手册》里面被叫做影子寄存器。事实上真正起作用的是影子寄存器。根据 TIMx_CR1寄存器中 APRE 位的设置:APRE=0 时,预装载寄存器的内容可以随时传送到影子寄存器,此时 2 者是连通的;而 APRE=1 时,在每一次更新事件(UEV)时,才把预装在寄存器的内容传送到影子寄存器。

      

esp32定时器延时 esp32 定时器中断_优先级_09

6)状态寄存器(TIMx_SR)

该寄存器用来标记当前与定时器相关的各种事件/中断是否发生

        

esp32定时器延时 esp32 定时器中断_优先级_10

                           

esp32定时器延时 esp32 定时器中断_初始化_11

5、初始化步骤

示例使用的主要是定时器3的,其他一些定时器也差不多

1 )TIM3  时钟使能。

这里我们通过 APB1ENR 的第 1 位来设置 TIM3 的时钟,因为 Stm32_Clock_Init 函数里面把APB1的分频设置为2了,所以我们的TIM3时钟就是APB1时钟的2倍,等于系统时钟(72M)。

RCC->APB1ENR|=1<<1;  //TIM3 时钟使能

2 )设置 TIM3_ARR 和 和 TIM3_PSC  的值。

通过这两个寄存器,我们来设置自动重装的值,以及分频系数。这两个参数加上时钟频率
就决定了定时器的溢出时间。

TIM3->ARR=arr; //设定计数器自动重装值//刚好 1ms
TIM3->PSC=psc; //预分频器 7200,得到 10Khz 的计数时钟

3 )设置 TIM3_DIER  允许更新中断。

因为我们要使用 TIM3 的更新中断,所以设置 DIER 的 UIE 位为 1,使能更新中断。

TIM3->DIER|=1<<0; //允许更新中断

4 )允许 TIM3  工作。

光配置好定时器还不行,没有开启定时器,照样不能用。我们在配置完后要开启定时器,通过 TIM3_CR1 的 CEN 位来设置

TIM3->CR1|=0x01; //使能定时器 3

5 )TIM3  中断分组设置。

在定时器配置完了之后,因为要产生中断,必不可少的要设置 NVIC 相关寄存器,以使能TIM3 中断。

MY_NVIC_Init(1,3,TIM3_IRQn,2);//抢占 1,子优先级 3,组 2 

6 )编写中断服务函数。

在最后,还是要编写定时器中断服务函数,通过该函数来处理定时器产生的相关中断。在中断产生后,通过状态寄存器的值来判断此次产生的中断属于什么类型。然后执行相关的操作,我们这里使用的是更新(溢出)中断,所以在状态寄存器 SR 的最低位。在处理完中断之后应该向 TIM3_SR 的最低位写 0,来清除该中断标志

void TIM3_IRQHandler(void)
{
       if(TIM3->SR&0X0001) //溢出中断
      {
               //这里写想要中断实现的功能,例如:LED亮    LED = 1; 
      } 
       TIM3->SR&=~(1<<0); //清除中断标志位
}

附件为例程,包括寄存器版本和库函数版本