银杏科技有限公司旗下技术文档发布平台 |
技术支持电话 | 0379-69926675-801 |
技术支持邮件 | Gingko@vip.163.com |
版本 | 日期 | 作者 | 修改内容 |
V1.0 | 2020-07-03 | gingko | 初次建立 |
实验三:EXTI外部中断输入实验——读取ARM按键状态
一、 实验目的与意义
了解STM32 GPIO结构。
了解STM32 GPIO 特征。
掌握EXTI中断的使用方法。
掌握STM32 HAL库中EXTI属性的配置方法。
掌握KEIL MDK 集成开发环境使用方法。
二、 实验设备及平台
-
-
Micro USB线缆。
Keil MDK 开发平台。
STM32CubeMX开发平台。
装有WIN XP(及更高版本)系统的计算机。
三、 实验原理
1、中断简介
2、STM32 NVIC中断简介
CM7内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置。但STM32F767并没有使用CM7内核的全部东西,而是只用了它的一部分。STM32F767xx总共有118个中断,其中包括10个内核中断和108个可屏蔽中断,具有16级可编程的中断优先级,而我们常用的就是这108个可屏蔽中断。
STM32F767的中断分组:STM32F767将中断分为5个组,组0~4。该分组的设置是由SCB→AIRCR寄存器的 bit10~8 来定义的。具体的分配关系如下表所示:
通过这个表,我们就可以清楚的看到组0~4对应的配置关系,例如组设置为3,那么此时所有的108个中断,每个中断的中断优先寄存器的高四位中的最高3位是抢占优先级,低1位是响应优先级。每个中断,你可以设置抢占优先级为0~7,响应优先级为1或0。抢占优先级的级别高于响应优先级。而数值越小所代表的优先级就越高。
这里需要注意两点:第一,如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;第二,高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。而抢占优先级相同的中断,高优先级的响应优先级不可以打断低响应优先级的中断。
结合实例说明一下:假定设置中断优先级组为2,然后设置中断3(RTC_WKUP中断)的抢占优先级为2,响应优先级为1。中断6(外部中断0)的抢占优先级为3,响应优先级为0。中断7(外部中断1)的抢占优先级为2,响应优先级为0。那么这3个中断的优先级顺序为:中断7>中断3>中断6。
上面例子中的中断3和中断7都可以打断中断6的中断。而中断7和中断3却不可以相互打断!
3、STM32F7 外部中断简介
STM32F7的每个IO都可以作为外部中断的中断输入口,这点也是STM32F7的强大之处。STM32F7的中断控制器支持22个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。STM32F7的23个外部中断为:
从上面可以看出,中断线0-15对应外部IO口的输入中断,一共是16个外部中断线。STM32F7供IO口使用的中断线只有16个,但是STM32F7的IO口却远远不止16个,那么STM32F7是怎么把16个中断线和IO口一一对应起来的呢?于是STM32就这样设计,GPIO的引脚GPIOx.0~GPIOx.15(x=A,B,C,D,E,F,G,H,I)分别对应中断线0~15。这样每个中断线对应了最多9个IO口,以线0为例:它对应了GPIOA.0、GPIOB.0、GPIOC.0、GPIOD.0、GPIOE.0、GPIOF.0、GPIOG.0、GPIOH.0、GPIOI.0。而中断线每次只能连接到1个IO口上,这样就需要通过配置来决定对应的中断线配置到哪个GPIO上了。下面我们看看GPIO跟中断线的映射关系图:
四、 实验程序
1、主函数
int main(void)
{
/* MCU 配置*/
/* 重置所有外围设备,初始化Flash接口和Systick */
HAL_Init();
/* 配置系统时钟 */
SystemClock_Config();
/* 初始化所有已配置的外围设备 */
MX_GPIO_Init();
LED_RED_ON;//初始化LED状态,红灯亮
while (1)
{
}
}
2、ARM_KEY引脚初始化
/*配置ARM_KEY引脚: PB9 */
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;//下降沿触发检测的外部中断模式
GPIO_InitStruct.Pull = GPIO_PULLUP;//
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* 外部中断初始化*/
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 15, 0); //设置中断的优先级。
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);// 在NVIC中断控制器中启用设备特定的中断。
3、中断回调函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
static int led_work_status = 0;
HAL_Delay(10);
if(ARM_KEY_STATE == KEY_DOWN){
led_work_status += 1;
if(led_work_status > 2)led_work_status = 0;
}
switch(led_work_status){
case 0:
LED_RED_ON;
LED_GREEN_OFF;
LED_BLUE_OFF;
break;
case 1:
LED_RED_OFF;
LED_GREEN_ON;
LED_BLUE_OFF;
break;
case 2:
LED_RED_OFF;
LED_GREEN_OFF;
LED_BLUE_ON;
break;
default:
break;
}
__HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_9); //清除EXTI的行挂起标志。
五、 实验步骤
把仿真器与iCore4的SWD调试口相连(直接相连或者通过转接器相连);
把iCore4通过Micro USB线与计算机相连,为iCore4供电;
打开Keil MDK 开发环境,并打开本实验工程;
烧写程序到iCore4上;
也可以进入Debug 模式,单步运行或设置断点验证程序逻辑。
六、 实验现象