• stm32寄存器版学习笔记04 定时计数器中断


      STM32共有8个定时计数器,其中TIME1和TIME8是高级定时器,TIME2~TIME5是通用定时器,TIME6和TIME7是基本定时器。以TIME3为例总结定时计数器的基本用法。

    1.TIM3的配置步骤

    ①TIM3时钟使能

      APB1外设复位寄存器 (RCC_APB1RSTR)  

    置1开启。清0关闭。

    第一位对TIM3的时钟使能

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

      APB2外设时钟使能寄存器(RCC_APB2ENR)

    ②设置TIM3_ARR和TIM3_PSC的值

    通过这两个寄存器来设置自动重装的值以及分频系数。

      自动重装载寄存器(TIMx_ARR)

      预分频器(TIMx_PSC)

    ③设置TIM3_DIER允许更新中断

      中断使能寄存器(TIMx_DIER)

    0:禁止更新中断。1:允许更新中断

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

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

     

    ④允许TIM3工作

      控制寄存器1(TIMx_CR1)

    CEN:使能计数器 位0  0:禁止计数器; 1:使能计数器。

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

        或   TIM3->CR1|=1<<0;

    ⑤TIM3中断分组设置

    直接调用MY_NVIC_Init()函数

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

    ⑥编写中断服务函数

      状态寄存器(TIMx_SR)

    Eg:  if(TIM3->SR&0X0001)//溢出中断

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

      Eg://定时器3中断服务程序
      void TIM3_IRQHandler(void) //TIM3_Int_Init(5000,7199);  //10Khz的计数频率,计数到5000为500ms
                                      //500ms中断一次
      {
        if(TIM3->SR&0X0001)  //溢出中断
        {
          //add your code
        }
        TIM3->SR&=~(1<<0);  //清除中断标志位
      }

    2.关于溢出事件的计算

      因为Stm32_Clock_Init函数里面已经初始化APB1的时钟为2分频,所以APB1的时钟是32MHz(系统时钟72MHz)。

      从STM32内部时钟树图可知:当APB1的时钟分频数为1时,TIM2~7的时钟为APB1的时钟;而如果APB1的时钟分频数不为1,那么TIM2~7的时钟频率是APB1时钟的两倍。因此TIM3的时钟为72MHz,再根据arr和psc即可计算中断时间

              Tout = ( (arr+1) * (psc+1) ) / Tclk

      其中,Tclk为TIM3的输入时钟频率(单位:MHz)。Tout为TIM3的溢出时间(单位:us)。

    Eg:void TIM3_Int_Init(u16 arr,u16 psc)----->TIM3_Int_Init(5000,7199);//10Khz的计数频率,计数到5000为500ms 

      Tout = (5000 * 7200)/72 = 500,000us = 500ms

    3.定时器中断的应用

     1 timer.c
     2 //定时器3中断服务程序     
     3 void TIM3_IRQHandler(void)      //TIM3_Int_Init(5000,7199);//10Khz的计数频率,计数到5000为500ms  
     4                                 //500ms中断一次
     5 {                                       
     6     if(TIM3->SR&0X0001)//溢出中断
     7     {
     8         LED1=!LED1;                                                                    
     9     }                   
    10     TIM3->SR&=~(1<<0);//清除中断标志位         
    11 }
    12 //通用定时器中断初始化
    13 //这里时钟选择为APB1的2倍,而APB1为36M
    14 //arr:自动重装值。
    15 //psc:时钟预分频数
    16 //这里使用的是定时器3!
    17 void TIM3_Int_Init(u16 arr,u16 psc)
    18 {
    19     RCC->APB1ENR|=1<<1;    //TIM3时钟使能    
    20      TIM3->ARR=arr;      //设定计数器自动重装值 
    21     TIM3->PSC=psc;      //预分频器设置
    22     TIM3->DIER|=1<<0;   //允许更新中断                
    23     TIM3->CR1|=0x01;    //使能定时器3
    24       MY_NVIC_Init(1,3,TIM3_IRQn,2);//抢占1,子优先级3,组2                                     
    25 }
     1 main.c
     2 int main(void)
     3 {            
     4     Stm32_Clock_Init(9); //系统时钟设置
     5     delay_init(72);         //延时初始化
     6     uart_init(72,9600);  //串口初始化 
     7     LED_Init();               //初始化与LED连接的硬件接口
     8     TIM3_Int_Init(5000,7199);//10Khz的计数频率,计数到5000为500ms  
     9        while(1)
    10     {
    11         LED0=!LED0;
    12         delay_ms(200);           
    13     }
    14 }
  • 相关阅读:
    Android NDK学习(1) 简介
    wmsys.wm_concat结果长度限制的问题
    onInterceptTouchEvent和onTouchEvent调用时序
    滑动到底部或顶部响应的ScrollView实现
    Android ViewPager使用详解
    android include标签的使用,在RelativeLayout中使用include标签需注意!!!!!
    Eclipse中如何在指定工程中搜索指定的字符串
    android:windowSoftInputMode属性详解
    cocos2d-x中关于touch事件的响应
    《从零开始学Swift》学习笔记(Day 6)——哎呀常量和变量都该什么时候用啊?
  • 原文地址:https://www.cnblogs.com/kuotian/p/5623148.html
Copyright © 2020-2023  润新知