- 开发板原理图
这次试验使用按键作为外部中断的触发源。
由于GPIO的每个管脚都可以作为中断源触发,原理图和按键部分一样。
对于GPIO和按键的初始化只需要将之前写好的文件包含进来,调用按键初始化函数就可以了。
此处主要记录中断的配置。
一样创建一个文件夹EXIT。方便于管理。
位于GPIO头文件里面
GPIO_EXTILineConfig();
中断分组函数
NVIC_PriorityGroupConfig();
NVIC用于开启中断的信道。一样的使用go to define可以找到相应的成员的参数写法。
与51单片机不同,STM32的中断服务函数名称不能使用自定义的函数名,而是有固定的写法具体查找exti.c库文件即可。
在中断的结构体配置中将KEY_UP的触发方式选择为上升沿触发,其余三个按键选择为下降沿触发就可完成按键的触发方式的配置。
代码如下:
exit.c
/****************************************************************/
#include "exti.h"
#include "SysTick.h"
#include "key.h"
#include "led.h"
void My_EXTI_Init(void)
{
//结构体变量用于配置NVIC misc中
NVIC_InitTypeDef NVIC_InitStructure;
//EXTI的配置结构体 (exti.h中)
EXTI_InitTypeDef EXTI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);
NVIC_InitStructure.NVIC_IRQChannel=EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel=EXTI2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel=EXTI3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel=EXTI4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
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_InitStructure.EXTI_Line=EXTI_Line2|EXTI_Line3|EXTI_Line4;
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0)==1)
{
delay_ms(10);
if(K_UP==1)
{
led2=0;
}
}
EXTI_ClearITPendingBit(EXTI_Line0);
}
void EXTI2_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line2)==1)
{
delay_ms(10);
if(K_LEFT == 0)
{
led3=1;
}
}
EXTI_ClearITPendingBit(EXTI_Line2);
}
void EXTI3_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line3)==1)
{
delay_ms(10);
if(K_DOWN == 0)
{
led2=1;
}
}
EXTI_ClearITPendingBit(EXTI_Line3);
}
void EXTI4_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line4)==1)
{
delay_ms(10);
if(K_RIGHT == 0)
{
led3=0;
}
}
EXTI_ClearITPendingBit(EXTI_Line4);
}
exit.h
#ifndef _EXTI_H
#define _EXTI_H
void My_EXTI_Init(void);
#include "system.h"
#endif
main.c
#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "key.h"
#include "exti.h"
int main()
{
u8 i;
SysTick_Init(72);
//中断分组
//响应事件总共四位
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
LED_Init();
KEY_Init();
My_EXTI_Init();
while(1)
{
i++;
if(i%20==0)
{
led1=!led1; //LED1状态取反
}
delay_ms(10);
}
}