[特殊字符] 江协科技 STM32 学习笔记(第五章)
【第五章 EXTI 外部中断】
[5-1] EXTI外部中断
[5-2] 对射式红外传感器计次&旋转编码器计次
引言
目前正处于学习江协STM32,自己想根据学习的内容进行一个总结,也是方便时间一长用于回顾,以方便形成一个整体的框架,也希望能够提供给大家看,同时能够查漏补缺,不正确的地方也希望大家指正。
一、外部中断和中断系统
中断系统是管理和执行中断的逻辑结构,外部中断是众多能产生中断的外设之一,本章借外部中断→(学)中断系统。
1、什么是中断?
在主程序运行过程中,出现了特定的中断触发条件(即中断源),使CPU暂停当前主正在运行的主程序,转而处理中断程序,处理完成后又返回原来被暂停位置主程序,继续运行。
⭐⭐⭐对于外部中断来说,中断时引脚发生了电平跳变;对定时器来说,定时时间到了;对串口来说,可以是接收到了程序。
2、中断优先级:当有多个中断源同时申请中断时,CPU会根据中断源的轻重缓急进行裁决,优先响应更加紧急的中断源。(注:优先级是由自己设置)
3、中断嵌套:当一个中断程序正在运行时,又有新的更高优先级的中断源申请中断,CPU再次暂停当前中断程序,转而处理新的中断程序,处理完后依次进行返回。
二、STM32中断
1.基础知识
1、STM32有68个可屏蔽中断通道,有EXTI(外部中断)、TIM(定时器)、ADC(模拟器转换)、USART(串口)、SPI和I2C(通信)、RTC(实时时钟)等外设。
2、使用NVIC统一管理中断,每个中断通道都拥有16个可编程的优先等级,可对优先级进一步分组,进一步设置抢占优先级和响应优先级。
2.中断实现过程
1、实现EXTI中断基本结构
2、具体实现
基本流程,根据EXTI基本结构写代码
1.配置RCC时钟,启动相应的GPIO和AFIO。EXTI和NVIC是内核外设,不需要开启RCC时钟,这两个的时钟是一直开着的状态,RCC只管内核的外设。
实列代码:
//先是开启GPIOB和AFIO的外设时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
2.配置GPIO口
初始化 GPIOB 端口的第 14 号引脚
实例代码
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
AFIO是一个数据选择器,主要是在前面n个GPIO口中挑选一个到EXTI程序中。(即多个输入一个输出)
在STM32中,AFIO主要有两个任务:①、复用功能引脚重映射 ②、中断引脚选择
GPIO_EXTILineConfig功能为配置AFIO的数据选择器来配置我们想要的中断引脚。配置的是14号引脚。
//第三步:配置AFIO(在库的_gpio中找定义)
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);
4.配置EXTI
EXTI简介:
- EXTI(Extern Interrupt)外部中断
- EXTI可以监测指定GPIO口的电平信号,当其指定的GPIO口产生电平变化时,EXTI将立即向NVIC(CPU的小助理)发出中断申请,经过NVIC裁决后即可中断CPU主程序,使CPU执行EXTI对应的中断程序
- 支持的触发方式:上升沿/下降沿/双边沿/软件触发
- 支持的GPIO口:所有的GPIO口,但相同的Pin不能同时触发中断(因为AFIO与EXTI的接口只有十六个,AFIO只能从众多GPIO的接口中挑选一个来接入EXTI,比如像PA0,PB0,PC0不能够同时使用)
- 通道数:16个GPIO_Pin,外加PVD输出、RTC闹钟、USB唤醒、以太网唤醒
- 触发响应方式:中断响应/事件响应
EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitStructure.EXTI_Line=EXTI_Line14; //要配置的中断线,与所选的pin口相关联
EXTI_InitStructure.EXTI_LineCmd=ENABLE; //指定中断线的新状态,开启中断
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt; //指定外部中断线的模式:中断模式和事件模式
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising; //指定触发信号的有限边沿
EXTI_Init(&EXTI_InitStructure);
5.配置NVIC
NVIC优先级管理,主要进行进行中断分配,NVIC只有一个输出口,根据中断的优先级来告诉CPU来先进行那个中断处理
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //函数中断分组
NVIC_InitTypeDef NVIC_InitStructure; //定义结构
NVIC_InitStructure.NVIC_IRQChannel=EXTI15_10_IRQn; //中断通道开启或者关闭,参数可以是IRQn_Type里面的值
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //指定中断中是使能还是失能;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1; //抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1; //响应优先级
NVIC_Init(&NVIC_InitStructure);
3.注意事项
在stm32中中断函数是固定的,每个中断通道对应一个中断函数,如果写错了中断函数的名字就会进不了中断。
DCD EXTI1_IRQHandler ; EXTI Line 1
DCD EXTI2_IRQHandler ; EXTI Line 2
DCD EXTI3_IRQHandler ; EXTI Line 3
DCD EXTI4_IRQHandler ; EXTI Line 4
DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
其中有一些是共用的(9_5和15_10各自分别分配到了一个通道里,器触发分别各自相同的中断函数,需要根据标志位区分到底那个中断进来),所以要进行中断标志位的判断,确保是我们想要的中断源进入中断函数。
列如:EXTI_GetFlagStatus(EXTI_Line14)==SET,判断是不是EXTI14进入了中断标志位。
在中断结束后一定要清除中断标志位,不然中断标志位置1后会一直申请中断。
//中断函数的名字是固定的,要在startup_stm32f10x_md.s中寻找,看到定义的中断向量表
void EXTI15_10_IRQHandler(void)
{
//中断函数中先进行一个中断标志位的判断,确保是我们想要的中断源触发的函数
if(EXTI_GetITStatus(EXTI_Line14)==SET)
{
// 延时10ms消抖
Delay_ms(10); // 需要实现精确延时函数
// 再次检查引脚电平,确保是稳定的高电平(假设遮挡为高,DO遮挡时时高电平)
if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 1)
{
CountSensor_count++;
}
EXTI_ClearITPendingBit(EXTI_Line14); //启动标志位后一定要清除,因为不清除的话,一直会中断,死循环
}
}
总结
暂时未写,后续补充。
更多推荐
所有评论(0)