1、外部中断/事件线映射
从上表可知,STM32F10x 的 EXTI 供外部 IO 口使用的中断线有 16 根,但是我们使用的 STM32F103 芯片却远远不止 16 个 IO 口,那么 STM32F103 芯片怎么解决这个问题的呢?因为 STM32F103 芯片每个 GPIO 端口均有 16 个管脚,因此把每个 端 口 的 16 个 IO 对 应 那 16 根 中 断 线 EXTI0-EXTI15 。比 如 :GPIOx.0-GPIOx.15(x=A,B,C,D,E,F,G)分别对应中断线 EXTI0-EXTI15,这样一来每个中断线就对应了最多 7 个 IO 口,比如:GPIOA.0、GPIOB.0、GPIOC.0、GPIOD.0、GPIOE.0、GPIOF.0、GPIOG.0。但是中断线每次只能连接一个在 IO 口上,这样就需要通过 AFIO 的外部中断配置寄存器 1 的 EXTIx[3:0]位来决定对应的中断线映射到哪个 GPIO 端口上,对于中断线映射到 GPIO 端口上的配置函数在stm32f10x_gpio.c 和 stm32f10x_gpio.h 中,所以使用到外部中断时要把这个文件加入到工程中,在创建库函数模板的时候我们默认已经添加。
2、EXTI 配置
#include "stm32f10x.h"
uint8_t main_temp = 0; //标志位
void LED_Init()
{
GPIO_InitTypeDef GPIO_InitStructure; //定义结构体变量
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0; //选择你要设置的IO口
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //设置推挽输出模式
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //设置传输速率
GPIO_Init(GPIOC,&GPIO_InitStructure); //初始化GPIO
GPIO_SetBits(GPIOC,GPIO_Pin_0); //将LED端口拉高,熄灭所有LED
}
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //定义结构体变量
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0; //选择你要设置的IO口
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD; //下拉输入
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //设置传输速率
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化GPIO
}
/*
* 简单说明: 外部中断初始化
*/
void My_EXTI_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//开启 AFIO 时钟
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);//选择GPIO管脚用作外部中断线路
//EXTI0 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //EXTI0中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2; //抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //子优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
EXTI_InitStructure.EXTI_Line=EXTI_Line0; //中断/事件线
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt; //中断模式
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising; //上升沿触发
EXTI_InitStructure.EXTI_LineCmd=ENABLE; //使能
EXTI_Init(&EXTI_InitStructure); //初始化EXTI
}
/*
* 简单说明: 外部中断0函数
*/
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0)==1) //判断中断线是否有中断发生
{
if( main_temp ){
main_temp = 0x00;
}
else{
main_temp = 0xff;
}
}
EXTI_ClearITPendingBit(EXTI_Line0); //清除中断标志位
}
int main( void )
{
LED_Init();
KEY_Init();
My_EXTI_Init();
while(1)
{
if( main_temp == 0x00 ){
GPIO_SetBits(GPIOC,GPIO_Pin_0);
}
else{
GPIO_ResetBits(GPIOC,GPIO_Pin_0);
}
}
}
--END--