普冉(PUYA)单片机开发笔记(12): 获取外部中断

2023-12-17 17:44

本文主要是介绍普冉(PUYA)单片机开发笔记(12): 获取外部中断,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

概述

将单片机的 GPIO 引脚作为外部按键的输入端是单片机较为常用的方式,例如把这颗 MCU 部署在一块控制面板的触点底板,使用者按压按钮(按键)对产品进行控制。本着学以致用的原则,使用 PY32F003 对外部中断如何处理是一项必须完成的学习内容了。今天我们就来操练一把。

参考厂家的例程,使用 PA12 作为外部中断的输入管脚,掌握一下 PY32F003 对外部中断处理的代码。PA12 设置为突变检测,当 PA12 上产生高低电平的变化时,翻转一次板载 LED 可以验证 MCU 是否正确捕捉了外部中断。

在我的这一个系列的实验,Keil 的文件组织都是沿用下来的,请参见我的任意一期《开发笔记》,这里就不罗嗦了,直接上代码。

实现代码

1. 在 main.h 中加一个预定义,然后定义和外部中断相关的函数原型

代码片段如下。

#define TIM_PWM_TEST    0
#define ADC_SAMPLE_TEST 0
#define FLASH_WR_TEST   0
#define I2C_COMM_TEST   0
#define I2C_SLAVE       0
#define EXTI_TEST       1...
...#if(EXTI_TEST)
void EXTI_Config(void);
void EXTI_Demo(void);
#endif...
...

文件新定义了预编译开关: EXTI_TEST,其它的开关全部设置为 0(关掉其它功能,免得产生冲突)。然后声明了 Config 和 Demo 两个函数。

2. app_exti.c 中实现相关函数

这一次我们将获取外部中断的相关函数都写到 app_exti.c 这一个文件中,包括 main.h 中预定义的 EXTI_Config() 函数,HAL_EXTI_MspInit() 函数和 EXTI4_15_IRQHandler() 函数,酱紫就不需要再“麻烦” 去修改 py32_f0xx_hal_msp.c 文件了。

完整代码如下。

/********************************************************************************* @file    app_exti.c* @brief   External Interrupt test functions.******************************************************************************* @copyright** Copyright (c) 2023 CuteModem Intelligence.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/#include "main.h"#if(EXTI_TEST)
/** ----------------------------------------------------------------------------
* @name   : void EXTI_Config(void)
* @brief  : EXTI 初始化, 配置引脚 PA12 为下降沿中断
* @param  : 
* @retval : void
* @remark : 
*** ----------------------------------------------------------------------------
*/
void EXTI_Config(void)
{GPIO_InitTypeDef  GPIO_InitStruct;__HAL_RCC_GPIOA_CLK_ENABLE();                  // 使能GPIOA时钟GPIO_InitStruct.Mode  = GPIO_MODE_IT_FALLING;  // 下降沿中断GPIO_InitStruct.Pull  = GPIO_PULLUP;           // 上拉GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;  // 速度为高速GPIO_InitStruct.Pin   = GPIO_PIN_12;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);             // 使能EXTI中断HAL_NVIC_SetPriority(EXTI4_15_IRQn, 0, 0);     // 配置中断优先级
}/** ----------------------------------------------------------------------------
* @name   : void EXTI4_15_IRQHandler(void)
* @brief  : EXTI 初始化, 配置事件引脚 PA12
* @param  : 每产生一次下降沿, LED翻转一次
* @retval : void
* @remark : 
*** ----------------------------------------------------------------------------
*/
void EXTI4_15_IRQHandler(void)
{BSP_LED_Toggle(LED3);HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12);//处理EXTI中断请求
}/** ----------------------------------------------------------------------------
* @name   : void EXTI_Demo(void);
* @brief  : 由 main() 调用的外部中断实验程序
* @param  : 
* @retval : void
* @remark : 
*** ----------------------------------------------------------------------------
*/
void EXTI_Demo(void)
{EXTI_Config();
}#endif
  • 使用 EXTI_Config() 函数分配 PA12 为外部中断源,内部上拉,下降沿中断,GPIO 高速。
  • 使用 EXTI4_15 中断,设置成 0 组最高优先级。
  • 在 EXT4_15中断服务程序中,翻转板载 LED 一次,然后调用 HAL_GPIO_EXTI_IRQHandler(GPIO_Pinx) 函数清除这个 GPIO 的中断标志,以便下一次捕获。
  • 定义了一个非常简单的 Demo 函数。

3. 修改一下 py32_f0xx_hal_it.c

已经在 app_exti.c 中实现了 EXTI_15_IRQ4_Handler,所以在 py32_f0xx_hal_it.c 中把那个函数关掉。

请注意这里不能重复定义其为 __weak 类型,这么做不会导致编译错误,但程序运行时会卡死。

/********************************************************************************* @file    py32f0xx_it.c* @author  MCU Application Team* @Version V1.0.0* @Date    2020-10-19* @brief   Interrupt Service Routines.*******************************************************************************/...
...#if(!EXTI_TEST)
void EXTI4_15_IRQHandler(void)
{
}
#endif...
...

4. 在 main() 函数中调用

/********************************************************************************* @file    main.c* @brief   Main program entry.******************************************************************************...
...********************************************************************************/#include "main.h"
#include <stdio.h>/**
* -------------------------------------------------------------------------
* @file   : int main(void)
* @brief  : main函数
* @param  : 无
* @retval : 无限循环,无返回值
* @remark : 
* -------------------------------------------------------------------------
*/
int main(void)
{HAL_Init();             // systick初始化SystemClock_Config();   // 配置系统时钟if(USART_Config() != HAL_OK) Error_Handler();         printf("\r\n\r\n\r\n""[SYS_INIT] Debug port initilaized.\r\n");printf("\r\n+---------------------------------------+""\r\n|        PY32F003 MCU is ready.         |""\r\n+---------------------------------------+""\r\n         10 digits sent to you!          ""\r\n+---------------------------------------+""\r\n");HAL_Delay(0);if (DBG_UART_Start() != HAL_OK) Error_Handler();HAL_Delay(0);#if(EXTI_TEST)EXTI_Config();
#endifwhile (1){ 
#if(!EXTI_TEST)BSP_LED_Toggle(LED3);HAL_Delay(500);
#endif}
}

程序很短,如果不考虑打印的话,只需要 HAL_Init(); SystemClock_Config(); 和 EXTI_Config(); 三个函数。主循环用 #if(!EXTI_TEST)关掉了,实际上是空的。

实验结果

编译烧录后,使用一根杜邦线连接 PA12 引脚,杜邦线的另一头接上 GND,反复插拔,观察板载 LED 的明灭。可以发现板载 LED 随着杜邦线的插拔一明一灭,说明实验是成功了的。

总结

  • 使用 PY32F003 的外部中断功能的配置很简单。
  • 如果使用 GPIO 的高速模式,对捕获外部中断有好处,但要避免插拔抖动造成的多次触发。实测使用 GPIO_SPEED_FREQ_VERY_HIGH 时,一次接触会产生 LED 的多次明灭;使用 GPIO_SPEED_FREQ_MEDIUM 时,好像又有点丢失的感觉。在实用设计中,在使用 HIGH 或者 VERY_HIGH 的同时,应该加一套时间常数较为合适的 RC 低通电路用于防抖。

本实验只是完成了一个管脚作为外部中断源的捕获,如果有多个的话,想来可能大同小异吧,毕竟芯片的 NVIC 构架是相同的。

谬误之处,欢迎在评论区讨论指正。

这篇关于普冉(PUYA)单片机开发笔记(12): 获取外部中断的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/505264

相关文章

Spring Boot集成/输出/日志级别控制/持久化开发实践

《SpringBoot集成/输出/日志级别控制/持久化开发实践》SpringBoot默认集成Logback,支持灵活日志级别配置(INFO/DEBUG等),输出包含时间戳、级别、类名等信息,并可通过... 目录一、日志概述1.1、Spring Boot日志简介1.2、日志框架与默认配置1.3、日志的核心作用

PyQt5 GUI 开发的基础知识

《PyQt5GUI开发的基础知识》Qt是一个跨平台的C++图形用户界面开发框架,支持GUI和非GUI程序开发,本文介绍了使用PyQt5进行界面开发的基础知识,包括创建简单窗口、常用控件、窗口属性设... 目录简介第一个PyQt程序最常用的三个功能模块控件QPushButton(按钮)控件QLable(纯文本

Python获取浏览器Cookies的四种方式小结

《Python获取浏览器Cookies的四种方式小结》在进行Web应用程序测试和开发时,获取浏览器Cookies是一项重要任务,本文我们介绍四种用Python获取浏览器Cookies的方式,具有一定的... 目录什么是 Cookie?1.使用Selenium库获取浏览器Cookies2.使用浏览器开发者工具

Java获取当前时间String类型和Date类型方式

《Java获取当前时间String类型和Date类型方式》:本文主要介绍Java获取当前时间String类型和Date类型方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录Java获取当前时间String和Date类型String类型和Date类型输出结果总结Java获取

C#监听txt文档获取新数据方式

《C#监听txt文档获取新数据方式》文章介绍通过监听txt文件获取最新数据,并实现开机自启动、禁用窗口关闭按钮、阻止Ctrl+C中断及防止程序退出等功能,代码整合于主函数中,供参考学习... 目录前言一、监听txt文档增加数据二、其他功能1. 设置开机自启动2. 禁止控制台窗口关闭按钮3. 阻止Ctrl +

基于Python开发一个图像水印批量添加工具

《基于Python开发一个图像水印批量添加工具》在当今数字化内容爆炸式增长的时代,图像版权保护已成为创作者和企业的核心需求,本方案将详细介绍一个基于PythonPIL库的工业级图像水印解决方案,有需要... 目录一、系统架构设计1.1 整体处理流程1.2 类结构设计(扩展版本)二、核心算法深入解析2.1 自

一文详解如何使用Java获取PDF页面信息

《一文详解如何使用Java获取PDF页面信息》了解PDF页面属性是我们在处理文档、内容提取、打印设置或页面重组等任务时不可或缺的一环,下面我们就来看看如何使用Java语言获取这些信息吧... 目录引言一、安装和引入PDF处理库引入依赖二、获取 PDF 页数三、获取页面尺寸(宽高)四、获取页面旋转角度五、判断

Python使用OpenCV实现获取视频时长的小工具

《Python使用OpenCV实现获取视频时长的小工具》在处理视频数据时,获取视频的时长是一项常见且基础的需求,本文将详细介绍如何使用Python和OpenCV获取视频时长,并对每一行代码进行深入解析... 目录一、代码实现二、代码解析1. 导入 OpenCV 库2. 定义获取视频时长的函数3. 打开视频文

MySQL 获取字符串长度及注意事项

《MySQL获取字符串长度及注意事项》本文通过实例代码给大家介绍MySQL获取字符串长度及注意事项,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql 获取字符串长度详解 核心长度函数对比⚠️ 六大关键注意事项1. 字符编码决定字节长度2

SpringBoot开发中十大常见陷阱深度解析与避坑指南

《SpringBoot开发中十大常见陷阱深度解析与避坑指南》在SpringBoot的开发过程中,即使是经验丰富的开发者也难免会遇到各种棘手的问题,本文将针对SpringBoot开发中十大常见的“坑... 目录引言一、配置总出错?是不是同时用了.properties和.yml?二、换个位置配置就失效?搞清楚加