1、STM32外部中断简介
STM32F103 的中断控制器支持 19 个外部中断/
事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。 STM32F103 的
19 个外部中断为:
线 0~15:对应外部 IO 口的输入中断。
线 16:连接到 PVD 输出。
线 17:连接到 RTC 闹钟事件。
线 18:连接到 USB 唤醒事件。
STM32 供 IO 口使用的中断线有 16 条,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 口上。
2、实验内容
通过板载的 3 个按键,控制板载的两个 LED 的亮灭以及蜂鸣器的发声。
3、实验思路
1、初始化IO口为输入。
GPIO_Init();
2、 开启IO口复用时钟。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
3、设置IO口与中断线的映射关系。
void GPIO_EXTILineConfig();
4、初始化线上中断,设置触发方式等。
EXTI_Init();
5、配置中断分组(NVIC),并使能中断。
NVIC_Init();
6、编写中断服务函数。
EXTIx_IRQHandler();
7、清除中断标志位
EXTI_ClearITPendingBit();
4、实验代码
main.c
#include "led.h"
#include "key.h"
#include "beep.h"
#include "delay.h"
#include "exti.h"
#include "usart.h"
int main()
{
delay_init();
LED_Init();
KEY_Init();
BEEP_Init();
EXTIX_Init();
LED1 = 0;
while(1)
{
printf("OK\r\n");
delay_ms(100);
}
}
exti.h
#ifndef __EXTI_H
#define __EXTI_H
#include "stm32f10x_exti.h"
void EXTIX_Init(void);
#endif
exti.c
#include "exti.h"
#include "led.h"
#include "key.h"
#include "beep.h"
#include "delay.h"
void EXTIX_Init(void )
{
EXTI_InitTypeDef EXTI_InitStructrue;
NVIC_InitTypeDef NVIC_InitStructrue;
KEY_Init();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); // 使能AFIO时钟;
// PE.3 IO与中断映射关系;
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource3);
// 初始化线上中断和中断触发方式;
EXTI_InitStructrue.EXTI_Line = EXTI_Line3;
EXTI_InitStructrue.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructrue.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructrue.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructrue);
NVIC_InitStructrue.NVIC_IRQChannel = EXTI3_IRQn;
NVIC_InitStructrue.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructrue.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructrue.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructrue);
// PE.4 IO与中断映射关系;
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource4);
// 初始化线上中断和中断触发方式;
EXTI_InitStructrue.EXTI_Line = EXTI_Line4;
EXTI_Init(&EXTI_InitStructrue);
NVIC_InitStructrue.NVIC_IRQChannel = EXTI4_IRQn;
NVIC_InitStructrue.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructrue.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructrue);
}
void EXTI3_IRQHandler()
{
delay_ms(10); // 消抖;
if (KEY1 == 0)
{
LED1 = !LED1;
LED0 = !LED0;
}
EXTI_ClearITPendingBit(EXTI_Line3);
}
void EXTI4_IRQHandler()
{
delay_ms(10); // 消抖;
if (KEY0 == 1)
{
BEEP = !BEEP;
}
EXTI_ClearITPendingBit(EXTI_Line4);
}