OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 688|回复: 0

《M144Z-M3最小系统板使用指南——STM32F103版》第十二章 外部中断实验

[复制链接]

1117

主题

1128

帖子

2

精华

超级版主

Rank: 8Rank: 8

积分
4667
金钱
4667
注册时间
2019-5-8
在线时间
1224 小时
发表于 2024-3-28 14:24:12 | 显示全部楼层 |阅读模式
本帖最后由 正点原子运营 于 2024-3-27 16:29 编辑

第十二章 外部中断实验
1)实验平台:正点原子 M144Z-M3 STM32F103最小系统板

2) 章节摘自【正点原子】M144Z-M3最小系统板使用指南——STM32F103版


4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boar ... _mini_sysboard.html

5)正点原子官方B站:https://space.bilibili.com/394620890

6)正点原子STM32技术交流QQ群:725095144

155537c2odj87vz1z9vj6l.jpg

155537nfqovl2gg9faaol9.png

前两章介绍了GPIO在输出模式和输入模式下最基本的的操作,本章将介绍如何将GPIO引脚作为外部中断输入来使用。通过本章的学习,读者将学习到GPIO作为外部中断输入的使用。
本章分为如下几个小节:
12.1 硬件设计
12.2 程序设计
12.3 下载验证

12.1 硬件设计
12.1.1 例程功能
1. 按下WKUP按键,LED0状态翻转。
2. 按下KEY0按键,LED1状态翻转。

12.1.2硬件资源
1. LED
       LED0 - PB5
       LED1 - PE5
2. 按键
       WKUP - PA0
       KEY0 - PE4

12.1.3 原理图
本章实验使用的两个M144Z-M3最小系统板STM32F103版板载按键,分别为KEY0按键和WKUP按键,其于板载MCU的连接原理图,如下图所示:                                 
11.png
图12.1.3.1 按键与MCU的连接原理图
从上面的原理图中可以看出,WKUP按键和KEY0按键的一端连接到了电源正极,而另一端分别与MCU的PA0引脚和PE4引脚相连接,并且在上一小节的介绍中,也说明了对于该硬件设计,PA0引脚和PE4引脚应当配置为下拉,这样一来,在按键被按下的时候,PA0引脚或PE4引脚就会从原来的低电平状态变为高电平状态,在这期间就会有一个上升沿的跳变,因此可以使用该上升沿信号作为中断的触发源。

12.2 程序设计
12.2.1 HAL库的GPIO驱动
针对本章的实验要求,仅需将对应的GPIO引脚配置为下拉并且上升沿触发中断模式即可,请见第10.2.1小节中配置GPIO引脚的相关内容。
①: 配置EXTI中断
该函数用于配置NVIC(嵌套向量中断控制器)中外设的中断优先级,因此不仅能用于配置EXTI的中断,还能配置其他外设等的中断,其函数原型如下所示:
  1. void HAL_NVIC_SetPriority( IRQn_Type IRQn,
  2.                              uint32_t PreemptPriority,
  3.                              uint32_t SubPriority);
复制代码
该函数的形参描述,如下表所示:
QQ截图20240327162751.png
表12.2.1.1 函数HAL_NVIC_SetPriority()形参描述
该函数的返回值描述,如下表所示:
QQ截图20240327162745.png
表12.2.1.2 函数HAL_NVIC_SetPriority()返回值描述
该函数的使用示例,如下所示:
  1. #include"stm32f1xx_hal.h"
  2. void example_fun(void)
  3. {
  4.     /* 配置EXTI0的中断优先级 */
  5.     HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);
  6. }
复制代码
②: 使能EXTI中断
该函数用于使能NVIC(嵌套向量中断控制器)中外设的中断优先级,因此不仅能用于使能EXTI的中断,还能使能其他外设等的中断,其函数原型如下所示:
  1. void HAL_NVIC_EnableIRQ(IRQn_Type IRQn);
复制代码
该函数的形参描述,如下表所示:
QQ截图20240327162732.png
表12.2.1.3 函数HAL_NVIC_EnableIRQ()形参描述
该函数的返回值描述,如下表所示:
QQ截图20240327162724.png
表12.2.1.4 函数HAL_NVIC_EnableIRQ()返回值描述
该函数的使用示例,如下所示:
  1. #include "stm32f1xx_hal.h"
  2. void example_fun(void)
  3. {
  4.     /* 使能EXTI0中断 */
  5.     HAL_NVIC_EnableIRQ(EXTI0_IRQn);
  6. }
复制代码

12.2.2外部中断驱动
本实验的外部中断驱动主要就是配置GPIO引脚作为EINT的外部中断源,并在其对应的中断回调函数中处理按键被按下后执行的操作。
外部中断驱动中,对GPIO引脚、SYSCFG、EINT的相关定义,如下所示:
  1. #define WKUP_INT_GPIO_PORT         GPIOA
  2. #define WKUP_INT_GPIO_PIN          GPIO_PIN_0
  3. #define WKUP_INT_GPIO_CLK_ENABLE()                                     \
  4.                                      do {                                \
  5.                                          __HAL_RCC_GPIOA_CLK_ENABLE();  \
  6.                                      } while (0)
  7. #define WKUP_INT_IRQn              EXTI0_IRQn
  8. #define WKUP_INT_IRQHandler        EXTI0_IRQHandler
  9. #define KEY0_INT_GPIO_PORT         GPIOA
  10. #define KEY0_INT_GPIO_PIN          GPIO_PIN_15
  11. #define KEY0_INT_GPIO_CLK_ENABLE()                                     \
  12.                                      do {                                \
  13.                                          __HAL_RCC_GPIOA_CLK_ENABLE();  \
  14.                                      } while (0)
  15. #define KEY0_INT_IRQn              EXTI15_10_IRQn
  16. #define KEY0_INT_IRQHandler        EXTI15_10_IRQHandler
复制代码
外部中断驱动中,外部中断的初始化函数,如下所示:
  1. /**
  2. *@brief   初始化外部中断
  3. *@param   无
  4. *@retval  无
  5. */
  6. void exti_init(void)
  7. {
  8.    GPIO_InitTypeDef gpio_init_struct = {0};
  9.    
  10.     /* 使能GPIO端口时钟 */
  11.    WKUP_INT_GPIO_CLK_ENABLE();
  12.    KEY0_INT_GPIO_CLK_ENABLE();
  13.    
  14.     /* 配置WKUP控制引脚 */
  15.    gpio_init_struct.Pin = WKUP_INT_GPIO_PIN;
  16.    gpio_init_struct.Mode = GPIO_MODE_IT_RISING;
  17.    gpio_init_struct.Pull = GPIO_PULLDOWN;
  18.    gpio_init_struct.Speed = GPIO_SPEED_FREQ_LOW;
  19.    HAL_GPIO_Init(WKUP_INT_GPIO_PORT, &gpio_init_struct);
  20.    
  21.     /* 配置KEY0控制引脚 */
  22.    gpio_init_struct.Pin = KEY0_INT_GPIO_PIN;
  23.    gpio_init_struct.Mode = GPIO_MODE_IT_RISING;
  24.    gpio_init_struct.Pull = GPIO_PULLDOWN;
  25.    gpio_init_struct.Speed = GPIO_SPEED_FREQ_LOW;
  26.    HAL_GPIO_Init(KEY0_INT_GPIO_PORT, &gpio_init_struct);
  27.    
  28.     /* 配置中断优先级并使能中断 */
  29.    HAL_NVIC_SetPriority(WKUP_INT_IRQn, 0, 0);
  30.    HAL_NVIC_EnableIRQ(WKUP_INT_IRQn);
  31.    HAL_NVIC_SetPriority(KEY0_INT_IRQn, 0, 0);
  32.    HAL_NVIC_EnableIRQ(KEY0_INT_IRQn);
  33. }
复制代码
在外部中断的初始化函数中,除了使能按键对应GPIO端口的时钟,还配置了对应的EXTI中断。
在外部中断的初始化函数中,开启了两个EXTI的中断,因此需要编写这两个EXTI中断对应的中断回调函数,如下所示:
  1. /**
  2. *@brief   WKUP按键外部中断服务函数
  3. *@param   无
  4. *@retval  无
  5. */
  6. voidWKUP_INT_IRQHandler(void)
  7. {
  8.    HAL_GPIO_EXTI_IRQHandler(WKUP_INT_GPIO_PIN);
  9. }
  10. /**
  11. *@brief   KEY0按键外部中断服务函数
  12. *@param   无
  13. *@retval  无
  14. */
  15. voidKEY0_INT_IRQHandler(void)
  16. {
  17.    HAL_GPIO_EXTI_IRQHandler(KEY0_INT_GPIO_PIN);
  18. }
  19. /**
  20. *@brief   HAL库外部中断回调函数
  21. *@param   GPIO_Pin: 外部中断线对应的引脚
  22. *@retval  无
  23. */
  24. voidHAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
  25. {
  26.     /* 机械按键消抖(仅演示,切勿在实际工程的中断服务函数种进行阻塞延时) */
  27.    delay_ms(20);
  28.    
  29.     switch (GPIO_Pin)
  30.     {
  31.          case WKUP_INT_GPIO_PIN:    /* WKUP按键对应引脚发生中断 */
  32.          {
  33.              LED0_TOGGLE();          /* 翻转LED0状态 */
  34.              break;
  35.          }
  36.          case KEY0_INT_GPIO_PIN:    /* KEY0按键对应引脚发生中断 */
  37.          {
  38.              LED1_TOGGLE();          /* 翻转LED1状态 */
  39.              break;
  40.          }
  41.     }
  42. }
复制代码
在按键被按下的一瞬间,其与MCU连接的GPIO引脚会收到一个上升沿的信号,就会触发EXTI的中断,并运行对应中断回调函数。

12.2.3 实验应用代码
本章实验的应用代码,如下所示:
  1. int main(void)
  2. {
  3.    HAL_Init();                         /* 初始化HAL库 */
  4.    sys_stm32_clock_init(RCC_PLL_MUL9); /* 配置时钟,72MHz */
  5.    delay_init(72);                     /* 初始化延时 */
  6.    usart_init(115200);                 /* 初始化串口 */
  7.    led_init();                         /* 初始化LED */
  8.    exti_init();                        /* 初始化外部中断 */
  9.    
  10.     while (1)
  11.     {
  12.          
  13.     }
  14. }
复制代码
本实验的应用代码很简单,在初始化完LED和外部表中断后,就进入一个什么都不做的while循环,这是因为按键控制LED亮灭状态翻转的操作都在对应EXTI的中断回调函数中完成了。

12.3 下载验证
在完成编译和烧录操作后,可以看到板子上的LED0和LED1默认是处于熄灭的状态,若此时按下WKUP按键,则能够看到LED0的亮灭状态发生了一次翻转,同样的,若此时按下KEY0按键,则能够看LED1的亮灭状态发生了一次翻转,与预期的实验现象效果相符。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 05:27

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表