待更新...
1 实验目的
点击KEY1和KEY2,通过触发中断分别实现LED1和LED2的反转。
2 实验准备
2.1 下载器
本次下载使用的下载器是ST-Link,当然也可以使用J-Link。官方下载地址:链接。
![](https://i-blog.csdnimg.cn/blog_migrate/3f9f7cf4a95e3aed2f967d23c962b7dd.jpeg)
2.2 下载器识别
点击魔术棒
![](https://i-blog.csdnimg.cn/blog_migrate/0d70169ceb0ddc33064b9ae187194fdb.png)
选择Debug-->Setting
![](https://i-blog.csdnimg.cn/blog_migrate/c8b36afe4335da615456b598c22898f8.png)
判断是否识别到仿真器(方框中显示ST-Link的信息,说明识别到仿真器)
![](https://i-blog.csdnimg.cn/blog_migrate/d128ab6787467f842fec764d565df09a.png)
2.3 设置Flash信息
设置Flash信息以及设置下载程序立刻运行。
![](https://i-blog.csdnimg.cn/blog_migrate/8fcdcadbb32c4af8c9813083eaa581d5.png)
2.4 设置头文件相关的路径
![](https://i-blog.csdnimg.cn/blog_migrate/83c3226933787772449a8aa3280d4192.png)
3 硬件电路
电路分析:
默认情况的按键是下拉到GND。
按键按下时,PIN脚被上拉到3.3V。
C56、C5的功能是实现消抖。
MCU检测到PA0和PA13为高电平时,进入中断服务函数。
![](https://i-blog.csdnimg.cn/blog_migrate/f223751d204848e412606350de1007d7.png)
4 代码分析
bsp_exit.h
#ifndef __EXTI_H
#define __EXTI_H
#include "stm32f10x.h"
/******************************************引脚定义 start********************************************/
#define KEY1_INT_GPIO_PORT GPIOA
#define KEY1_INT_GPIO_CLK (RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO)
#define KEY1_INT_GPIO_PIN GPIO_Pin_0
#define KEY1_INT_EXTI_PORTSOURCE GPIO_PortSourceGPIOA
#define KEY1_INT_EXTI_PINSOURCE GPIO_PinSource0
#define KEY1_INT_EXTI_LINE EXTI_Line0
#define KEY1_INT_EXTI_IRQ EXTI0_IRQn
#define KEY1_IRQHandler EXTI0_IRQHandler
#define KEY2_INT_GPIO_PORT GPIOC
#define KEY2_INT_GPIO_CLK (RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO)
#define KEY2_INT_GPIO_PIN GPIO_Pin_13
#define KEY2_INT_EXTI_PORTSOURCE GPIO_PortSourceGPIOC
#define KEY2_INT_EXTI_PINSOURCE GPIO_PinSource13
#define KEY2_INT_EXTI_LINE EXTI_Line13
#define KEY2_INT_EXTI_IRQ EXTI15_10_IRQn
#define KEY2_IRQHandler EXTI15_10_IRQHandler
/******************************************引脚定义 end********************************************/
/******************************************函数申明 start********************************************/
void EXTI_Key_Config(void);
/******************************************函数申明 end********************************************/
#endif /* __EXTI_H */
bsp_exit.c
/**
******************************************************************************
* @file bsp_exti.c
* @author 一杯苦咖啡
* @version V1.0
* @date 2023-06-26
* @brief I/O线中断应用bsp
******************************************************************************
*/
#include "bsp_exti.h"
/**************************************************************************************
* name : static void NVIC_Configuration(void)
* Function : 配置嵌套向量中断控制器NVIC
* Parameters : void
* Returns : NULL
* Author : 一杯苦咖啡
* Check :
* Date : 2023/3/26
**************************************************************************************/
static void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* 配置NVIC为优先级组1 */
/* 提示 NVIC_PriorityGroupConfig() 在整个工程只需要调用一次来配置优先级分组*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/* 配置中断源:按键1 */
NVIC_InitStructure.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ;
/* 配置抢占优先级 */
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
/* 配置子优先级 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
/* 使能中断通道 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* 配置中断源:按键2,其他使用上面相关配置 */
NVIC_InitStructure.NVIC_IRQChannel = KEY2_INT_EXTI_IRQ;
NVIC_Init(&NVIC_InitStructure);
}
/**************************************************************************************
* name : void EXTI_Key_Config(void)
* Function : 配置 IO为EXTI中断口,并设置中断优先级
* Parameters : void
* Returns : NULL
* Author : 一杯苦咖啡
* Check :
* Date : 2023/3/26
**************************************************************************************/
void EXTI_Key_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
/*开启按键GPIO口的时钟*/
RCC_APB2PeriphClockCmd(KEY1_INT_GPIO_CLK,ENABLE);
/* 配置 NVIC 中断*/
NVIC_Configuration();
/*--------------------------KEY1配置-----------------------------*/
/* 选择按键用到的GPIO */
GPIO_InitStructure.GPIO_Pin = KEY1_INT_GPIO_PIN;
/* 配置为浮空输入 */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure);
/* 选择EXTI的信号源 */
GPIO_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE, KEY1_INT_EXTI_PINSOURCE);
EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE;
/* EXTI为中断模式 */
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
/* 上升沿中断 */
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
/* 使能中断 */
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/*--------------------------KEY2配置-----------------------------*/
/* 选择按键用到的GPIO */
GPIO_InitStructure.GPIO_Pin = KEY2_INT_GPIO_PIN;
/* 配置为浮空输入 */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(KEY2_INT_GPIO_PORT, &GPIO_InitStructure);
/* 选择EXTI的信号源 */
GPIO_EXTILineConfig(KEY2_INT_EXTI_PORTSOURCE, KEY2_INT_EXTI_PINSOURCE);
EXTI_InitStructure.EXTI_Line = KEY2_INT_EXTI_LINE;
/* EXTI为中断模式 */
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
/* 下降沿中断 */
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
/* 使能中断 */
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
/*********************************************END OF FILE**********************/
stm32f10x_it.h
/**************************************************************************************
* name : void KEY1_IRQHandler(void)
* Function : 按键中断1的中断服务函数
* Parameters : void
* Returns : NULL
* Author : 一杯苦咖啡
* Check :
* Date : 2023/3/26
**************************************************************************************/
void KEY1_IRQHandler(void)
{
//确保是否产生了EXTI Line中断
if(EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET)
{
// LED1 取反
LED1_TOGGLE;
//清除中断标志位
EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE);
}
}
/**************************************************************************************
* name : void KEY2_IRQHandler(void)
* Function : 按键中断2的中断服务函数
* Parameters : void
* Returns : NULL
* Author : 一杯苦咖啡
* Check :
* Date : 2023/3/26
**************************************************************************************/
void KEY2_IRQHandler(void)
{
//确保是否产生了EXTI Line中断
if(EXTI_GetITStatus(KEY2_INT_EXTI_LINE) != RESET)
{
// LED2 取反
LED2_TOGGLE;
//清除中断标志位
EXTI_ClearITPendingBit(KEY2_INT_EXTI_LINE);
}
}
main.c
/**
******************************************************************************
* @file bsp_led.c
* @author fire
* @version V1.0
* @date 2023-03-26
* @brief 主函数
*******************************************************************************
**/
#include "bsp_led.h"
#define SOFT_DELAY Delay(0x0FFFFF);
void Delay(__IO u32 nCount);
/**************************************************************************************
* name : int main(void)
* Function : 主函数
* Parameters : void
* Returns : NULL
* Author : 一杯苦咖啡
* Check :
* Date : 2021/3/20
**************************************************************************************/
int main(void)
{
/* LED 端口初始化 */
LED_GPIO_Config();
/* 初始化EXTI中断,按下按键会触发中断,
* 触发中断会进入stm32f4xx_it.c文件中的函数
* KEY1_IRQHandler和KEY2_IRQHandler,处理中断,反转LED灯。
*/
EXTI_Key_Config();
/* 等待中断,由于使用中断方式,CPU不用轮询按键 */
while(1)
{
}
}
/*********************************************END OF FILE**********************/
5 实验效果演示
![](https://i-blog.csdnimg.cn/blog_migrate/33a1bc14f79e9c1e755875fc66f44880.png)
6 问题分析
为什么无仿真器无法使用,设备管理器上显示有黄色感叹号?
没有安装ST-Link的驱动(驱动的下载位置文中有详细说明)