STM32学习笔记(中断系统)

中断系统

中断向量:由于程序中的中断函数地址是由编译器分配的,不是固定的。但是中断跳转,由于硬件的限制,只能跳到固定的地址执行程序。为了让硬件跳到一个不固定的中断函数里,需要在内存里定义一个地址列表,这个列表的地址是固定的,中断函数发生后,就跳到固定的位置,在这个位置,由编译器,再加上一条跳转到中断函数的代码,这样中断跳转就可以跳转到任意位置了。终端地址的列表就叫中断向量表。相当于中断跳转的一个跳板。

NVIC结构(嵌套中断向量控制器)

统一分配中断优先级和管理中断,NVIC是一个内核外设,是CPU小助手。

·NVIC的中断优先级由优先级寄存器的4位(0~15)决定,这4位可以进行切分,分为高n位的抢占优先级和低4-n位的响应优先级

·抢占优先级高的可以中断嵌套,响应优先级高的可以优先排队,抢占优先级和响应优先级均相同的按中断号排队

分组方式

抢占优先级

响应优先级

分组0

0位,取值为0

4位,取值为0~15

分组1

1位,取值为0~1

3位,取值为0~7

分组2

2位,取值为0~3

2位,取值为0~3

分组3

3位,取值为0~7

1位,取值为0~1

分组4

4位,取值为0~15

0位,取值为0

EXTI(Extern Interrupt)外部中断

外部中断源EXTI的中断向量:EXTI0,EXTI1,EXTI2,EXTI3,EXTI4,EXTI9_5,EXTI9_5,EXTI15_10。

EXTI(Extern Interrupt)外部中断

EXTI可以监测指定GPIO口的电平信号,当其指定的GPIO口产生电平变化时,EXTI将立即向NVIC发出中断申请,经过NVIC裁决后即可中断CPU主程序,使CPU执行EXTI对应的中断程序

支持的触发方式:上升沿/下降沿/双边沿/软件触发

支持的GPIO口:所有GPIO口,但相同的Pin不能同时触发中断

通道数:16个GPIO_Pin,外加PVD输出、RTC闹钟、USB唤醒、以太网唤醒

触发响应方式:中断响应/事件响应(中断相应就是触发中断函数。事件相应就是中断信号不通向CPU,而是通向其他外设,出发其他外设的操作)

PA0,PB0PC0等相同Pin的引脚经过AFIO(数据选择器)后只有其中一个能连接到EXTI通道0上。

AFIO复用IO口

·AFIO主要用于引脚复用功能的选择和重定义

·在STM32中,AFIO主要完成两个任务:复用功能引脚重映射、中断引脚选择

EXTI框图

数据选择器,根据控制端而选择一个输入端输出

中断屏蔽寄存器起到开关作用,如果置1则输出根据请求挂起寄存器输出(中断标志位),如果置0,则屏蔽中断。

发射脉冲信号,从而触发其他外设。

外部中断配置流程

  1. 配置RCC,把涉及到的外设时钟都打开(GPIO,AFIO,EXTI,NVIC。其中EXTI,NVIC无需单独打开,NVIC是内核外设,内核外设也不需要开启时钟。RCC开启的都是内核之外的外设)
  2. 配置GPIO将端口设置为输入模式
  3. 配置AFIO,选择使用的这路GPIO,连接到EXTI
  4. 配置EXTI,选择边沿触发方式,选择出发响应方式
  5. 配置NVIC,给中断选择优先级

AFIO和GPIO在一个文件里面GPIO.H

void GPIO_AFIODeInit(void); //复位AFIO外设,清除AFIO外设配置

void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//锁定GPIO配置,锁定参数的引脚,防止意外更改

void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);//配置事件输出功能

void GPIO_EventOutputCmd(FunctionalState NewState);//配置事件输出功能

void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);//Pin重映射

void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);//配置AFIO数据选择器,选择中断引脚。

EXTI库函数

void EXTI_DeInit(void);//清除EXTI的配置状态,恢复成默认上电状态

void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);//根据结构体EXTI_InitStruct的参数配置EXTI

外设

EXTI_InitStruct的参数有:

EXTI_Line指定要配置的中断线(EXTI_Line0~EXTI_Line19)

EXTI_LineCmd 指定选择中断线的新状态( ENABLE和DISABLE)

EXTI_Mode指定外部中断线的模式(EXTI_Mode_Interrupt 和EXTI_Mode_Event)

EXTI_Trigger指定触发信号的有效边沿(EXTI_Trigger_Rising 上升沿,EXTI_Trigger_Falling下降沿, EXTI_Trigger_Rising_Falling 双边)

void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);//把参数传递的结构体变量赋一个默认值

void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);//软件触发外部中断

FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);//获取指定标志位是否被置1(在主程序中使用)

void EXTI_ClearFlag(uint32_t EXTI_Line);//对置1的标志位进行清除(在主程序中使用)

ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);//获取中断标志位是否被置1(在中断函数中使用)

void EXTI_ClearITPendingBit(uint32_t EXTI_Line);//清除中断挂起标志位(在中断函数中使用)

NVIC库函数在杂项里面misc.h

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);//用来中断分组(抢占和响应)

分组方式整个芯片只能用一种,整个工程定义一次就行

@arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority

  *                                4 bits for subpriority

  *     @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority

  *                                3 bits for subpriority

  *     @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority

  *                                2 bits for subpriority

  *     @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority

  *                                1 bits for subpriority

  *     @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority

  *                                0 bits for subpriority

void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);//根据参数结构体来初始化NVIC

NVIC_IRQChannel 指定中断通道来开启或关闭(用那个通道EXTI0_IRQn,EXTI1_IRQn,EXTI2_IRQn,EXTI3_IRQn,EXTI4_IRQn,EXTI9_5_IRQn,EXTI9_5_IRQn,EXTI15_10_IRQn)

NVIC_IRQChannelCmd 指定通道使能还是失能(ENABLE,DISABLE)

NVIC_IRQChannelPreemptionPriority 指定通道的抢占优先级

NVIC_IRQChannelSubPriority 指定通道的响应优先级

(根据NVIC_PriorityGroupConfig的分组对用来设置)

void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset);//设置中断向量表

void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState);//系统低功耗配置

/******************************************************************************

//1配置RCC,打开时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//打开GPIOB时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//打开AFIO时钟

//2配置GPIO端口

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;

GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;

GPIO_Init(GPIOB,&GPIO_InitStructure);

//3配置AFIO,选择使用PB14作为中断输入

GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);

//4配置EXTI,选择边沿触发方式

EXTI_InitTypeDef EXTI_Initstructure;

EXTI_Initstructure.EXTI_Line = EXTI_Line14;

EXTI_Initstructure.EXTI_LineCmd = ENABLE;

EXTI_Initstructure.EXTI_Mode = EXTI_Mode_Interrupt;

EXTI_Initstructure.EXTI_Trigge

r = EXTI_Trigger_Falling;

EXTI_Init(&EXTI_Initstructure);

//5 NVIC配置

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

NVIC_Init(&NVIC_InitStructure);

******************************************************************************/

中断函数

在STM32中断函数的名字是固定的,函数名在启动文件startup_stm32f10x_md.s中查找。

以IRQHandler结尾的字符串就是中断函数的名字(例如BP14是EXTI15_10通道 函数名为EXTI15_10_IRQHandler)。中断函数都是无参数无返回值,函数名写错就无法进入中断

//中断函数

void EXTI15_10_IRQHandler(void)

{

if(EXTI_GetITStatus(EXTI_Line14) == SET) //判断中断标志位,10-15通道都可以触发EXTI15_10_IRQHandler函数,判断该函数是否14通道触发

{

//中断函数内容

EXTI_ClearITPendingBit(EXTI_Line14);//执行完中断函数后,需要将中断标志位清零

}

}

  • 16
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值