单片机外部中断的基本原理
STM32 的每个 IO 都可以作为外部中断的中断输入口,这点也是 STM32 的强大之处。那么其中断是怎样实现的呢?其原理就是由GPIO口产生触发信号,通过NVIC中断控制器和EXTI外部中断控制器完成中断响应。使用外部中断可以对优先级进行分组,设置抢占优先级和响应优先级。
STM32F103 的中断控制器支持 19 个外部中断/ 事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。STM32F103 的19 个外部中断为:
- 线 0~15:对应外部 IO 口的输入中断。
- 线 16:连接到PVD 输出。
- 线 17:连接到RTC 闹钟事件。
- 线 18:连接到USB 唤醒事件。
STM32 供 IO 口使用的中断线只有 16 个,但 STM32 的 IO 口却远远不止 16 个,那么是怎样对应的呢?其实是采用“一对多”的形式。GPIO 的管教 GPIOx.0至GPIOx.15(x=A、B、C、D、E、F、G)分别对应中断线 0~15。这样每个中断线对应了最多 7 个 IO 口,以线 0 为例:它对应了GPIOA.0、GPIOB.0、GPIOC.0、GPIOD.0、GPIOE.0、GPIOF.0、GPIOG.0。而中断线每次只能连接到 1 个 IO 口上,这样就需要通过配置来决定对应的中断线配置到哪个 GPIO 上了。如下图所示,左边为GPIO,右边为对应的中断线。
实验案例
红外对管检测实验
红外对管传感器通过比较器输出高低电平,当有遮挡输出低电平,无遮挡输出高电平。
- 实验准备:STM32核心板和红外对管
- 原理图
程序源码:
1、外部中断配置与中断服务函数
void EXTIX_Init(void)
{EXTI_InitTypeDef EXTI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;INFRARED_Init();RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能复用功能时钟//GPIOA.0 中断线以及中断初始化配置 下降沿触发 PA0 //红外对管对应PA0GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0); EXTI_InitStructure.EXTI_Line=EXTI_Line0;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能红外对管 所在的外部中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2, NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03; //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道NVIC_Init(&NVIC_InitStructure);
}//外部中断0服务程序
void EXTI0_IRQHandler(void)
{LED0=!LED0; EXTI_ClearITPendingBit(EXTI_Line0); //清除LINE0上的中断标志位
}
2、主函数
int main(void)
{ delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级uart_init(115200); //串口初始化为115200LED_Init(); //初始化与LED连接的硬件接口INFRARED_Init(); //初始化红外对管的硬件接口EXTIX_Init(); //外部中断初始化LED0=0; //点亮LED0while(1){ printf("OK\r\n"); delay_ms(1000); }
}
实验现象:
本实验通过外部中断0检测红外对管是否有被遮挡,当用手指遮挡红外对管传感器,触发中断,板载独立led状态翻转。
继电器开合原理
继电器的工作原理与线圈电流密不可分。当线圈中通过电流时,会产生磁场,从而使继电器的触点闭合或断开。继电器中的弹簧用于保持触点的闭合或断开状态。当线圈中无电流时,弹簧的弹力会使触点保持闭合;当线圈中有电流时,磁场产生的吸力会克服弹簧的弹力,使触点断开。
继电器控制实验
继电器模块电路由三极管控制并驱动继电器,其中三极管的基极与单片机的IO口相连RL-IO。继电器的控制引脚RL-IO与单片机引脚PD7相连接。
- 实验需要:STM32核心板和继电器模块
- 继电器模块电路原理图:
程序源码:
首先,我们要对继电器进行初始化,并定义好各种继电器设置,如输出1时,关闭继电器。下面仅展示主函数。
int main(void){delay_init(); //延时函数初始化 RELAY_Init(); //初始化蜂鸣器端口while(1){RELAY=0; delay_ms(1000);//延时1000msRELAY=1; delay_ms(1000);//延时1000ms}}
实验现象:
编译并下载程序,本实验通过代码控制底板上的继电器周期性的打开关闭,可以听到继电器吸合的“哒哒”声。