STM32——固件库外部 中断 EXTI和NVIC 震动感应灯
1.配置 GPIOA1
//1.配置GPIOA1
GPIO_InitTypeDef shake_init;
//1.1使能GPIOA时钟,设置复用,中断线输入
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //设置复用 用作外部中断源
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1); //外设端口作为中断线号输入
//1.2.配置GPIOA结构体
shake_init.GPIO_Mode = GPIO_Mode_IPD;
shake_init.GPIO_Pin = GPIO_Pin_1;
shake_init.GPIO_Speed = GPIO_Speed_10MHz;
//1.3初始化GPIOA
GPIO_Init(GPIOA, &shake_init);
2.配置 EXIT 外部中断结构体
EXTI_Line:中断线(一共20条)
EXTI_Mode:EXTI 中断的模式/产生的事件
EXTI_Trigger:EXTI()触发方式 上升沿 下降沿 上下都触发)
EXTI_LineCmd:控制是否使能EXTI线,使能EXTI线或禁用
//2.配置 EXIT 外部中断结构体
EXTI_InitTypeDef exti_init;
exti_init.EXTI_Line = EXTI_Line1; //A1 引脚,所以中断线1
exti_init.EXTI_Mode = EXTI_Mode_Interrupt; //中断模式
exti_init.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
exti_init.EXTI_LineCmd = ENABLE; //使能中断线1
EXTI_Init(&exti_init); //初始化 exti 外部中断
3.配置NVIC中断优先级结构体
//3.配置NVIC中断优先级结构体
NVIC_InitTypeDef nvic_init;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置第2组
//GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1); //外设端口作为中断线号输入
nvic_init.NVIC_IRQChannel = EXTI1_IRQn; //A1引脚嘛 选择通道1
nvic_init.NVIC_IRQChannelSubPriority = 1; //设置抢占优先级 1级
nvic_init.NVIC_IRQChannelPreemptionPriority = 1; //设置子优先级 1级
nvic_init.NVIC_IRQChannelCmd = ENABLE; //使能VIC优先级开关
NVIC_Init(&nvic_init); //初始化NVIC中断优先级
4.搭建中断服务函数
//4.搭建中断函数服务函数
void EXTI1_IRQHandler()
{
if( EXTI_GetITStatus(EXTI_Line1) != RESET ) //检查中断状态,RESET=发生中断
{
GPIO_ResetBits(GPIOA, GPIO_Pin_3);
delay(1000);
GPIO_SetBits(GPIOA, GPIO_Pin_3);
}
EXTI_ClearITPendingBit(EXTI_Line1); //清除标志位
}
exti.c
#include "exti.h"
#include "stm32f10x.h"
void exti_Init()
{
EXTI_InitTypeDef exti_init;
NVIC_InitTypeDef nvic_init;
//1.配置GPIOA
GPIO_InitTypeDef shake_init;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
// GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);
shake_init.GPIO_Mode = GPIO_Mode_IPD;
shake_init.GPIO_Pin = GPIO_Pin_1;
shake_init.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOA, &shake_init);
//2.设置EXTI外部中断
exti_init.EXTI_Line = EXTI_Line1;
exti_init.EXTI_Mode = EXTI_Mode_Interrupt;
exti_init.EXTI_Trigger = EXTI_Trigger_Falling;
exti_init.EXTI_LineCmd = ENABLE;
EXTI_Init(&exti_init);
//3.配置NVIC中断优先级
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);
nvic_init.NVIC_IRQChannel = EXTI1_IRQn;
nvic_init.NVIC_IRQChannelSubPriority = 1;
nvic_init.NVIC_IRQChannelPreemptionPriority = 1;
nvic_init.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvic_init);
}
exti.h
#include "stm32f10x.h"
void exti_Init(void);
main.c
#include "stm32f10x.h"
#include "main.h"
#include "led.h"
#include "shake.h"
#include "relay.h"
#include "exti.h"
void delay(uint16_t time)
{
uint16_t i=0;
while(time--)
{
i=10000;
while(i--);
}
}
int main()
{
// LED_Init();
Shake_Init();
Relay_Init();
exti_Init();
// GPIO_SetBits(GPIOC, GPIO_Pin_13);
GPIO_SetBits(GPIOA, GPIO_Pin_3);
while(1)
{
}
}
void EXTI1_IRQHandler()
{
//4.搭建中断服务函数
if( EXTI_GetITStatus(EXTI_Line1) != RESET ) //判断是否发生中断
{
GPIO_ResetBits(GPIOA, GPIO_Pin_3);
delay(1000);
GPIO_SetBits(GPIOA, GPIO_Pin_3);
}
EXTI_ClearFlag(EXTI_Line1); //清除标志位
}