设计分享 | STM32F103RCT6定时器定时中断原理

wx:嵌入式工程师成长日记

https://mp.weixin.qq.com/s?__biz=Mzg4Mzc3NDUxOQ==&mid=2247484146&idx=1&sn=8633770f809e999f05b8dc9a99cbef4c&chksm=cf4307aaf8348ebc677d7277d56ab1bae8b0d0f0ada1932af3877bc3b5e8a9fe6ead180f374a&token=1179446781&lang=zh_CN#rdicon-default.png?t=M85Bhttps://mp.weixin.qq.com/s?__biz=Mzg4Mzc3NDUxOQ==&mid=2247484146&idx=1&sn=8633770f809e999f05b8dc9a99cbef4c&chksm=cf4307aaf8348ebc677d7277d56ab1bae8b0d0f0ada1932af3877bc3b5e8a9fe6ead180f374a&token=1179446781&lang=zh_CN#rd

具体功能实现

当启动开发板时,OLED上的数字开始每隔1s自增一,实现定时器的功能

器件

STM32F103RCT6,OLED屏,四根杜邦线

前后展示图

前展示图

后展示图

知识介绍

ClearFlag()和ClearITPendingBit()的区别

ClearFlag():清除中断标志位

ClearITPendingBit():清除中断待处理位

标志位是事件发生与否的判断依据,用于支持函数的运行,如果事件发生,则该位至1,但是这不一定会产生中断

待处理位是控制中断发生的标志,如果该位置1(前提是相应标志位置1和中断已使能),则会产生中断,进入中断服务函数,而且在中断服务函数中必须手动将该位置0,否则程序会一直执行该中断。

TIM_Cmd

使能和失能外围设备(开启定时器时钟)

TIM_RepetitionCounter()

只有在高级定时器才能用到

基本定时器:TIM6,TIM7

通用定时器:TIM2~TIM5

高级定时器:TIM1,TIM8

其中TIM1和TIM8的时钟是由APB2输出产生,其他则是由APB1输出产生

NVIC(嵌套向量中断控制)

作用:用于中断分组,从而分配抢占优先级和响应优先级

编程步骤:

①选择优先级分组 NVIC_PriorityGroupConfig

②选择,配置,并使能中断 

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //选择定时器2中断 
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占优先级为2 
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //响应优先级为1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能定时器2中断; 
NVIC_Init(&NVIC_InitStructure); //初始化以上参数;

③写出相应的中断函数

void EXTI2_IRQHandler(void) 

中断函数都是固定的,需查阅文件

主函数代码(C语言)KEIL5实现

#include "stm32f10x.h"        // Device header

#include "Delay.h"

#include "OLED.h"

#include "Timer.h"



void timer_init()

{

TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;



TIM_InternalClockConfig(TIM2);



RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);

TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;

TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;

TIM_TimeBaseInitStruct.TIM_Period=10000-1;

TIM_TimeBaseInitStruct.TIM_Prescaler=7200-1;

TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;

TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);



TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);



NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;

NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;

NVIC_Init(&NVIC_InitStructure);

TIM_Cmd(TIM2,ENABLE);

}

u16 num;

int main()

{

OLED_Init();

timer_init();

OLED_ShowString(1,1,"num");

while(1)

{

OLED_ShowNum(1,5,num,5);

}

}

void TIM2_IRQHandler()

{

if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)

{

num++;

TIM_ClearITPendingBit(TIM2,TIM_IT_Update);

}

}

问题解答

Q

什么是抢占优先级和响应优先级?

A

STM32 的中断向量具有两个属性,一个为抢占属性,另一个为响应属性,其属性编号越小,表明它的优先级别越高。

①抢占优先级:打断其他中断的属性,因为这个属性会出现嵌套中断,在执行完中断服务函数B后再继续执行中断函数A,由NVIC_IRQChannelPreemptionPriority()配置

②响应优先级:在抢占属性相同时,当两个中断向量的抢占优先级相同时,如果两个中断同时到达,则先处理响应优先级高的中断。(优先级数字越小,优先级越高)由NVIC_IRQChannelSubPriority()配置

 wx:嵌入式工程师成长日记

https://mp.weixin.qq.com/s?__biz=Mzg4Mzc3NDUxOQ==&mid=2247484146&idx=1&sn=8633770f809e999f05b8dc9a99cbef4c&chksm=cf4307aaf8348ebc677d7277d56ab1bae8b0d0f0ada1932af3877bc3b5e8a9fe6ead180f374a&token=1179446781&lang=zh_CN#rdicon-default.png?t=M85Bhttps://mp.weixin.qq.com/s?__biz=Mzg4Mzc3NDUxOQ==&mid=2247484146&idx=1&sn=8633770f809e999f05b8dc9a99cbef4c&chksm=cf4307aaf8348ebc677d7277d56ab1bae8b0d0f0ada1932af3877bc3b5e8a9fe6ead180f374a&token=1179446781&lang=zh_CN#rd

STM32F103RCT6是一款基于ARM Cortex-M3内核的微控制器,它包含了一组功能强大的定时器,用于控制系统周期性的事件触发。其中,定时器5(TIM5)是一个16位自动装载计数器,提供丰富的功能,支持脉冲宽度调制(PWM)、捕获、比较等模式。 ### STM32F103RCT6 定时器5 (TIM5) 的定时中断 定时器5定时中断是指当TIM5的时间达到预设值时,系统会引发中断请求,处理器暂停当前任务,并进入中断服务程序处理该事件。以下是配置TIM5定时中断的基本步骤: #### 配置 TIM5 中断 1. **选择触发源**:确定定时中断是由外部输入还是内部时钟触发。 - 可通过寄存器`TIM5->CR1`设置触发源模式。例如,启用外部输入边沿检测可以使用 `TIM_CR1_CMS_0` 和 `TIM_CR1_CCxS_0` 来分别设置计数模式和通道模式。 2. **初始化定时器**:使用`HAL_TIM_Init()`函数初始化TIM5,指定频率、分频因子、复位模式等参数。 3. **中断使能**:在TIM5的中断向量表中配置中断请求。 - 对于TIM5,通常需要启用`TIM_IT_Update`中断,表示计数值更新的中断。这通常在`stm32f10xx_hal_tim.c`文件中完成。 4. **中断服务处理**:编写对应的中断服务函数,处理定时器中断的逻辑操作。这包括读取当前计数值、更新状态、控制外部设备或执行特定任务等。 #### 实现示例 假设需要配置TIM5在每秒生成一次中断,首先初始化TIM5并设置其时钟源和预分频系数,然后启动定时器并开启中断: ```c #include "stm32f10x.h" void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim) { // 初始化完成后回调 } void Init_Timer5() { TIM_HandleTypeDef htim; htim.Instance = TIM5; htim.Init.Prescaler = 7999; // 分频系数(系统时钟/8000) htim.Init.CounterMode = TIM_COUNTERMODE_UP; // 向上计数模式 htim.Init.Period = 999; // 计数值(一秒内的计数次数) htim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; // 无分频 htim.Init.RepetitionCounter = 0; // 不重复计数 htim.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; // 禁止预装载 if (HAL_TIM_Base_Init(&htim) != HAL_OK) { return; } // 设置中断优先级及使能 NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 高优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 高子优先级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; if (NVIC_Init(&NVIC_InitStructure) != HAL_OK) { return; } HAL_TIM_Base_Start_IT(&htim); // 开始计时并启用中断 // 初始化完毕后的回调 HAL_TIM_MspPostInit(&htim); } ``` 以上代码只是一个基本示例,实际应用中可能还需要考虑更复杂的中断管理以及错误检查机制。 ### 相关问题: 1. 如何配置STM32F103RCT6的TIM5以触发外部输入中断? 2. STM32F103RCT6定时器5中断处理函数如何设计以应对实时系统的需要? 3. 当遇到中断响应延迟时,如何优化STM32F103RCT6定时中断性能? --- 请注意,在实际工程中使用定时器时,务必注意硬件资源限制、电源管理和软件效率等方面的要求,确保系统的稳定性和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值