STM32
直播中

tulin

12年用户 1225经验值
私信 关注
[问答]

STM32F4定时器中断的作用是什么?

STM32F4定时器中断的作用是什么?

回帖(1)

王睦羽

2021-11-24 09:13:13
作用:
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();
    }
}
举报

更多回帖

发帖
×
20
完善资料,
赚取积分