STM32F103固件库编程(4)—中断服务
系统异常,体现在内核水平
外部中断,体现在外设水平
NVIC:嵌套向量中断控制器,属于内核外设
(一)中断编程的顺序
- 使能中断请求
- 配置中断优先级分组
- 配置NVIC寄存器,初始化NVIC_InitTypeDef;
- 编写中断服务函数
typedef struct
{
uint8_t NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled.
This parameter can be a value of @ref IRQn_Type
(For the complete STM32 Devices IRQ Channels list, please
refer to stm32f10x.h file) */
uint8_t NVIC_IRQChannelPreemptionPriority; /*!< Specifies the pre-emption priority for the IRQ channel
specified in NVIC_IRQChannel. This parameter can be a value
between 0 and 15 as described in the table @ref NVIC_Priority_Table */
uint8_t NVIC_IRQChannelSubPriority; /*!< Specifies the subpriority level for the IRQ channel specified
in NVIC_IRQChannel. This parameter can be a value
between 0 and 15 as described in the table @ref NVIC_Priority_Table */
FunctionalState NVIC_IRQChannelCmd; /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel
will be enabled or disabled.
This parameter can be set either to ENABLE or DISABLE */
} NVIC_InitTypeDef;
(二)EXTI
EXTI(External interrupt/event controller)—外部中断/事件控制器,管理了控制器的 20 个中断/事件线。每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿 检测和下降沿的检测。EXTI 可以实现对每个中断/事件线进行单独配置,可以单独配置为 中断或者事件,以及触发事件的属性
中断屏蔽寄存器(EXTI_IMR)
事件屏蔽寄存器(EXTI_EMR)
上升沿触发选择寄存器(EXTI_RTSR)
下降沿触发选择寄存器(EXTI_FTSR)
软件中断事件寄存器(EXTI_SWIER)
挂起寄存器(EXTI_PR)
typedef struct
{
uint32_t EXTI_Line; /*!< Specifies the EXTI lines to be enabled or disabled.
This parameter can be any combination of @ref EXTI_Lines */
EXTIMode_TypeDef EXTI_Mode; /*!< Specifies the mode for the EXTI lines.
This parameter can be a value of @ref EXTIMode_TypeDef */
EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines.
This parameter can be a value of @ref EXTIMode_TypeDef */
FunctionalState EXTI_LineCmd; /*!< Specifies the new state of the selected EXTI lines.
This parameter can be set either to ENABLE or DISABLE */
}EXTI_InitTypeDef;
(三)外部中断配置寄存器 1(AFIO_EXTICR1)
这些位可由软件读写,用于选择EXTIx外部中断的输入源
(四)代码部分
main.c
#include "stm32f10x.h"
#include "exti.h"
int main(void)
{
EXTI_Key_Config();
while(1);
}
exti.c
#include "exti.h"
//初始化NVIC
static void EXYI_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStruct.NVIC_IRQChannel=EXTI0_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
void EXTI_Key_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct;
//配置中断优先级
EXYI_NVIC_Config();
//初始化GPIO口
RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK, ENABLE);
GPIO_InitStruct.GPIO_Pin=KEY1_GPIO_PIN;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_Init(KEY1_GPIO_PORT,&GPIO_InitStruct);
//初始化EXTI
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
EXTI_InitStruct.EXTI_Line=EXTI_Line0;
EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising;
EXTI_InitStruct.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStruct);
}
exti.h
#ifndef __EXTI_H
#include "stm32f10x.h"
#define KEY1_GPIO_PIN GPIO_Pin_0
#define KEY1_GPIO_PORT GPIOA
#define KEY1_GPIO_CLK RCC_APB2Periph_GPIOA
void EXTI_Key_Config(void);
#define __EXTI_H
#endif
中断服务函数(在stm32f10x_it.h操作)
首先,#include “exti.h”
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0)!=0)
{
//中断函数
}
//清除中断标志
EXTI_ClearITPendingBit(EXTI_Line0);
}