HPM6750开发笔记《GPIO例程深度解析》

目录

创建工程:

代码分析:

1.头文件包含:

2.宏定义:

3.中断服务程序(ISR):

清除中断标志:

处理 LED 状态切换:

处理用户按键状态:

处理其他情况:

4.void test_gpio_input_interrupt(void):

打印提示信息:

初始化 LED GPIO:

配置 GPIO 引脚为输入模式:

配置中断触发类型:

启用 GPIO 中断:

设置中断优先级:

进入低功耗模式:

5.void test_gpio_toggle_output(void):

打印提示信息:

初始化 LED GPIO:

循环切换 LED 状态:

打印测试完成信息:

6.int main(void)

初始化板级硬件:

测试 GPIO 输出状态切换:

测试 GPIO 输入中断:

进入无限循环:

运行现象:


创建工程:

首先还是在HPM SDK里面创建工程选项如下图:


代码分析:

/** Copyright (c) 2021 HPMicro** SPDX-License-Identifier: BSD-3-Clause**/#include "board.h"
#include "hpm_gpio_drv.h"#define GPIO_TOGGLE_COUNT 5void isr_gpio(void)
{gpio_clear_pin_interrupt_flag(BOARD_APP_GPIO_CTRL, BOARD_APP_GPIO_INDEX,BOARD_APP_GPIO_PIN);
#ifdef BOARD_LED_GPIO_CTRLgpio_toggle_pin(BOARD_LED_GPIO_CTRL, BOARD_LED_GPIO_INDEX,BOARD_LED_GPIO_PIN);printf("toggle led pin output\n");
#else
#if defined(GPIO_SOC_HAS_EDGE_BOTH_INTERRUPT) && (GPIO_SOC_HAS_EDGE_BOTH_INTERRUPT == 1)if (gpio_read_pin(BOARD_APP_GPIO_CTRL, BOARD_APP_GPIO_INDEX, BOARD_APP_GPIO_PIN) == false) {printf("user key pressed\n");} else {printf("user key released\n");}
#elseprintf("user key pressed\n");
#endif
#endif}
SDK_DECLARE_EXT_ISR_M(BOARD_APP_GPIO_IRQ, isr_gpio)void test_gpio_input_interrupt(void)
{gpio_interrupt_trigger_t trigger;printf("input interrupt\n");
#ifdef BOARD_LED_GPIO_CTRLprintf("user led will be switched on off based on user switch\n");gpio_set_pin_output(BOARD_LED_GPIO_CTRL, BOARD_LED_GPIO_INDEX,BOARD_LED_GPIO_PIN);
#endifgpio_set_pin_input(BOARD_APP_GPIO_CTRL, BOARD_APP_GPIO_INDEX,BOARD_APP_GPIO_PIN);
#if defined(GPIO_SOC_HAS_EDGE_BOTH_INTERRUPT) && (GPIO_SOC_HAS_EDGE_BOTH_INTERRUPT == 1)trigger = gpio_interrupt_trigger_edge_both;
#elsetrigger = gpio_interrupt_trigger_edge_falling;
#endifgpio_config_pin_interrupt(BOARD_APP_GPIO_CTRL, BOARD_APP_GPIO_INDEX,BOARD_APP_GPIO_PIN, trigger);gpio_enable_pin_interrupt(BOARD_APP_GPIO_CTRL, BOARD_APP_GPIO_INDEX,BOARD_APP_GPIO_PIN);intc_m_enable_irq_with_priority(BOARD_APP_GPIO_IRQ, 1);while (1) {__asm("wfi");}
}#ifdef BOARD_LED_GPIO_CTRL
void test_gpio_toggle_output(void)
{printf("toggling led %u times in total\n", GPIO_TOGGLE_COUNT);gpio_set_pin_output(BOARD_LED_GPIO_CTRL, BOARD_LED_GPIO_INDEX,BOARD_LED_GPIO_PIN);gpio_write_pin(BOARD_LED_GPIO_CTRL, BOARD_LED_GPIO_INDEX,BOARD_LED_GPIO_PIN, board_get_led_gpio_off_level());for (uint32_t i = 0; i < GPIO_TOGGLE_COUNT; i++) {gpio_toggle_pin(BOARD_LED_GPIO_CTRL, BOARD_LED_GPIO_INDEX,BOARD_LED_GPIO_PIN);board_delay_ms(500);gpio_toggle_pin(BOARD_LED_GPIO_CTRL, BOARD_LED_GPIO_INDEX,BOARD_LED_GPIO_PIN);board_delay_ms(500);printf("toggling led %u/%u times\n", i + 1, GPIO_TOGGLE_COUNT);}
}
#endifint main(void)
{board_init();board_init_gpio_pins();printf("gpio \n");#ifdef BOARD_LED_GPIO_CTRLtest_gpio_toggle_output();
#endiftest_gpio_input_interrupt();while (1);return 0;
}

1.头文件包含:
#include "board.h"
#include "hpm_gpio_drv.h"

这里包含了与嵌入式系统板级支持和GPIO驱动相关的头文件。


2.宏定义:
#define GPIO_TOGGLE_COUNT 5

这个宏定义表示在测试中要切换LED状态的次数。


3.中断服务程序(ISR):
void isr_gpio(void) {// 处理GPIO中断
}
SDK_DECLARE_EXT_ISR_M(BOARD_APP_GPIO_IRQ, isr_gpio)

这定义了一个GPIO中断服务程序(ISR),当GPIO中断发生时执行。在中断服务程序中,通过 gpio_clear_pin_interrupt_flag 函数清除中断标志,然后根据硬件配置,切换LED状态或输出用户按键的状态。

清除中断标志
gpio_clear_pin_interrupt_flag(BOARD_APP_GPIO_CTRL, BOARD_APP_GPIO_INDEX, BOARD_APP_GPIO_PIN);
处理 LED 状态切换:
#ifdef BOARD_LED_GPIO_CTRL
gpio_toggle_pin(BOARD_LED_GPIO_CTRL, BOARD_LED_GPIO_INDEX, BOARD_LED_GPIO_PIN);
printf("toggle led pin output\n");
处理用户按键状态:
#if defined(GPIO_SOC_HAS_EDGE_BOTH_INTERRUPT) && (GPIO_SOC_HAS_EDGE_BOTH_INTERRUPT == 1)
if (gpio_read_pin(BOARD_APP_GPIO_CTRL, BOARD_APP_GPIO_INDEX, BOARD_APP_GPIO_PIN) == false) {printf("user key pressed\n");
} else {printf("user key released\n");
}

如果硬件支持双边沿触发的中断(GPIO_SOC_HAS_EDGE_BOTH_INTERRUPT 宏被定义且等于 1),则通过 gpio_read_pin 函数检查用户按键的状态。如果按键被按下,则打印 "user key pressed";如果按键被释放,则打印 "user key released"。

处理其他情况:
#else
printf("user key pressed\n");
#endif

如果没有硬件支持双边沿触发的中断,直接打印 "user key pressed"。


4.void test_gpio_input_interrupt(void):
void test_gpio_input_interrupt(void) {// 测试GPIO输入中断
}
打印提示信息
printf("input interrupt\n");

打印一条提示消息,指示该函数用于测试 GPIO 的输入中断功能。

初始化 LED GPIO
#ifdef BOARD_LED_GPIO_CTRL
printf("user led will be switched on off based on user switch\n");
gpio_set_pin_output(BOARD_LED_GPIO_CTRL, BOARD_LED_GPIO_INDEX, BOARD_LED_GPIO_PIN);
#endif

定义了 BOARD_LED_GPIO_CTRL 宏,表示存在 LED 的 GPIO 控制器,那么打印一条消息提示 LED 的状态将会根据用户开关的状态进行切换,并通过 gpio_set_pin_output 函数将 LED 的 GPIO 引脚设置为输出模式。

配置 GPIO 引脚为输入模式
gpio_set_pin_input(BOARD_APP_GPIO_CTRL, BOARD_APP_GPIO_INDEX, BOARD_APP_GPIO_PIN);

通过调用 gpio_set_pin_input 函数将指定的 GPIO 引脚配置为输入模式。

配置中断触发类型
#if defined(GPIO_SOC_HAS_EDGE_BOTH_INTERRUPT) && (GPIO_SOC_HAS_EDGE_BOTH_INTERRUPT == 1)
trigger = gpio_interrupt_trigger_edge_both;
#else
trigger = gpio_interrupt_trigger_edge_falling;
#endif
gpio_config_pin_interrupt(BOARD_APP_GPIO_CTRL, BOARD_APP_GPIO_INDEX, BOARD_APP_GPIO_PIN, trigger);

根据硬件支持的中断触发类型,配置 GPIO 引脚的中断触发类型。如果支持双边沿触发中断,则设置 triggergpio_interrupt_trigger_edge_both,否则设置为 gpio_interrupt_trigger_edge_falling

启用 GPIO 中断
gpio_enable_pin_interrupt(BOARD_APP_GPIO_CTRL, BOARD_APP_GPIO_INDEX, BOARD_APP_GPIO_PIN);

通过调用 gpio_enable_pin_interrupt 函数启用 GPIO 引脚的中断。

设置中断优先级
intc_m_enable_irq_with_priority(BOARD_APP_GPIO_IRQ, 1);

通过调用 intc_m_enable_irq_with_priority 函数,设置与 GPIO 中断相关的中断优先级。

进入低功耗模式
while (1) {__asm("wfi");
}

进入一个无限循环,并在循环中调用 __asm("wfi"); 进入等待中断(WFI)指令,使处理器进入低功耗模式,等待 GPIO 中断的发生。

在这个测试函数中,主要目的是配置和启用 GPIO 的输入中断,并在进入低功耗模式后等待中断的发生。当 GPIO 中断触发时,与中断相关的处理函数 isr_gpio 将被调用。这个测试函数用于验证嵌入式系统中 GPIO 输入中断的正常工作。


5.void test_gpio_toggle_output(void):
打印提示信息
printf("toggling led %u times in total\n", GPIO_TOGGLE_COUNT);

打印一条消息,指示该函数将会切换 LED 总共 GPIO_TOGGLE_COUNT 次。

初始化 LED GPIO
gpio_set_pin_output(BOARD_LED_GPIO_CTRL, BOARD_LED_GPIO_INDEX, BOARD_LED_GPIO_PIN);
gpio_write_pin(BOARD_LED_GPIO_CTRL, BOARD_LED_GPIO_INDEX, BOARD_LED_GPIO_PIN, board_get_led_gpio_off_level());

使用 gpio_set_pin_output 函数将 LED 的 GPIO 引脚设置为输出模式,并使用 gpio_write_pin 函数设置 LED 的初始状态,根据板级支持的函

printf("toggling led test completed\n");

board_get_led_gpio_off_level 来确定 LED 的初始状态。

循环切换 LED 状态
for (uint32_t i = 0; i < GPIO_TOGGLE_COUNT; i++) {gpio_toggle_pin(BOARD_LED_GPIO_CTRL, BOARD_LED_GPIO_INDEX, BOARD_LED_GPIO_PIN);board_delay_ms(500);gpio_toggle_pin(BOARD_LED_GPIO_CTRL, BOARD_LED_GPIO_INDEX, BOARD_LED_GPIO_PIN);board_delay_ms(500);printf("toggling led %u/%u times\n", i + 1, GPIO_TOGGLE_COUNT);
}

在一个循环中,使用 gpio_toggle_pin 函数切换 LED 的输出状态,然后通过 board_delay_ms 函数延迟 500 毫秒,再次切换状态,以模拟 LED 的开关操作。在每次切换之后,打印一条消息,显示切换的次数。

打印测试完成信息
printf("toggling led test completed\n");

总体而言,test_gpio_toggle_output 函数用于测试嵌入式系统中 GPIO 输出状态切换的功能。通过在循环中切换 LED 的状态,它模拟了 LED 的开关操作,并通过打印相关信息,显示切换的次数和测试完成的消息。


6.int main(void)

int main(void) 函数是嵌入式系统中的主函数,它是程序的入口点。以下是 main 函数的主要步骤的解释:

初始化板级硬件
board_init();
board_init_gpio_pins();

调用 board_init 函数和 board_init_gpio_pins 函数,用于初始化板级硬件,包括系统时钟、GPIO 等。

测试 GPIO 输出状态切换:
#ifdef BOARD_LED_GPIO_CTRL
test_gpio_toggle_output();
#endif

定义了 BOARD_LED_GPIO_CTRL 宏,表示存在 LED 的 GPIO 控制器,那么调用 test_gpio_toggle_output 函数,测试 GPIO 输出状态切换功能。

测试 GPIO 输入中断

调用 test_gpio_input_interrupt 函数,测试 GPIO 输入中断功能。

进入无限循环

main 函数的主要作用是初始化嵌入式系统的硬件环境,然后进行 GPIO 功能的测试。具体测试的内容包括 GPIO 输出状态切换和 GPIO 输入中断。在这个例子中,通过宏的定义来判断是否存在 LED 的 GPIO 控制器,以确定是否执行 GPIO 输出状态切换的测试。无论是否进行 GPIO 输出状态切换测试,都会执行 GPIO 输入中断的测试。程序最终进入一个无限循环,保持运行状态。


运行现象:

  • 支持双沿触发模式的芯片,工程配置的是双沿触发模式,每次按键按下和释放都会翻转一次LED状态,并打印两次LED切换输出。

  • 当工程正确运行后,可以观察到LED闪烁5次,之后按下GPIO按键(请确认具体开发板 按键 部分描述)可以翻转LED的状态,串口终端会输出如下信息:

toggling led 5 times in total
toggling led 1/5 times
toggling led 2/5 times
toggling led 3/5 times
toggling led 4/5 times
toggling led 5/5 times
input interrupt
user led will be switched on off based on user switch
toggle led pin output
toggle led pin output

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/316237.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WPF+Halcon 培训项目实战(11):HS组件封装

文章目录 前言相关链接项目专栏运行环境匹配图片封装组件新增类库项目选择依赖顺序并添加Nuget修改原本矩形方法运行结果&#xff1a; 对矩形进行抽象封装抽象基类矩形抽象改造 圆形抽象封装代码运行结果 前言 为了更好地去学习WPFHalcon&#xff0c;我决定去报个班学一下。原…

基于Rangenet Lib的自动驾驶LiDAR点云语义分割与可视化

这段代码是一个C程序&#xff0c;用于处理来自KITTI数据集的激光雷达&#xff08;LiDAR&#xff09;扫描数据。程序主要实现以下功能&#xff1a; 1. **读取和解析命令行参数**&#xff1a;使用Boost库中的program_options模块来定义和解析命令行参数。这包括扫描文件路径、模型…

计算机毕业设计 基于SSM的果蔬作物疾病防治系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

第二十七章 正则表达式

第二十七章 正则表达式 1.正则快速入门2.正则需求问题3.正则底层实现14.正则底层实现25.正则底层实现36.正则转义符7.正则字符匹配8.字符匹配案例19.字符匹配案例211.选择匹配符&#xff08;|&#xff09;12.正则限定符{n}{n,m}&#xff08;1个或者多个&#xff09;*(0个或者多…

介绍两本书《助推》与《耐力》

冠历最后一年已经养成了没有冲突的情况下每天跑步、读书的习惯&#xff0c;今天突发奇想&#xff1a;是否重新挑战下每日写作。 ​ 今天介绍两本书。第一本是《助推》&#xff0c;这本书是由于真友 吾真本 的介绍开始读的。 一句话介绍这本书&#xff0c;那就是&#xff1a;如果…

Hive08_分区表

一 分区表 1 概念&#xff1a; 分区表实际上就是对应一个 HDFS 文件系统上的独立的文件夹&#xff0c;该文件夹下是该分区所 有的数据文件。Hive 中的分区就是分目录&#xff0c;把一个大的数据集根据业务需要分割成小的数据 集。在查询时通过 WHERE 子句中的表达式选择查询…

机器人制作开源方案 | 多地形适应野外探索智能车

1. 作品基本介绍 如今&#xff0c;智能机器人在军事、制造业、交通运输、航天航空、医疗、服务等领域已有广泛的应用&#xff0c;智能车是机器人研究领域的一项重要基础内容&#xff0c;在各种移动机构中&#xff0c;最为常见的是轮式移动方式&#xff0c;当今社会正处于科技高…

Linux 断言的使用

断言为我们提供了一种可以静态或动态地检查程序在目标平台上整体状态的能力&#xff0c;与它相关的接口由头文件 assert.h 提供

霹雳吧啦Wz《pytorch图像分类》-p4GoogLeNet网络

《pytorch图像分类》p4GoogLeNet网络详解 一、GoogLeNet网络中的亮点1.inception结构2.使用11的卷积核进行降维及映射处理3.GoogLeNet辅助分类器4.模型参数 二、模块代码1.BasicConv2d2.Inception 三、课程代码1.module.py2.train.py3.predict.py 一、GoogLeNet网络中的亮点 论…

ES(Elasticsearch)的基本使用

一、常见的NoSQL解决方案 1、redis加粗样式 Redis是一个基于内存的 key-value 结构数据库。Redis是一款采用key-value数据存储格式的内存级NoSQL数据库&#xff0c;重点关注数据存储格式&#xff0c;是key-value格式&#xff0c;也就是键值对的存储形式。与MySQL数据库不同&a…

助力成长的开源项目 —— 筑梦之路

闯关式 SQL 自学&#xff1a;sql-mother 免费的闯关式 SQL 自学教程网站&#xff0c;从 0 到 1 带大家掌握常用 SQL 语法&#xff0c;目前一共有 30 多个关卡&#xff0c;希望你在通关的时候&#xff0c;变身为一个 SQL 高手。除了闯关模式之外&#xff0c;这个项目支持自由选…

剑指 Offer(第2版)面试题 68:树中两个结点的最低公共祖先

剑指 Offer&#xff08;第2版&#xff09;面试题 68&#xff1a;树中两个结点的最低公共祖先 剑指 Offer&#xff08;第2版&#xff09;面试题 68&#xff1a;树中两个结点的最低公共祖先解法1&#xff1a;递归拓展题&#xff1a;二叉搜索树的最近公共祖先解法1&#xff1a;两次…