STM32F4定时器中断理解


目录

 

作用:

基本知识:

简介:

  一.高级控制定时器:

  二.通用定时器:

  三.基本定时器:

工作原理概括

程序编写


作用:

1.使用定时器可以替代延延时函数,延时函数占用CPU。

2.定时器计算固定脉冲,时间可准确计算:

公式:
  Ft=168Mhz/4*时钟分频
  Tout(us)=((arr+1)*(psc+1))/Ft(Mhz)
  arr:自动重装载值
  psc:定时器分频 (分频系数) //-1为参考手册要求
  Ft:定时器时钟频率 Mhz
例:
  定时器时钟84Mhz,8400分频,500重装值
  Tout=(8400*500)/84M=0.05us=500ms 500ms定时器溢出一次
注意:
  理想情况下,通过设定合适的psc将定时器周期设置为1s,但是很可惜,定时器只有16位的预分频寄存器,最大2^16-1,而这里我们的STM32F4定时器频率84Mhz,理想设置的psc应该为84000,但是达不到,
  可以设置为8400,这样一个加载频率就是10Khz,一个加载周期0.1s.我们在此基础上,可以更改arr,让总体的定时器周期增大.
  

3.使用定时器中断利于程序的模块化设计,使能或失能即可对模块开关进行掌控。

 

基本知识:

定时器种类:

1.高级控制定时器:TIM1,TIM8

2.通用定时器:TIM2-TIM5,TIM9-TIM14

3.基本定时器:TIM6,TIM7

 

简介:

  一.高级控制定时器:

    1.16位递增、递减、递增/递减自动重载计数器。

    2.16 位可编程预分频器,用于对计数器时钟频率进行分频(即运行时修改),分频系数 介于 1 到 65536 之间。

    3.多达 4 个独立通道,可用于:输入捕获,输出比较,PWM 生成(边沿和中心对齐模式),单脉冲模式输出

    4. 发生如下事件时生成中断/DMA 请求:

      ①更新:计数器上溢/下溢、计数器初始化(通过软件或内部/外部触发)

      ②触发事件:计数器启动、停止、初始化或通过内部/外部触发计数

      ③输入捕获

      ④输出比较

      ⑤断路输入

  二.通用定时器:

      ●TIM2-TIM5

      1.(TIM3,TIM4)16位或者(TIM2,TIM5)32位递增、递减和递增/递减自动重载计数器。

      2.16 位可编程预分频器,用于对计数器时钟频率进行分频(即运行时修改),分频系数介 于 1 到 65536 之间。

      3.多达 4 个独立通道,可用于:输入捕获,输出比较,PWM 生成(边沿和中心对齐模式),单脉冲模式输出

      4.发生如下事件时生成中断/DMA 请求:

        ①更新:计数器上溢/下溢、计数器初始化(通过软件或内部/外部触发)

        ②触发事件:计数器启动、停止、初始化或通过内部/外部触发计数

        ③输入捕获

        ④输出比较

      ●TIM9-TIM14

      1.16 位自动重载递增计数器(属于中等容量器件)。

      2.16 位可编程预分频器,用于对计数器时钟频率进行分频(即运行时修改),分频系数 介于 1 和 65536 之间。

      3.多达 2个独立通道,可用于:输入捕获,输出比较,PWM 生成(边沿和中心对齐模式),单脉冲模式输出

      4.发生如下事件时生成中断/DMA 请求:

        ①更新:计数器上溢/下溢、计数器初始化(通过软件或内部/外部触发)

        ②触发事件:计数器启动、停止、初始化或通过内部/外部触发计数

        ③输入捕获

        ④输出比较

  三.基本定时器:

     1.16 位自动重载递增计数器 

     2.16 位可编程预分频器,用于对计数器时钟频率进行分频(即运行时修改),分频系数 介于 1 和 65536 之间 

     3.用于触发 DAC 的同步电路 

     4.发生如下更新事件时会生成中断/DMA 请求:计数器上溢

工作原理概括

先介绍下几个寄存器:

  1.TIMX_CNT:当前定时器计数值

  2.TIMX_ARR(预加载寄存器):存放预设定的自动重载值,而非定时器内的溢出值

  3.影子寄存器(自动重加载寄存器):存放当前定时器溢出值

 

  我们注意到,在时间计算公式上,arr的值被减了1,这是因为我们定义的自动重载值会放入自动重载寄存器,当定时器使能时,自动重载寄存器会将值给影子寄存器,而CNT从0开始计数,所以设定的值需要减一

  定时器使能,自动重载寄存器会将值给影子寄存器,CNT开始计数,达到溢出值后,定时器周期结束,产生了一个更新中断,但是此时我们在中断服务程序中修改预加载寄存器(TIMX_ARR),但是并没有直接写入到自动重装载寄存器,而是要等到下一个定时器周期结束,在更新中断刚产生,前于中断服务程序时,将预加载寄存器的值赋给自动重加载计时器。

 

   

程序编写

以TIM3为例,利用定时器的计数器上溢中断为例,编写简单定时器中断程序利用draw()函数完成屏幕刷新。

首先完成定时器中断的初始化


void TIM3_Int_Init(u16 arr,u16 psc)   //通用定时器3初始化
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;  
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);   //使能计时器的APB1时钟

    TIM_TimeBaseInitStructure.TIM_Period = arr; //自动重装载值
	
    TIM_TimeBaseInitStructure.TIM_Prescaler=psc;   //定时器分频
    TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //上溢
    TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;

    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);  //初始化TIM3

    TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);        //使用更新中断
    TIM_Cmd(TIM3,ENABLE);                           //使能定时器

    NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;   //定时器三中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; //中断抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03;    //子优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

再开始编写定时器中断服务函数

void TIM3_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出,中断
    {
        draw();	   //屏幕刷新
    }
    TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //重置计数器
}

在main函数中,就可以利用全局变量或者指针对各种数据更改,从而通过定时器中断将交互显示在屏幕上

int main(void)
{
    delay_init(168);	    	
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	
    uart_init(115200);	 	
    LED_Init();			    
    LCD_Init();
    key_Configuration();
    TIM3_Int_Init(500 - 1, 8400 - 1);
    draw();	
    POINT_COLOR=RED;
    delay_ms(100);
    while(1)
    {
        KEYCODE=KEY_Scanf();
        lock();
    }
}

整体代码和驱动放在github上:https://github.com/wu58430/STM32F4-LOCK

更多原理细节后续补充

 

 

你可能感兴趣的:(STM32F4)