stm32使用通用定时器中断的一般流程

本文详细介绍了STM32定时器的配置过程,包括使能时钟、设定计数器值、预分频器值、中断使能、中断分组及优先级设置等关键步骤。同时,通过实例说明了如何计算ARR与PSC值以实现特定的中断间隔。

(注:文中的x为数字)

初始化

1.TIMx的外设时钟使能
RCC->APB1ENR |= 1 << n;

2.设定ARR寄存器(计时器自动重装值)
TIMx->ARR = arr;

3.设定预分频器的值
在设定预分频器的值之前,先理解这里的预分频器与时钟系统里的APB1外设的PPRE1不同(由于原子的SYSTEM中时钟初始化函数将PPRE1设为非1,所以外设定时器的时钟就应该加倍了),也就是说进入下面这张图的内部时钟(CK_INT)为72MHZ,而PSC预分频器改变的是时基单元的那个,看到了吗?
在这里插入图片描述

代码格式:
TIMx->PSC = psc;

4.允许更新中断
TIMx->DIER |= 1<< 0;

5.开定时器使能
TIMx->CR1 |= 1 << 0;

6.设置中断分组及优先级
在这里就用原子提供的MY_NVIC_Init();函数
(具体代码看《设置中断流程》)


(注:其实还应该有一个设置定时器是向哪个方向计数:但默认的是边沿对齐向上计数模式;如果要改变计数方向看下图进行相关寄存器(CR1)的修改就可以了)
在这里插入图片描述


写中断服务函数

(注:每次进入中断的最后要清除SR的0位
TIMx->SR &= ~(0x01 << 0))


如何计算装入ARR与PSC的值(在这里采用溯回法讲解)
PSC.:如果要将72MHZ分频7200,则为6199
ARR:这个寄存器中存放的是产生中断间隔的总计时点数,也就是说,当CNT寄存器中每次从0到arr将产生中断(默认向上计数模式),那么变化一次的时间就显得关键了。那么如何计算变化一次数的时间呢?这要配合PSC寄存器来说了。
我们知道,经过PSC分频的频率指的是变化一次所需时间周期的倒数。前面说过,经过原子的时钟初始化使得APB1定时器时钟为72MHZ,而PSC就是分频的72MHZ。举例来说,假如你想要一次产生0.5s的中断,那PSC就设置7200 - 1 = 6199 ARR设置5000 - 1 = 4999,前者设置分频为10kHZ,CNT改变一次0.0001s,后者设置计数总点为5000 中断时间为5000 * 0.0001 = 0.5s
(至于那个为什么-1 可以这样理解,每次溢出(在向上计数模式中),即归0,都要经过arr + 1个间隔,关于PSC,看一段话:
在这里插入图片描述
其实读者自行画一个图就好理解了,在这也就不赘述了)

<think>嗯,用户想了解如何在STM32F103上配置通用定时器中断,需要示例教程。好的,我得先回忆一下STM32通用定时器配置步骤。首先,STM32通用定时器有很多,比如TIM2到TIM5,它们都是16位或者32位的。配置中断的话,通常需要几个步骤:初始化定时器、设置预分频和重装载值、使能中断、编写中断服务函数,最后启动定时器。 用户提供的参考引用里提到,定时器中断和串口中断类似,需要判断中断来源和清除标志位。所以得确保在中断处理函数里检查中断类型并清除相应的标志,否则会不断进入中断,导致程序卡死。 接下来,我需要考虑用户可能的开发环境,比如使用标准库还是HAL库。这里假设用户使用标准库,因为HAL库虽然更现代,但标准库在STM32F1系列中仍然广泛使用。所以示例代码应该基于标准库的函数。 首先,配置时钟,使能TIM2的时钟,因为通用定时器通常挂载在APB1总线上。然后配置定时器的基本参数,比如预分频器(PSC)和自动重装载寄存器(ARR)。预分频器用来将系统时钟分频,得到定时器的计数频率。ARR决定定时器的溢出时间。 然后,配置中断,需要使能更新中断,并设置NVIC,也就是嵌套向量中断控制器,来管理中断优先级和使能中断。之后,编写中断服务函数,这里要注意函数名的正确性,比如TIM2_IRQHandler。在中断函数里,先检查中断标志,处理完后再清除标志。 最后,启动定时器,开始计数。用户可能需要具体的数值例子,比如如何计算定时时间。例如,系统时钟是72MHz,预分频7200-1,这样定时器时钟是72MHz /7200 = 10kHz,ARR设置为10000-1,这样溢出时间就是1秒。这样用户可以根据自己的需求调整数值。 还要注意,用户可能需要知道如何开启外设时钟,正确配置GPIO(如果用到PWM的话),但这里主要是定时器中断,可能不需要GPIO配置。不过有些情况下,用户可能会结合PWM使用,所以是否需要提及?不过问题明确是中断配置,所以可能不需要。 另外,用户可能容易忽略的地方是中断服务函数的名称是否正确,是否在启动文件中有定义,以及是否忘记使能NVIC中的中断通道。还有,预分频器和ARR的数值计算是否正确,比如是否需要减一,因为寄存器是从0开始计数的。 最后,生成相关问题,可能涉及如何计算定时时间、优化中断处理的方法、与其他中断的优先级冲突、使用其他定时器模式等。这样用户可以根据问题进一步深入学习。</think>### STM32F103通用定时器中断配置步骤 在STM32F103中配置通用定时器中断需以下步骤(以TIM2为例): #### 1. **使能时钟** 开启TIM2和对应GPIO(若需PWM输出)的时钟: ```c RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // TIM2挂载在APB1总线 ``` #### 2. **定时器基础配置** 设置预分频器(PSC)和自动重装载值(ARR),控制计数周期: ```c TIM_TimeBaseInitTypeDef TIM_InitStruct; TIM_InitStruct.TIM_Prescaler = 7200 - 1; // 72MHz/7200 = 10kHz TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_InitStruct.TIM_Period = 10000 - 1; // 10kHz/10000 = 1Hz(1中断一次) TIM_InitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInit(TIM2, &TIM_InitStruct); ``` #### 3. **中断配置** 使能更新中断并设置NVIC优先级: ```c TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); // 允许更新事件触发中断 NVIC_InitTypeDef NVIC_InitStruct; NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); ``` #### 4. **中断服务函数** 在`stm32f10x_it.c`中实现中断处理逻辑,**必须清除中断标志**: ```c void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { // 用户自定义操作(如翻转LED) TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 清除中断标志[^1] } } ``` #### 5. **启动定时器** ```c TIM_Cmd(TIM2, ENABLE); // 启动TIM2 ``` ### 关键点说明 - **预分频与周期计算** 公式:$$T_{中断} = \frac{(PSC + 1) \times (ARR + 1)}{f_{时钟}}$$ 例如:72MHz时钟,PSC=7199,ARR=9999时,中断周期为1秒。 - **中断标志处理** 未清除标志会导致重复进入中断,需在中断函数内调用`TIM_ClearITPendingBit`。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值