精华内容
下载资源
问答
  • STM32定时器中断

    2020-03-07 18:04:47
    STM32定时器中断 Time.h库 #ifndef __TIMER_H #define __TIMER_H #include "sys.h" void TIM3_Int_Init(u16 arr,u16 psc); //入口参数 #endif Time.c库 #include "timer.h" #include "led.h" //通用定时器3...

    STM32定时器中断

    Time.h库

    #ifndef __TIMER_H
    #define __TIMER_H
    #include "sys.h"
    void TIM3_Int_Init(u16 arr,u16 psc);  //入口参数
     
    #endif
    
    

    Time.c库

    #include "timer.h"
    #include "led.h"
    
    
    //通用定时器3中断初始化
    //这里时钟选择为APB1的2倍,而APB1为36M
    //arr:自动重装值。
    //psc:时钟预分频数
    //这里使用的是定时器3!
    void TIM3_Int_Init(u16 arr,u16 psc)
    {
    #include "stm32f10x.h"                  // Device header
        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:能定时器时钟。
       RCC_APB1PeriphClockCmd();
       RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
       
    2:初始化定时器,配置ARR,PSC。
          TIM_TimeBaseInit();
          
          TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
          
          //定时器TIM3初始化
    	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	
    	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
    	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim  分频系数为1  72KHZ/1
    	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
    	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
    
    3:开启定时器中断,配置NVIC。
          void TIM_ITConfig();
          NVIC_Init();
          NVIC_InitTypeDef NVIC_InitStructure;
          //中断优先级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_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断
    	
    4:使能定时器。
          TIM_Cmd();
          TIM_Cmd(TIM3, ENABLE);  //使能TIMx					
    
    5:编写中断服务函数。
          TIMx_IRQHandler();
          //定时器3中断服务程序
    void TIM3_IRQHandler(void)   //TIM3中断
    {
    	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
    		{
    		TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIM3更新中断标志 
    		LED1=!LED1;
    		}
    }
    
    

    主函数里

    #include "led.h"
    #include "delay.h"
    #include "key.h"
    #include "sys.h"
    #include "usart.h"
    #include "timer.h"
     
     int main(void)
     {		
     
    	delay_init();	    	 //延时函数初始化	  
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    	uart_init(115200);	 //串口初始化为115200
     	LED_Init();			     //LED端口初始化
    	TIM3_Int_Init(4999,7199);//10Khz的计数频率,计数到5000为500ms  
       	while(1)
    	{
    		LED0=!LED0;
    		delay_ms(200);		   
    	}	 
    
     
    }	 
    
    Tout(溢出时间)=(ARR+1)(PSC+1)/Tclk
    Tout(溢出时间)=5000*7200/72000,000=0.5毫秒
    
    展开全文
  • stm32定时器中断

    2015-08-19 09:13:12
    stm32f407的定时器中断实验,测试通过
  • STM32 定时器中断定时器
  • stm32 定时器中断算法

    2018-09-06 01:16:13
    stm32 定时器中断算法,s曲线七段法,可以根据自己应用实例进行更改
  • STM32 定时器中断

    2020-12-08 19:20:28
    通用定时器工作过程:

    通用定时器工作过程:
    在这里插入图片描述
    时钟选择:

    计数器时钟可以由下列时钟源提供:

    • 内部时钟(CK_INT)
    • 外部时钟模式1:外部输入脚(TIx)
    • 外部时钟模式2:外部触发输入(ETR)
    • 内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器Timer1而作为另一个定时器Timer2的预分频器。

    内部时钟选择
    在这里插入图片描述
    在这里插入图片描述
    时钟计算方法:
    在这里插入图片描述默认调用SystemInit函数情况下:
    SYSCLK=72M
    AHB时钟=72M
    APB1时钟=36M
    所以APB1的分频系数=AHB/APB1时钟=2
    所以,通用定时器时钟CK_INT=2*36M=72M

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

    • 向下计数模式(时钟分频因子=1(意思就是:CK_PSC=CK_CNT))

    在这里插入图片描述在这里插入图片描述

    • 向上计数模式(时钟分频因子=1)
      在这里插入图片描述
      在这里插入图片描述

    • 中央对齐计数模式(时钟分频因子=1 ARR=6)
      在这里插入图片描述
      在这里插入图片描述
      定时器中断实验相关寄存器:

    • 计数器当前值寄存器CNT
      在这里插入图片描述

    • 预分频寄存器TIMx_PSC

    在这里插入图片描述

    • 自动重装载寄存器(TIMx_ARR)
      在这里插入图片描述
    • 控制寄存器1(TIMx_CR1)
      在这里插入图片描述
    • DMA中断使能寄存器(TIMx_DIER)
      在这里插入图片描述

    常用库函数

    定时器参数初始化:

     void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
    ypedef struct
    {
      uint16_t TIM_Prescaler;//预分频系数的设置      
      uint16_t TIM_CounterMode;//计数模式   
      uint16_t TIM_Period;//自动装载值
      uint16_t TIM_ClockDivision;//输入捕获会用到 
      uint8_t TIM_RepetitionCounter;//高级定时器会用到
    } TIM_TimeBaseInitTypeDef; 
    TIM_TimeBaseStructure.TIM_Period = 4999;
    TIM_TimeBaseStructure.TIM_Prescaler =7199; 
    TIM_TimeBaseStructure.TIM_ClockDivision =TIM_CKD_DIV1; 
    TIM_TimeBaseStructure.TIM_CounterMode =TIM_CounterMode_Up; 
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); 
    

    定时器使能函数:

    void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)
    

    定时器中断使能函数:

    void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
    

    状态标志位获取和清除:

    FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
    void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
    ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
    void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);
    

    定时器中断实现步骤:

    • 能定时器时钟。
     RCC_APB1PeriphClockCmd();
    
    • 初始化定时器,配置ARR,PSC。
     TIM_TimeBaseInit();
    
    • 开启定时器中断,配置NVIC。
    void TIM_ITConfig();
          NVIC_Init();
    
    • 使能定时器。
    TIM_Cmd();
    
    • 编写中断服务函数。
    TIMx_IRQHandler();//中断函数要判断中断标志位,和手动清除中断标志位
    ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
    void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);
    

    Tout(溢出时间)=(ARR+1)(PSC+1)/Tclk

    其中arr为你重装的值,

    psc是预分频计时器的值(预分频系数),

    Tclk是时钟频率

    Tclk/(psc+1)是定时器的时钟

    (psc+1))/Tclk*1是计算的计数器 减少/增加 一个数所用的时间;

    那么(psc+1))/Tclk*(arr+1)就是一次定时器的时间:

    然后继续重装arr再次计数,计时:

    就构成一个循环;

    • TIM2-TIM5的时钟不是直接来自于APB1,而是来自于输入为APB1的一个倍频器。这个倍频器的作用是:当APB1的预分频系数为1时,这个倍频器不起作用,当APB1的预分频系数为其他数值时(即预分频系数为2、4、8或16),这个倍频器起作用,定时器的时钟频率等于APB1的频率的2倍。
    • 分频系数就是对定时器时钟进行多少分频之后在使用,最好设置为定时器时钟的倍数,方便运算;重新装载值是计算这么多值,时间到了之后重新开始计算的值,每一次计数的时间为分频之后时钟的到时;

    假设定时器时钟为72M,分频系数设置为7200-1,那现在定时器的时钟为10kHz,每计一个数花费1/(10000)秒,重装值设置为5000-1,那一次溢出的时间为500ms。
    分频值是是指你将系统时钟的频率减小,假设时钟频率是 72Mhz,然后分频值是 7199,现在你的定时器值就是 10kHz,表示每计一个数,然后过了 1/(10^4)秒,然后你的重装值就是你的时间了,如果值是 9999,就表示定时时间为 1s。

    定时器配置代码:

    void TIM4_Init(u16 ar,u16 rs)
    {
    	TIM_TimeBaseInitTypeDef TIM_InitStrue;
    	NVIC_InitTypeDef NVIC_InitStrue;
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);//使能定时器时钟
    	
    	TIM_InitStrue.TIM_Period=ar;//自动装载值
    	TIM_InitStrue.TIM_Prescaler=rs;//预分频系数的设置
    	TIM_InitStrue.TIM_CounterMode=TIM_CounterMode_Up;
    	TIM_InitStrue.TIM_ClockDivision=TIM_CKD_DIV1;//设置时钟分割:TDTS = Tck_tim
    	TIM_TimeBaseInit(TIM4,&TIM_InitStrue);//初始化定时器,对定时器进行配置
    	
    	TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);//开启定时器中断
    	
    	NVIC_InitStrue.NVIC_IRQChannel=TIM4_IRQn;
    	NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;
    	NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=2;
    	NVIC_InitStrue.NVIC_IRQChannelSubPriority=2;
    	NVIC_Init(&NVIC_InitStrue);//初始化中断,设置中断的优先级
    
    	TIM_Cmd(TIM4,ENABLE);//使能定时器
    }
    
    void TIM4_IRQHandler(void)
    {
    	if(TIM_GetITStatus(TIM4,TIM_IT_Update)!=RESET)
    	{
    		LED1=!LED1;
    		TIM_ClearITPendingBit(TIM4,TIM_IT_Update);//清除中断标志位
    	}
    }	
    

    实验现象:LED0闪烁,时间间隔就是定时器的溢出时间

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,652
精华内容 1,060
关键字:

stm32定时器中断