STM32 定时器中断

您所在的位置:网站首页 STM32中断编程初始化步骤 STM32 定时器中断

STM32 定时器中断

2024-07-08 19:44| 来源: 网络整理| 查看: 265

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

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

内部时钟(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闪烁,时间间隔就是定时器的溢出时间



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3