普冉(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

相关文章

基于Python开发Windows屏幕控制工具

《基于Python开发Windows屏幕控制工具》在数字化办公时代,屏幕管理已成为提升工作效率和保护眼睛健康的重要环节,本文将分享一个基于Python和PySide6开发的Windows屏幕控制工具,... 目录概述功能亮点界面展示实现步骤详解1. 环境准备2. 亮度控制模块3. 息屏功能实现4. 息屏时间

SpringMVC高效获取JavaBean对象指南

《SpringMVC高效获取JavaBean对象指南》SpringMVC通过数据绑定自动将请求参数映射到JavaBean,支持表单、URL及JSON数据,需用@ModelAttribute、@Requ... 目录Spring MVC 获取 JavaBean 对象指南核心机制:数据绑定实现步骤1. 定义 Ja

C++中RAII资源获取即初始化

《C++中RAII资源获取即初始化》RAII通过构造/析构自动管理资源生命周期,确保安全释放,本文就来介绍一下C++中的RAII技术及其应用,具有一定的参考价值,感兴趣的可以了解一下... 目录一、核心原理与机制二、标准库中的RAII实现三、自定义RAII类设计原则四、常见应用场景1. 内存管理2. 文件操

Python实例题之pygame开发打飞机游戏实例代码

《Python实例题之pygame开发打飞机游戏实例代码》对于python的学习者,能够写出一个飞机大战的程序代码,是不是感觉到非常的开心,:本文主要介绍Python实例题之pygame开发打飞机... 目录题目pygame-aircraft-game使用 Pygame 开发的打飞机游戏脚本代码解释初始化部

使用Python开发一个现代化屏幕取色器

《使用Python开发一个现代化屏幕取色器》在UI设计、网页开发等场景中,颜色拾取是高频需求,:本文主要介绍如何使用Python开发一个现代化屏幕取色器,有需要的小伙伴可以参考一下... 目录一、项目概述二、核心功能解析2.1 实时颜色追踪2.2 智能颜色显示三、效果展示四、实现步骤详解4.1 环境配置4.

SpringBoot服务获取Pod当前IP的两种方案

《SpringBoot服务获取Pod当前IP的两种方案》在Kubernetes集群中,SpringBoot服务获取Pod当前IP的方案主要有两种,通过环境变量注入或通过Java代码动态获取网络接口IP... 目录方案一:通过 Kubernetes Downward API 注入环境变量原理步骤方案二:通过

Python使用smtplib库开发一个邮件自动发送工具

《Python使用smtplib库开发一个邮件自动发送工具》在现代软件开发中,自动化邮件发送是一个非常实用的功能,无论是系统通知、营销邮件、还是日常工作报告,Python的smtplib库都能帮助我们... 目录代码实现与知识点解析1. 导入必要的库2. 配置邮件服务器参数3. 创建邮件发送类4. 实现邮件

使用Python实现获取屏幕像素颜色值

《使用Python实现获取屏幕像素颜色值》这篇文章主要为大家详细介绍了如何使用Python实现获取屏幕像素颜色值,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 一、一个小工具,按住F10键,颜色值会跟着显示。完整代码import tkinter as tkimport pyau

Java -jar命令如何运行外部依赖JAR包

《Java-jar命令如何运行外部依赖JAR包》在Java应用部署中,java-jar命令是启动可执行JAR包的标准方式,但当应用需要依赖外部JAR文件时,直接使用java-jar会面临类加载困... 目录引言:外部依赖JAR的必要性一、问题本质:类加载机制的限制1. Java -jar的默认行为2. 类加

python获取cmd环境变量值的实现代码

《python获取cmd环境变量值的实现代码》:本文主要介绍在Python中获取命令行(cmd)环境变量的值,可以使用标准库中的os模块,需要的朋友可以参考下... 前言全局说明在执行py过程中,总要使用到系统环境变量一、说明1.1 环境:Windows 11 家庭版 24H2 26100.4061