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

2024-01-02 20:24:10

目录

创建工程:

代码分析:

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 5

void isr_gpio(void)
{
    gpio_clear_pin_interrupt_flag(BOARD_APP_GPIO_CTRL, BOARD_APP_GPIO_INDEX,
                        BOARD_APP_GPIO_PIN);
#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");
#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");
    }
#else
    printf("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_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
    gpio_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;
#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_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);
    }
}
#endif

int main(void)
{
    board_init();
    board_init_gpio_pins();
    printf("gpio \n");

#ifdef BOARD_LED_GPIO_CTRL
    test_gpio_toggle_output();
#endif
    test_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

文章来源:https://blog.csdn.net/weixin_50932441/article/details/135342634
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。