在这个小项目中,对stm32的GPIO初始化、EXTI中断初始化、NVIC初始化。这里通过A0口进行中断判断,C13进行中断的回应(接LED)
(1)GPIO初始化:先对要判断中断和响应中断的端口进行使能。
void GPIO_Configuration(void)
{
//初始化两个GPIO口
//先将GPIO的A口和C口使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC , ENABLE);
//设置A口结构体
GPIO_InitTypeDef GPIOA_Structure;
GPIOA_Structure.GPIO_Mode=GPIO_Mode_IPU; //GPIOA口设置成上拉输入模式,用于连接按键,只要按按键就下拉0,不按按键就1,安就中断
GPIOA_Structure.GPIO_Pin=GPIO_Pin_0; //设置A0口
GPIOA_Structure.GPIO_Speed=GPIO_Speed_50MHz;
//结构体配置完成,开始初始化GPIO口
GPIO_Init(GPIOA,&GPIOA_Structure); //结构体要引用
//初始化中断响应口
//设置C口结构体
GPIO_InitTypeDef GPIOC_Structure;
GPIOC_Structure.GPIO_Mode=GPIO_Mode_Out_PP; //将C口设置成推挽输出,一般情况,输出都设置成推挽输出
GPIOC_Structure.GPIO_Pin=GPIO_Pin_13;
GPIOC_Structure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIOC_Structure);
}
(2)GPIO口初始化完成了,开始初始化EXTI中断
void EXTI_Configuration(void)
{
//因为EXTI中断识别功能属于端口复用,因此先进行端口复用
//端口复用功能AFIO时钟有APB2控制
//先开启端口复用AFIO功能时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
//映射IO口与EXTI中断线
//因为中断识别对应的是信号的变化的口,也就是按键口,因此,这里选择的是A0(因为A0接的是按键,中断判断)
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);
//清除中断标志位,每执行一次都要清除一次,刷新状态
EXTI_ClearITPendingBit(EXTI_Line0); //也就是A0端口的标志位
//最后,进行中断初始化
//一样的,配置结构体
EXTI_InitTypeDef EXTI_Structure;
EXTI_Structure.EXTI_Line=EXTI_Line0; //中断线路就是0口
EXTI_Structure.EXTI_Mode=EXTI_Mode_Interrupt; //中断模式,就是中断,还有事件选项这里选中断
//因为A0口为上拉输入,即高电平,那么正常情况都是高电平,那么设置低电平为中断出发信号,因此设置成下降引触发
EXTI_Structure.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_Structure.EXTI_LineCmd=ENABLE; //使能,不必赘述
//EXTI结构体配置完成,开始初始化EXTI中断
EXTI_Init(&EXTI_Structure);
}
(3)现在端口和中断都已经都已经初始化完成,开始初始化NVIC,也就是配置优先级
void NVIC_Configuration(void)
{
//先决定要配置几个抢占优先级,几个响应优先级
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//这里配置没有抢占优先级,有16位响应优先级
//配置了优先级个数后,再进行优先级分配
//配置中断优先级
NVIC_InitTypeDef NVIC_Structure;
NVIC_Structure.NVIC_IRQChannel=EXTI0_IRQn;//中断通道号,也就是A0口
NVIC_Structure.NVIC_IRQChannelPreemptionPriority=0; //定义抢占优先级
NVIC_Structure.NVIC_IRQChannelSubPriority=0;//定义响应优先级
NVIC_Structure.NVIC_IRQChannelCmd=ENABLE;//使能,不必赘述
}
(4)配置中断函数,注意,这里的中断函数名是固定的,写错了不会报错也不会运行中断函数
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0) != RESET) //读取A0口的中断状态,如果中断状态不为0,也就是1,则运行
{
GPIOC->ODR ^= GPIO_Pin_13;
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
总程序
#include "stm32f10x.h" // Device header
void GPIO_Configuration(void)
{
//初始化两个GPIO口
//先将GPIO的A口和C口使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC , ENABLE);
//设置A口结构体
GPIO_InitTypeDef GPIOA_Structure;
GPIOA_Structure.GPIO_Mode=GPIO_Mode_IPU; //GPIOA口设置成上拉输入模式,用于连接按键,只要按按键就上拉1,不按按键就0,不安就中断
GPIOA_Structure.GPIO_Pin=GPIO_Pin_0; //设置A0口
GPIOA_Structure.GPIO_Speed=GPIO_Speed_50MHz;
//结构体配置完成,开始初始化GPIO口
GPIO_Init(GPIOA,&GPIOA_Structure); //结构体要引用
//初始化中断响应口
//设置C口结构体
GPIO_InitTypeDef GPIOC_Structure;
GPIOC_Structure.GPIO_Mode=GPIO_Mode_Out_PP; //将C口设置成推挽输出,一般情况,输出都设置成推挽输出
GPIOC_Structure.GPIO_Pin=GPIO_Pin_13;
GPIOC_Structure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIOC_Structure);
}
//GPIO口初始化完成了,开始初始化EXTI中断
void EXTI_Configuration(void)
{
//因为EXTI中断识别功能属于端口复用,因此先进行端口复用
//端口复用功能AFIO时钟有APB2控制
//先开启端口复用AFIO功能时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
//映射IO口与EXTI中断线
//因为中断识别对应的是信号的变化的口,也就是按键口,因此,这里选择的是A0(因为A0接的是按键,中断判断)
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);
//清除中断标志位,每执行一次都要清除一次,刷新状态
EXTI_ClearITPendingBit(EXTI_Line0); //也就是A0端口的标志位
//最后,进行中断初始化
//一样的,配置结构体
EXTI_InitTypeDef EXTI_Structure;
EXTI_Structure.EXTI_Line=EXTI_Line0; //中断线路就是0口
EXTI_Structure.EXTI_Mode=EXTI_Mode_Interrupt; //中断模式,就是中断,还有事件选项这里选中断
//因为A0口为上拉输入,即高电平,那么正常情况都是高电平,那么设置低电平为中断出发信号,因此设置成下降引触发
EXTI_Structure.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_Structure.EXTI_LineCmd=ENABLE; //使能,不必赘述
//EXTI结构体配置完成,开始初始化EXTI中断
EXTI_Init(&EXTI_Structure);
}
//现在端口和中断都已经都已经初始化完成,开始初始化NVIC,也就是配置优先级
void NVIC_Configuration(void)
{
//先决定要配置几个抢占优先级,几个响应优先级
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//这里配置没有抢占优先级,有16位响应优先级
//配置了优先级个数后,再进行优先级分配
//配置中断优先级
NVIC_InitTypeDef NVIC_Structure;
NVIC_Structure.NVIC_IRQChannel=EXTI0_IRQn;//中断通道号,也就是A0口
NVIC_Structure.NVIC_IRQChannelPreemptionPriority=0; //定义抢占优先级
NVIC_Structure.NVIC_IRQChannelSubPriority=0;//定义响应优先级
NVIC_Structure.NVIC_IRQChannelCmd=ENABLE;//使能,不必赘述
}
//配置中断函数,注意,这里的中断函数名是固定的,写错了不会报错也不会运行中断函数
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0) != RESET) //读取A0口的中断状态,如果中断状态不为0,也就是1,则运行
{
GPIOC->ODR ^= GPIO_Pin_13;
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
int main(void)
{
GPIO_Configuration();
NVIC_Configuration();
EXTI_Configuration();
while (1)
{
}
}