wordpress主题下载zip,郑州seo课程,重庆市建设工程信息网招标文件,电商培训STM32 学习9 中断、外部中断及定时器中断 一、STM32中断介绍一、STM32中断介绍1. 什么是中断#xff1f;2. 中断在嵌入式系统中的作用和重要性3. STM32中断的概述 4. 中断的优先级4.1 中断优先级级别4.2 中断优先级分类#xff08;1#xff09;硬件优先级#xff08;2… STM32 学习9 中断、外部中断及定时器中断 一、STM32中断介绍一、STM32中断介绍1. 什么是中断2. 中断在嵌入式系统中的作用和重要性3. STM32中断的概述 4. 中断的优先级4.1 中断优先级级别4.2 中断优先级分类1硬件优先级2响应速度优先级3重要性优先级4任务优先级 4.3 中断优先级设置4.4 中断优先级规则 二、STM32中断编程1. 使用能外设某个中断1使能中断2配置中断触发条件 2. 设置中断优先级分组3. 编写中断服务函数 三、外部中断1. 概念2. EXTI3. EXTI 框图4. EXTI中断/事件线路5. 外部中断使用步骤6. 示例1exti_utils.h2exti_utils.c 六、定时器中断1. 简介2. 通用定时器简介1时基单元2计数器模式3时钟选择4输入通道5捕获通道6定时器级联7定时器中断 3. 定时时间计算公式4. 配置步骤1选择定时器模块2 初始化时钟3初始化定时器参数4设置定时器中断类型并使能5使能6配置中断优先级7中断服务函数 5. 示例1timx_utils.h2timx_utils.c3main.c 七、中断嵌套1. 概念2. 中断的实现方式 一、STM32中断介绍
一、STM32中断介绍
1. 什么是中断
中断是一种计算机编程中的技术用于在程序执行期间暂停当前任务转而执行预定义的中断服务程序ISR处理特定的事件或信号。
中断机制允许系统对实时事件做出及时响应而不必用循环去等待特定事件的发生。
2. 中断在嵌入式系统中的作用和重要性
在嵌入式系统中特别是在实时系统中对一些事件的即时响应至关重要。例如传感器数据的读取、定时器溢出、外部输入信号等都是需要及时处理的事件。
使用中断可以确保系统能够在这些事件发生时立即作出响应而不会因为等待而造成延迟或丢失数据。
3. STM32中断的概述
STM32系列微控制器提供了丰富的中断支持包括但不限于外部中断、定时器中断、串口中断和DMA中断等。 STM32F10x芯片有84个中断通道包括16个内核中断和68个可屏蔽中断在《STM32F10x中文参考手册》第65页有向量表进行了详细介绍摘录如下
4. 中断的优先级
在STM32系列微控制器中中断优先级决定了当多个中断同时发生时哪一个中断将被优先处理。
4.1 中断优先级级别
中断优先级通常是一个整数STM32F103使用中断优先级控制字节的高4位0为最高优先级15为最低优先级。 STM32系列微控制器通常将中断分为多个组每个组有自己的优先级范围。例如对于外部中断可以有4个组每个组可以有16个优先级。
4.2 中断优先级分类
以下是几种常见的中断优先级分类方式
1硬件优先级
硬件优先级是指微控制器硬件提供的中断优先级机制。在STM32系列微控制器中中断的硬件优先级通常是一个数字数字越小优先级越高。例如优先级0是最高优先级15是最低优先级。开发者可以根据需要为每个中断设置不同的硬件优先级。
2响应速度优先级
响应速度优先级是根据中断需要被多快地响应来确定的。一些紧急事件可能需要立即得到处理因此这些中断会被分配更高的优先级以确保系统能够及时响应。例如定时器溢出中断可能比普通外部中断更加紧急因此可以为定时器中断分配更高的优先级。
3重要性优先级
重要性优先级是根据中断对系统功能的重要性来确定的。一些关键的系统功能可能需要被优先处理以确保系统的正常运行。例如系统故障中断可能比其他一般中断更加重要因此可以为系统故障中断分配更高的优先级。
4任务优先级
任务优先级是根据中断所执行的任务的重要性来确定的。系统中可能存在多个任务这些任务有不同的优先级。中断的优先级可以根据所执行的任务的重要性来确定以确保系统能够优先处理重要任务。
4.3 中断优先级设置
在STM32中中断优先级的设置是通过NVICNested Vectored Interrupt Controller嵌套向量中断控制器进行的。
NVIC属于M3内核的一个外设控制着芯片的中断功能。ARM给NVIC预留的功能比较多而M3内核进行了裁剪。
中断控制器相关的寄存器在固件库的core_cm3.h 文件NVIC结构体里定义常见的寄存器有
NVIC_ISERx 使用中断寄存器NVIC_ICERx 禁用中断NVIC_ISPRx 设置中断挂起NVIC_ICPRx 清除中断的挂起状态NVIC_IPRx 设置中断优先级NVIC_STIR 用于软件触发中断NVIC_ICSR 提供了一些中断相关的状态和控制位
我们可以通过NVIC接口函数来配置中断的优先级常用的函数包括NVIC_SetPriority()和NVIC_SetPriorityGrouping()等。通过这些函数可以将不同中断设置为不同的优先级并根据实际需求进行灵活配置。
4.4 中断优先级规则
在设置中断优先级时需要遵循一定的规则以确保系统的正确性和稳定性
优先级较低的中断可以被较高优先级的中断抢占。换句话说当一个中断正在执行时如果发生了优先级更高的中断系统会立即转去执行更高优先级的中断服务程序。优先级相同的中断先被触发的中断会先被处理。即如果多个中断同时发生并且优先级相同则先触发的中断会先得到处理。
二、STM32中断编程
1. 使用能外设某个中断
1使能中断
2配置中断触发条件
2. 设置中断优先级分组
初始化 NVIC_InitTypeDef 结构体
typedef struct
{uint8_t NVIC_IRQChannel; // 中断源设置uint8_t NVIC_IRQChannelPreemptionPriority; // 抢占优先级uint8_t NVIC_IRQChannelSubPriority; // 响应优先级FunctionalState NVIC_IRQChannelCmd; // 中断使能或失能
}NVIC_IRQChannel中断源可以在 stm32f10x.h 头文件中查到
3. 编写中断服务函数
void EXTI0_IRQHandler(void)
{// 处理外部中断0发生时的事件// 例如读取外部输入引脚状态、清除中断标志等// 清除中断挂起标志位EXTI_ClearITPendingBit(EXTI_Line0);
}
中断服务的函数名称在启动文件中定义建议不要修改
三、外部中断
1. 概念
外部中断是STM32系列微控制器中的一种中断类型它允许外部事件如外部输入引脚状态的变化触发中断从而使系统能够实时响应外部的输入信号。外部中断常用于处理外部设备的输入如按钮、传感器等。
2. EXTI
外部中断线路管理器External Interrupt/Event ControllerEXTI是STM32系列微控制器中的一个重要外设用于管理外部中断和事件的触发和处理。
STM32F10x EXTI包含多达19个用于产生事件/中断请求的边沿检测器。
EXTI允许外部事件例如GPIO引脚状态的变化触发中断可以选择类型中断或事件和相应的触发事件上升沿触发、下降沿触发或边沿触发从而实现对外部输入信号的实时响应。还可以独立地屏蔽EXTI中断。
下面是部分EXTI中断向量表 除了EXTI 另外 RTCAlarm、USB唤醒、PVD电源检测中断、ETH_WKUP 等外部中断。
3. EXTI 框图 4. EXTI中断/事件线路
EXTI线路说明EXTI 线 0~15对应外部IO 口的输入中断EXTI 线 16连接PVD输出EXTI 线17连接到RTC闹钟事件EXTI 线 18连接到USB唤醒事件EXTI 线19连接到以太网唤醒事件联网型芯片
5. 外部中断使用步骤
使能外部中断通过配置外部中断线路管理器EXTI和GPIO外设使能外部中断功能 // 使能外部中断线0NVIC_InitTypeDef NVIC_InitStruct;NVIC_InitStruct.NVIC_IRQChannel EXTI0_IRQn; // 外部中断0NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority 0x01; // 抢占优先级为1NVIC_InitStruct.NVIC_IRQChannelSubPriority 0x01; // 响应优先级为1NVIC_InitStruct.NVIC_IRQChannelCmd ENABLE;NVIC_Init(NVIC_InitStruct);开启AFIO 时钟设置IO口与中断线映射关系配置中断分组使能中断
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 选择优先级分组方式这里选择分组2
初始化EXTi选择触发方式 初始化使用 EXTI_InitStruct 函数 // 初始化外部中断线路管理器EXTIEXTI_InitTypeDef EXTI_InitStruct;EXTI_InitStruct.EXTI_Line EXTI_Line0; // 使用外部中断线0EXTI_InitStruct.EXTI_Mode EXTI_Mode_Interrupt; // 设置为中断模式EXTI_InitStruct.EXTI_Trigger EXTI_Trigger_Rising; // 上升沿触发EXTI_InitStruct.EXTI_LineCmd ENABLE; // 使能外部中断线0EXTI_Init(EXTI_InitStruct);编写EXTI中断服务函数
EXTI0_IRQHandlerEXTI1_IRQHandlerEXTI2_IRQHandlerEXTI3_IRQHandlerEXTI4_IRQHandlerEXTI9_5_IRQHandlerEXTI5_10_IRQHandler
6. 示例
本实例使用的开发板 GPIO 按键电路 对于开发板的K1、K2、K3 使用下降沿触发 KEY_UP 使用上升沿触发。对应的引脚
KEY_UPGPIOA GPIO_Pin0 引脚KEY_LEFTGPIOE GPIO_Pin2 引脚KEY_RIGHTGPIOE_GPIO_Pin4 引脚KEY_DOWNGPIOE_GPIO_Pin3 引脚
1exti_utils.h
#ifndef __exti_utils_h__
#define __exti_utils_h__#include stm32f10x.h
void custom_exti_init(void);
#endif
2exti_utils.c
#include exti_utils.h
#include stdio.h
#include sys_tick_utils.h
#include led_utils.h
#include key_utils.h/*** brief 外部中断初始化
*/
void custom_exti_init(void) {// 开启AFIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);// GPIO 引脚映射到 EXTI 中断线GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);// GPIOE 映射到 EXTI 中断线GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource2);GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource3);GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource4);// 配置外部中断0的优先级NVIC_InitTypeDef NVIC_InitStruct;NVIC_InitStruct.NVIC_IRQChannel EXTI0_IRQn;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority 0x02; // 抢占优先级为1NVIC_InitStruct.NVIC_IRQChannelSubPriority 0x03; // 响应优先级为3NVIC_InitStruct.NVIC_IRQChannelCmd ENABLE;NVIC_Init(NVIC_InitStruct);NVIC_InitStruct.NVIC_IRQChannel EXTI2_IRQn;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority 0x02; // 抢占优先级为1NVIC_InitStruct.NVIC_IRQChannelSubPriority 0x02; // 响应优先级为2NVIC_InitStruct.NVIC_IRQChannelCmd ENABLE;NVIC_Init(NVIC_InitStruct);NVIC_InitStruct.NVIC_IRQChannel EXTI3_IRQn;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority 0x02; // 抢占优先级为1NVIC_InitStruct.NVIC_IRQChannelSubPriority 0x1; // 响应优先级为1NVIC_InitStruct.NVIC_IRQChannelCmd ENABLE;NVIC_Init(NVIC_InitStruct);NVIC_InitStruct.NVIC_IRQChannel EXTI4_IRQn;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority 0x02; // 抢占优先级为1NVIC_InitStruct.NVIC_IRQChannelSubPriority 0x0; // 响应优先级为0NVIC_InitStruct.NVIC_IRQChannelCmd ENABLE;NVIC_Init(NVIC_InitStruct);// 初始化外部中断线路管理器EXTIEXTI_InitTypeDef EXTI_InitStruct;EXTI_InitStruct.EXTI_Line EXTI_Line0; // 外部中断线0EXTI_InitStruct.EXTI_Mode EXTI_Mode_Interrupt; // 中断模式EXTI_InitStruct.EXTI_Trigger EXTI_Trigger_Rising; // 上升沿触发EXTI_InitStruct.EXTI_LineCmd ENABLE; // 使能外部中断线0EXTI_Init(EXTI_InitStruct);EXTI_InitStruct.EXTI_Line EXTI_Line2; // 外部中断线2EXTI_InitStruct.EXTI_Mode EXTI_Mode_Interrupt; // 中断模式EXTI_InitStruct.EXTI_Trigger EXTI_Trigger_Falling; // 下降沿触发EXTI_InitStruct.EXTI_LineCmd ENABLE; // 使能外部中断线0EXTI_Init(EXTI_InitStruct);EXTI_InitStruct.EXTI_Line EXTI_Line3; // 外部中断线2EXTI_InitStruct.EXTI_Mode EXTI_Mode_Interrupt; // 中断模式EXTI_InitStruct.EXTI_Trigger EXTI_Trigger_Falling; // 下降沿触发EXTI_InitStruct.EXTI_LineCmd ENABLE; // 使能外部中断线0EXTI_Init(EXTI_InitStruct);EXTI_InitStruct.EXTI_Line EXTI_Line4; // 外部中断线2EXTI_InitStruct.EXTI_Mode EXTI_Mode_Interrupt; // 中断模式EXTI_InitStruct.EXTI_Trigger EXTI_Trigger_Falling; // 下降沿触发EXTI_InitStruct.EXTI_LineCmd ENABLE; // 使能外部中断线0EXTI_Init(EXTI_InitStruct);
}
/*** brief 外部中断0中断服务函数
*/
void EXTI0_IRQHandler(void) {if (EXTI_GetITStatus(EXTI_Line0) ! RESET) {delay_ms(10);if (key_up_value 1) {led_lightn(0);EXTI_ClearITPendingBit(EXTI_Line0); // 清除中断标志位return;}}
}
/*** brief 外部中断2中断服务函数
*/
void EXTI2_IRQHandler(void) {if (EXTI_GetITStatus(EXTI_Line2) ! RESET) {delay_ms(10);if (key_left_value 0) {led_lightn(2);EXTI_ClearITPendingBit(EXTI_Line2); // 清除中断标志位return;}}
}
/*** brief 外部中断3中断服务函数
*/
void EXTI3_IRQHandler(void) {if (EXTI_GetITStatus(EXTI_Line3) ! RESET) {delay_ms(10);if (key_down_value 0) {led_lightn(1);EXTI_ClearITPendingBit(EXTI_Line3); // 清除中断标志位return;}}
}
/*** brief 外部中断4中断服务函数
*/
void EXTI4_IRQHandler(void) {if (EXTI_GetITStatus(EXTI_Line4) ! RESET) {delay_ms(10);if (key_right_value 0) {led_lightn(3);EXTI_ClearITPendingBit(EXTI_Line4); // 清除中断标志位return;}}
}
本示例的功能在按下按键后分别使用LED显示 0,1,2,3。
六、定时器中断
1. 简介
STM32F1系列微控制器提供了多种定时器模块包括
2个 基本定时器TIM6和TIM7用于生成简单的定时中断适用于一些简单的定时任务。4个 通用定时器TIM2至TIM5具有更多的功能和配置选项可以实现更复杂的定时任务和PWM输出等功能。2个 高级定时器TIM1、TIM8功能最为丰富的定时器可以用于高级的PWM控制、编码器接口、脉冲捕获等应用。 通用定时器通常挂接在APB1 高级定时器通常挂载在AHB上。
2. 通用定时器简介
STM32F1的通用定时器包含一个 16位 自动重载计数器CNT该计数器由可编程预分频器PSC驱动。 通用定时器支持多种工作模式包括定时器模式、定时器中断模式、PWM输出模式、输入捕获模式和输出比较模式等。
使用定时器预分频器和RCC时钟控制器预分频器脉冲长度和波形周期可以在几个微秒至几个毫秒间调整。 通用定时器框图
1时基单元
通用定时器的时基单元是指定时器的基本计时单元它决定了定时器计数的频率和精度。时基单元包括
计数器寄存器TIMx_CNT16位预分频器寄存器TIMx_PSC16位在1~65535之间取值自动装载寄存器TIMx_ARR。
预分频系数用来将定时器的时钟频率降低到一个合适的范围以适应具体的应用需求它的值是一个正整数通常可以通过以下公式来计算
[ \text{实际频率} \frac{\text{时钟源频率}}{\text{预分频系数}} ]
2计数器模式
根据所选的计数器模式定时器的计数器将以不同的方式进行计数。
在向上计数模式下计数器从0开始递增在向下计数模式下计数器从自动重装载值开始递减在中央对齐模式和双边沿对齐模式下计数器的溢出值为自动重装载值的一半。
不同的计数器模式适用于不同的应用场景可以根据具体的需求选择合适的模式来实现相应的功能。
3时钟选择
通用定时器的时钟决定了定时器的计数速率和精度。在STM32微控制器中通用定时器可以选择多种时钟源包括内部时钟源和外部时钟源。
常见的时钟源 内部时钟源Internal Clock Source内部时钟源是由微控制器内部的时钟模块提供的时钟信号通常为主时钟HCLK或高速内部时钟HSI。内部时钟源具有稳定性好、可靠性高的优点适用于大多数应用场景。 外部时钟源External Clock Source外部时钟源是由外部晶振或外部时钟信号提供的时钟信号通常通过外部引脚输入到微控制器内部。外部时钟源具有精度高、抗干扰能力强的特点适用于对时钟精度有较高要求的应用场景。
4输入通道
通用定时器包含4个独立通道TIMx_CH1-4每个通道对应芯片的引脚如下图所示
5捕获通道
捕获通道是通用定时器TIM中用于捕获外部事件如输入脉冲时间戳的通道。在捕获模式下定时器可以监视一个外部信号的边沿触发并记录下此时计数器的值从而得到外部事件的时间戳信息。捕获通道通常用于测量脉冲宽度、频率、周期等应用场景其主要特点
外部事件捕获捕获通道允许定时器监视外部信号的变化如上升沿或下降沿以捕获外部事件的时间戳。多通道支持通用定时器通常支持多个捕获通道每个通道可以独立地捕获外部事件的时间戳。精确度高由于定时器的高精度计数器和硬件触发机制捕获通道可以实现很高的时间精度和稳定性。
6定时器级联
如果使用外部信号控制定时器可实现多个定时器互连使用一个定时器控制另一个定时器。
7定时器中断
通用定时器TIM在STM32微控制器中可以产生多种类型的中断常见的中断包括 更新中断Update Interrupt当定时器的计数器溢出或者自动重装载值被加载到计数器时会产生更新事件从而触发更新中断。更新中断是定时器最基本的中断类型用于处理定时器计数周期结束时的事件。 比较/捕获中断Compare/Capture Interrupt定时器可以配置为输出比较模式或输入捕获模式在这些模式下当计数器的值与比较值相等或者外部事件触发捕获时会产生比较/捕获事件从而触发比较/捕获中断。比较/捕获中断用于处理定时器与外部事件的相关操作。 触发中断Trigger Interrupt定时器可以配置为外部时钟模式或触发输入模式在这些模式下当外部触发事件到来时会产生触发事件从而触发触发中断。触发中断用于处理外部触发事件的相关操作。 DMA请求中断DMA Request Interrupt当定时器的更新、比较或捕获事件发生时可以产生DMA请求从而触发DMA请求中断。DMA请求中断用于处理DMA传输相关的操作。
3. 定时时间计算公式
定时器定时时间的公式可以通过以下方式进行计算 T o u t ( p e r i o d ∗ ( p s c 1 ) ) T c l k T_{out} \frac{(period * (psc1))}{T_{clk}} ToutTclk(period∗(psc1))
4. 配置步骤
通用定时器的配置步骤通常包括以下几个关键步骤
1选择定时器模块
首先确定要使用的通用定时器模块通常有 TIM1、TIM2、TIM3、TIM4 等可供选择根据具体的需求选择合适的定时器模块。
2 初始化时钟
// 使能TIM4时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE); 3初始化定时器参数
需要初始化自动重装值分频系数计数方式等。 // 定时器配置TIM_TimeBaseInitTypeDef TIM_InitStruct;TIM_InitStruct.TIM_Prescaler 36000 - 1; // 预分频系数1~65535实际值会自动加1TIM_InitStruct.TIM_CounterMode TIM_CounterMode_Up; // 向上计数模式TIM_InitStruct.TIM_Period 1000; // 自动重装载值即定时器周期TIM_InitStruct.TIM_ClockDivision TIM_CKD_DIV1; // 时钟分频TIM_InitStruct.TIM_RepetitionCounter 0; // 重复计数器高级计数器使用TIM_TimeBaseInit(TIM2, TIM_InitStruct);这里计算的定时时间为 1000 ∗ 36000 72 M 0.5 ( 秒 ) \frac{1000 * 36000}{72M}0.5(秒) 72M1000∗360000.5(秒)
其中的频率是APB1总线频率*2。
4设置定时器中断类型并使能
// 定时器配置TIM_TimeBaseInitTypeDef TIM_InitStruct;// 此处配置定时器的参数如预分频系数、计数器模式、自动重装载值等// 初始化定时器TIM_TimeBaseInit(TIM2, TIM_InitStruct);// 使能更新中断TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);5使能 // 使能定时器TIM_Cmd(TIM2, ENABLE);6配置中断优先级 // 配置定时器中断优先级NVIC_InitTypeDef NVIC_InitStruct;NVIC_InitStruct.NVIC_IRQChannel TIM2_IRQn;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority 0;NVIC_InitStruct.NVIC_IRQChannelSubPriority 0;NVIC_InitStruct.NVIC_IRQChannelCmd ENABLE;NVIC_Init(NVIC_InitStruct);7中断服务函数
void TIM2_IRQHandler(void) {if (TIM_GetITStatus(TIM2, TIM_IT_Update) ! RESET) {// 处理定时器更新中断事件// 清除中断标志位TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}5. 示例
本示例通过定时器中断控制LED闪烁。
1timx_utils.h
#ifndef __TIMX_UTILS_H__
#define __TIMX_UTILS_H__
#include stm32f10x.h
void timx_init(u16 preriod, u16 psc);
void timx_init_ms(u16 ms);
#endif
2timx_utils.c
#include timx_utils.h
#include led_utils.h
#include stm32f10x.h/*** brief 初始化定时器* param preriod: 自动重装载寄存器周期值* param prescaler: 时钟预分频数
*/
void timx_init(u16 preriod, u16 prescaler)
{TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);TIM_TimeBaseStructure.TIM_Period preriod;TIM_TimeBaseStructure.TIM_Prescaler prescaler;TIM_TimeBaseStructure.TIM_ClockDivision 0;TIM_TimeBaseStructure.TIM_CounterMode TIM_CounterMode_Up;// 初始化TIM_TimeBaseInit(TIM4, TIM_TimeBaseStructure);// 中断使能TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);// 使能定时器TIM_Cmd(TIM4, ENABLE);// 中断优先级NVIC设置NVIC_InitStructure.NVIC_IRQChannel TIM4_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority 1;NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE;NVIC_Init(NVIC_InitStructure);
}
/*** brief 初始化定时器* param ms: 定时器中断时间
*/
void timx_init_ms(u16 ms)
{// 直接调用 timx_init 函数timx_init(ms*2, 36000-1);
}static u8 n0;void TIM4_IRQHandler(void)
{if (TIM_GetITStatus(TIM4, TIM_IT_Update) ! RESET){led_lightn(n);n;if(n9){n0;}TIM_ClearITPendingBit(TIM4, TIM_IT_Update);}
}
3main.c
#include gpio_utils.h
#include stm32f10x.h
#include sys_tick_utils.h
#include led_utils.h
#include exti_utils.h
#include timx_utils.h// 主函数
int main(void)
{GPIO_Configuration(); //调用GPIO配置函数sys_tick_init(72);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 定时器的时钟频率是72MHz,预分频系数是36000,// 所以定时器的时钟频率是72MHz/360002KHz,周期是1000,// 所以定时器的周期是1000/2KHz0.5stimx_init_ms(1000);led_all_off();while (1) //无限循环{delay_ms(10);}
}
七、中断嵌套
1. 概念
中断嵌套是指在一个中断服务程序ISR中允许发生另一个中断的情况。简单来说就是当一个中断正在处理时如果发生了另一个中断系统能够暂时中断当前的中断处理流程转而处理新的中断请求待新的中断处理完成后再返回继续处理原先的中断。
在嵌套中断系统中通常存在多个中断优先级每个中断都有其自己的优先级高优先级的中断可以抢占正在执行的低优先级中断。这样可以确保高优先级的事件能够得到及时处理提高了系统对紧急事件的响应能力。
2. 中断的实现方式
中断嵌套的实现通常需要硬件和软件的支持。
硬件需要提供支持多级中断优先级的中断控制器如STM32系列微控制器中的嵌套向量中断控制器NVIC。软件方面则需要编写合适的中断服务程序并在其中实现中断优先级的管理和中断处理的逻辑。
本文代码开源地址 https://gitee.com/xundh/stm32_arm_learn