STM32F407系列文章目录
第一章 获取相关组件(注意:下载或安装不要有中文路径)
第二章 新建工程
第三章 GPIO相关配置实验
第四章 串口实验
第五章 外部中断实验
前言
本文章采用Keil5及STM32F4(SDK-设计资源)进行STM32F407(ARM芯片)系列学习
- 萌新入坑,如有不对的地方请大佬多多指教,谢谢!->欢迎评论区留言
- 对于萌新来说,学习无非就是多看博文,但是…0.0大佬们的思维大多都有些跳跃,真的很难理解(当然大佬们估计都是为了记录或者提醒自己的工作及学习例程),所以想通过慢慢学习,把每一步都解释出来(保姆版)
第五章 外部中断实验
1.原理图
- MCU引脚
- 涉及外设
2.代码示例
- exti.c
- 库函数版本
#include "exti.h"
#include "delay.h"
#include "key.h"
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOE, ENABLE); // 使能GPIOA,GPIOE时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4; // KEY0 KEY1 KEY2对应引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; // 普通输入模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // 100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // 上拉
GPIO_Init(GPIOE, &GPIO_InitStructure); // 初始化GPIOE2,3,4
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // WK_UP对应引脚PA0
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; // 下拉
GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化GPIOA0
}
void EXTIX_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
KEY_Init(); //按键对应的IO口初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); // 使能SYSCFG时钟
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource2); // PE2 连接到中断线2
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource3); // PE3 连接到中断线3
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource4); // PE4 连接到中断线4
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0); // PA0 连接到中断线0
/* 配置EXTI_Line0 */
EXTI_InitStructure.EXTI_Line = EXTI_Line0; // LINE0
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; // 中断事件
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; // 上升沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE; // 使能LINE0
EXTI_Init(&EXTI_InitStructure); // 配置
/* 配置EXTI_Line2,3,4 */
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); // 配置
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; // 外部中断0
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00; // 抢占优先级0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; // 子优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能外部中断通道
NVIC_Init(&NVIC_InitStructure); // 配置
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn; // 外部中断2
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03; // 抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; // 子优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能外部中断通道
NVIC_Init(&NVIC_InitStructure); // 配置
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn; // 外部中断3
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; // 抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; // 子优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能外部中断通道
NVIC_Init(&NVIC_InitStructure); // 配置
NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn; // 外部中断4
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01; // 抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; // 子优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能外部中断通道
NVIC_Init(&NVIC_InitStructure); // 配置
}
//外部中断0服务程序
void EXTI0_IRQHandler(void)
{
delay_ms(10); // 消抖
if (WK_UP == 1)
{
//BEEP = !BEEP; // 蜂鸣器翻转
}
EXTI_ClearITPendingBit(EXTI_Line0); // 清除LINE0上的中断标志位
}
//外部中断2服务程序
void EXTI2_IRQHandler(void)
{
delay_ms(10); // 消抖
if (KEY2 == 0)
{
//LED0 = !LED0;
}
EXTI_ClearITPendingBit(EXTI_Line2); // 清除LINE2上的中断标志位
}
//外部中断3服务程序
void EXTI3_IRQHandler(void)
{
delay_ms(10); // 消抖
if (KEY1 == 0)
{
//LED1=!LED1;
}
EXTI_ClearITPendingBit(EXTI_Line3); // 清除LINE3上的中断标志位
}
//外部中断4服务程序
void EXTI4_IRQHandler(void)
{
delay_ms(10); // 消抖
if (KEY0 == 0)
{
//LED0 = !LED0;
//LED1 = !LED1;
}
EXTI_ClearITPendingBit(EXTI_Line4); // 清除LINE4上的中断标志位
}
- 寄存器版本
#include "exti.h"
#include "delay.h"
#include "key.h"
void KEY_Init(void)
{
RCC->AHB1ENR |= 1 << 0; // 使能PORTA时钟
RCC->AHB1ENR |= 1 << 4; // 使能PORTE时钟
GPIO_Set(GPIOE, PIN2|PIN3|PIN4, GPIO_MODE_IN, 0, 0, GPIO_PUPD_PU); // PE2~4设置上拉输入
GPIO_Set(GPIOA, PIN0, GPIO_MODE_IN, 0, 0, GPIO_PUPD_PD); // PA0设置为下拉输入
}
void EXTIX_Init(void)
{
KEY_Init();
Ex_NVIC_Config(GPIO_E, 2, FTIR); // 下降沿触发
Ex_NVIC_Config(GPIO_E, 3, FTIR); // 下降沿触发
Ex_NVIC_Config(GPIO_E, 4, FTIR); // 下降沿触发
Ex_NVIC_Config(GPIO_A, 0, RTIR); // 上升沿触发
MY_NVIC_Init(3, 2, EXTI2_IRQn, 2); // 抢占3,子优先级2,组2
MY_NVIC_Init(2, 2, EXTI3_IRQn, 2); // 抢占2,子优先级2,组2
MY_NVIC_Init(1, 2, EXTI4_IRQn, 2); // 抢占1,子优先级2,组2
MY_NVIC_Init(0, 2, EXTI0_IRQn, 2); // 抢占0,子优先级2,组2
}
//外部中断0服务程序
void EXTI0_IRQHandler(void)
{
delay_ms(10); // 消抖
if (WK_UP == 1)
{
//BEEP = !BEEP; // 蜂鸣器翻转
}
EXTI->PR = 1 << 0; // 清除LINE0上的中断标志位
}
//外部中断2服务程序
void EXTI2_IRQHandler(void)
{
delay_ms(10); // 消抖
if (KEY2 == 0)
{
//LED0 = !LED0;
}
EXTI->PR = 1 << 2; // 清除LINE2上的中断标志位
}
//外部中断3服务程序
void EXTI3_IRQHandler(void)
{
delay_ms(10); // 消抖
if (KEY1 == 0)
{
//LED1=!LED1;
}
EXTI->PR = 1 << 3; // 清除LINE3上的中断标志位
}
//外部中断4服务程序
void EXTI4_IRQHandler(void)
{
delay_ms(10); // 消抖
if (KEY0 == 0)
{
//LED0 = !LED0;
//LED1 = !LED1;
}
EXTI->PR = 1 << 4; // 清除LINE4上的中断标志位
}
- exti.h
#ifndef __EXTI_H
#define __EXIT_H
#include "sys.h"
void KEY_Init(void);
void EXTIX_Init(void); // 外部中断初始化
#endif
- main.c
#include "sys.h"
#include "delay.h"
#include "exti.h"
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 设置系统中断优先级分组2
//Stm32_Clock_Init(336, 8, 2, 7); // 设置时钟,168Mhz
delay_init(168); // 初始化延时函数
EXTIX_Init(); // 初始化外部中断输入
while(1)
{
;
}
}
总结
本章为TMS320F280049学习系列文章 第五章:外部中断实验