STM32外部中断实验

STM32外部中断实验

1、前言

​ 本篇介绍的是使用外部按键,将B5引脚做为外部中断输入的IO口,利用外部中断来点亮STM32开发板上面的LED灯。

2、硬件连接

​ 将按键一端连接到B5引脚上另一端连接到B6引脚上。

3、外部中断

​ 我认为外部中断其实就是一条自己规定程序的中断条件,可以随时中断现在正在运行的程序而执行中断函数的一条指令。此次外部中断实验的原理就是将B5引脚设置为下降沿触发(程序每执行一遍都会检验中断是否触发,即检验B5是否为低电平),当检验到B5为低电平时立即中断正在运行的主程序,跳转运行至中断处理函数改变开发板上LED灯的状态,运行完后再回到主函数继续运行。

1、相关寄存器

​ ISER[8]中断使能寄存器组,ICER[8]中断除能寄存器组,ISPR[8]中断挂起控制寄存器组,ICPR[8]个中断解挂控制寄存器组,IABR[8]中断激活标志位寄存器组,IP[240]中断优先级控制的寄存器组。这些寄存器都是对应位写1有效,写0无效。

​ IMR:中断屏蔽寄存器,EMR:事件屏蔽寄存器,FTSR:下降沿触发选择寄存器,SWIER:软件中断事件寄存器,PR:挂起寄存器。

​ 关于寄存器详细信息可参考STM3不完全手册83~89页

2、中断分组

​ IP 寄存器组由 240 个 8bit 的寄存器组成,每个可屏蔽中断占用 8bit,这样总共可以表示 240 个可屏蔽中断。而 STM32 只用到 了其中的 68 个。IP[67]~IP[0]分别对应中断 67~0。而每个可屏蔽中断占用的 8bit 并没有全部使 用,而是 只用了高 4 位。这 4 位,又分为抢占优先级和子优先级。抢占优先级在前,子优先级 在后。而这两个优先级各占几个位又要根据 SCB->AIRCR 中的中断分组设置来决定。

​ 这里简单介绍一下 STM32 的中断分组:STM32 将中断分为 5 个组,组 0-4。该分组的设 置是由 SCB->AIRCR 寄存器的 bit10-8 来定义的。具体的分配关系如图所示:

在这里插入图片描述

​ 通过这个图,我们就可以清楚的看到组 0-4 对应的配置关系,例如组设置为 3,那么此时 所有的 68 个中断,每个中断的中断优先寄存器的高四位中的最高 3 位是抢占优先级,低 1 位是 响应优先级。每个中断,你可以设置抢占优先级为 0-7,响应优先级为 1 或 0。抢占优先级的 级别高于响应优先级。而数值越小所代表的优先级就越高

两个中断优先级的比较就像两个两位数的数字进行比较,抢占优先级相当于十位,响应优先级相当于个位。先比较十位再比较个位。

​ 这里需要注意两点:
第一,如果两个中断的抢占优先级和响应优先级都是一样的话,则看 哪个中断先发生就先执行

​ 第二,高优先级的抢占优先级是可以打断正在进行的低抢占优先级 中断的。而抢占优先级相同的中断,高优先级的响应优先级不可以打断低响应优先级的中断

//设置 NVIC 分组

//NVIC_Group:NVIC 分组 0~4 总共 5 组

void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group)

{ u32 temp,temp1; temp1=(~NVIC_Group)&0x07;//取后三位

temp1<<=8; temp=SCB->AIRCR; //读取先前的设置

temp&=0X0000F8FF; //清空先前分组 temp|=0X05FA0000; //写入钥匙

temp|=temp1; SCB->AIRCR=temp; //设置分组

}

3、外部中断的配置

外部中断初始化

//设置 NVIC

//NVIC_PreemptionPriority:抢占优先级

//NVIC_SubPriority :响应优先级

//NVIC_Channel :中断编号

//NVIC_Group :中断分组 0~4

//注意优先级不能超过设定的组的范围!否则会有意想不到的错误

//组划分:

//组 0:0 位抢占优先级,4 位响应优先级

//组 1:1 位抢占优先级,3 位响应优先级

//组 2:2 位抢占优先级,2 位响应优先级

//组 3:3 位抢占优先级,1 位响应优先级

//组 4:4 位抢占优先级,0 位响应优先级

//NVIC_SubPriority 和 NVIC_PreemptionPriority 的原则是,数值越小,越优先

void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel, u8 NVIC_Group)

{

u32 temp;

MY_NVIC_PriorityGroupConfig(NVIC_Group);//设置分组

temp=NVIC_PreemptionPriority<<(4-NVIC_Group);

temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);

temp&=0xf; //取低四位

NVIC->ISER[NVIC_Channel/32]|=(1<IP[NVIC_Channel]|=temp<<4; //设置响应优先级和抢断优先级

}

外部中断配置

//外部中断配置函数

//只针对 GPIOA~G;不包括 PVD,RTC 和 USB 唤醒这三个

//参数:GPIOx:0~6,代表 GPIOA~G;BITx:需要使能的位;TRIM:触发模式,1,下升沿;

// 2,上降沿;3,任意电平触发

//该函数一次只能配置 1 个 IO 口,多个 IO 口,需多次调用

//该函数会自动开启对应中断,以及屏蔽线

void Ex_NVIC_Config(u8 GPIOx,u8 BITx,u8 TRIM)

{

u8 EXTADDR;

u8 EXTOFFSET;

EXTADDR=BITx/4; //得到中断寄存器组的编号

EXTOFFSET=(BITx%4)*4;

RCC->APB2ENR|=0x01; //使能 io 复用时钟

AFIO->EXTICR[EXTADDR]&=~(0x000F<<EXTOFFSET);//清除原来设置!!!

AFIO->EXTICR[EXTADDR]|=GPIOx<<EXTOFFSET;//EXTI.BITx 映射到 GPIOx.BITx

//自动设置

EXTI->IMR|=1<<BITx; //开启 line BITx 上的中断

if(TRIM&0x01)EXTI->FTSR|=1<<BITx; //line BITx 上事件下降沿触发

if(TRIM&0x02)EXTI->RTSR|=1<<BITx; //line BITx 上事件上升降沿触发

}

4、代码实现

中断服务函数:

//外部中断9~5服务程序 void EXTI9_5_IRQHandler(void) { delay_ms(10); //消抖 if(KEY0==0) //按键0 { LED0=!LED0; } EXTI->PR=1<<5; //清除LINE5上的中断标志位 }

​ 设置完中断服务函数后记得清除LINE5上的中断标志位

​ IO口0到4各占一个寄存器,9到5共用一个寄存器,14到10共用一个寄存器。

初始化外部中断:

//外部中断初始化程序

//初始化PA0,PC5,PA15为中断输入.

void EXTI_Init(void)

{

KEY_Init(); Ex_NVIC_Config(GPIO_B,5,FTIR); //下降沿触发 MY_NVIC_Init(2,2,EXTI9_5_IRQn,2); //抢占2,子优先级2,组2

}

测试函数

int main(void)

{

Stm32_Clock_Init(9);//系统时钟设置

delay_init(72); //延时初始化

uart_init(72,9600); //串口初始化

LED_Init(); //初始化与LED连接的硬件接口

EXTI_Init(); //外部中断初始化

LED0=0; //点亮LED

while(1)

{

printf("OK\r\n");

delay_ms(1000);

}

); //串口初始化 `

LED_Init(); //初始化与LED连接的硬件接口

EXTI_Init(); //外部中断初始化

LED0=0; //点亮LED

while(1)

{

printf("OK\r\n");

delay_ms(1000);

}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值