1、使用GPIOA1来作为外部中断源时,需要定义3个结构体,分别是:GPIO、外部中断、中断优先级控制相关
中断控制部分的结构体在stm32固件库的 中断相关的.h文件找到
2、GPIOA1既是作为输入,也作为外部中断源,需要打开GPIOA的时钟以及GPIO的复用时钟
对其使能
时钟相关函数可以在rcc.h时钟相关的h文件找到
3、 再设置GPIOA1为外部中断源:
4、 然后对中断优先级分组:
这里选择2组,只有一个中断源选哪个都无所谓 。
5、接着对第一步定义的三个结构体进行配置:
GPIO的模式看情况来配置,这里我需要GPIOA1来做振动传感器的输出端,不震动输出高电平,震动输出低电平,所以这里选择的是下拉输入,配置好之后再对各自的内容进行初始化就完成了外部中断的c文件相关的代码。
6、主函数部分的中断代码如下:
外部中断1处理函数在启动文件当中封装好了可以打开直接复制调用
每次执行该中断时会获取中断标志位,执行完成后标志位需要软件置位
外部中断c文件代码
#include "exti.h"
#include "stm32f10x.h"void exti_Init(void)
{GPIO_InitTypeDef shake_init; //定义GPIO结构体EXTI_InitTypeDef exte_init;//定义外部中断结构体NVIC_InitTypeDef nvic_init;//定义中断控制结构体(misc.h文件)//打开GPIOA时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//GPIOA1即是GPIO输出端口也是外部中断源所以打开复用时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);//GPIOA1口设置为外部中断源//中断优先级分组NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置GPIOA1配置shake_init.GPIO_Mode = GPIO_Mode_IPD;//下拉输入shake_init.GPIO_Pin = GPIO_Pin_1;shake_init.GPIO_Speed = GPIO_Speed_10MHz;//GPIOA初始化GPIO_Init(GPIOA, &shake_init);//配置EXTI外部中断exte_init.EXTI_Line = EXTI_Line1;exte_init.EXTI_Mode = EXTI_Mode_Interrupt;//中断模式exte_init.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿信号exte_init.EXTI_LineCmd = ENABLE;//使能中断EXTI_Init(&exte_init);//中断初始化//配置NVIC中断控制器nvic_init.NVIC_IRQChannel = EXTI1_IRQn;//用的是GPIO1所以用中断通道1nvic_init.NVIC_IRQChannelCmd = ENABLE ; nvic_init.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级nvic_init.NVIC_IRQChannelSubPriority = 1;//子优先级NVIC_Init(&nvic_init);//中断控制初始化}
main.c:
#include "led.h"
#include "stm32f10x.h"
#include "relay.h"
#include "exti.h"
#include "shake.h"
void delay(uint16_t time)
{uint16_t i= 0;while(time--){i=12000;while(i--);}}int main()
{LED_Init();Relay_Init();Shake_Init();exti_Init();
void EXTI1_IRQHandler(void)
{if(EXTI_GetITStatus(EXTI_Line1) != RESET){GPIO_ResetBits(GPIOA,GPIO_Pin_3);//闭合继电器delay(1000); GPIO_SetBits(GPIOA,GPIO_Pin_3);//打开继电器}EXTI_ClearFlag(EXTI_Line1);//清除中断标志位}
}
使用中断来代替while函数来判断是否震动点亮led的方式会减少数据的调用,提高单片机工作效率。