当前位置: 首页 > news >正文

【星闪】Hi2821 | Pinctrl、GPIO + LED灯和按键输入例程

1. 简介

1.1 硬件特性

  • 芯片有 32 IO 口,每个都可以配置为 GPIO 口模式;
  • GPIO 作为输入管脚时,可作为中断源,低功耗场景下,中断源可以配置为任一 GPIO 口;
  • 每个 GPIO 都可独立使能上下拉和驱动等级,驱动等级有 4 档, 覆盖1~18mA,上下拉电阻阻值范围在 80k~100k;
  • 芯片冷复位时,所有的 GPIO 为高阻态;
  • GPIO11~GPIO24 参考电压跟随 VDDIO1,其余 IO 参考电压跟随 VBAT(VDD1/VDD2)。

1.2 Pinctrl

        Pinctrl 主要配置IO驱动能力、IO功能复用以及设置IO上下拉状态等功能。部分函数接口如下:

  • uapi_pin_init(void):初始化Pinctrl。
  • uapi_pin_deinit(void):去初始化Pinctrl。
  • uapi_pin_set_mode(pin_t pin, pin_mode_t mode):设置指定IO复用模式(pin表示当前IO管脚,mode表示当前引脚需要配置的复用模式)。
  • uapi_pin_get_mode(pin_t pin):获取指定IO的复用模式(pin表示当前IO管脚)。
  • uapi_pin_set_ds(pin_t pin, pin_drive_strength_t ds):设置指定IO驱动能力(pin表示当前IO管脚,ds表示当前引脚需要配置的驱动能力)。
  • uapi_pin_get_ds(pin_t pin):获取指定IO驱动能力(pin表示当前IO管脚)。
  • uapi_pin_set_pull(pin_t pin, pin_pull_t pull_type):设置指定IO的上拉/下拉状态(pin表示当前IO管脚,pull_type表示当前引脚需要配置的上下拉状态)。
  • uapi_pin_get_pull(pin_t pin):获取指定IO的上拉/下拉状态(pin表示当前IO管脚)。
  • uapi_pin_set_ie(pin_t pin,pin_input_enable_t ie):设置指定IO的IE使能/去使能(pin表示当前IO管脚,ie表示当前引脚需要配置的输入中断使能状态)。
  • uapi_pin_get_ie(pin_t pin):获取指定IO的IE使能/去使能(pin表示当前IO管脚)。

1.3 GPIO

        GPIO 主要设置/获取GPIO管脚方向、设置/获取输出电平状态、设置管脚中断。部分函数接口如下:

  • uapi_gpio_init(void):初始化GPIO。
  • uapi_gpio_deinit(void):去初始化GPIO。
  • uapi_gpio_set_dir(pin_t pin, gpio_direction_t dir):设置指定GPIO方向(输入/输出)(pin表示当前IO管脚,dir表示当前引脚需要配置的输入输出方向)。
  • uapi_gpio_get_dir(pin_t pin):获取指定GPIO方向(输入/输出)(pin表示当前IO管脚)。
  • uapi_gpio_set_val(pin_t pin, gpio_level_t level):设置指定GPIO输出电平状态(pin表示当前IO管脚,level表示当前引脚需要配置的电平状态)。
  • uapi_gpio_get_val(pin_t pin):获取指定GPIO的输入电平状态(pin表示当前IO管脚)。
  • uapi_gpio_get_output_val(pin_t pin):获取指定GPIO的输出电平状态(pin表示当前IO管脚)。
  • uapi_gpio_toggle(pin_t pin):GPIO输出电平状态翻转(pin表示当前IO管脚)。
  • uapi_gpio_register_isr_func(pin_t pin, uint32_t trigger, gpio_callback_t callback):注册指定GPIO中断(pin表示当前IO管脚,trigger表示当前引脚需要配置的中断类型,callback表示当前引脚配置的回调函数)。
  • uapi_gpio_unregister_isr_func(pin_t pin):去注册指定GPIO中断(pin表示当前IO管脚)。
  • uapi_gpio_enable_interrupt(pin_t pin):使能GPIO中断(pin表示当前IO管脚)。
  • uapi_gpio_disable_interrupt(pin_t pin): 关闭GPIO中断(pin表示当前IO管脚)。
  • uapi_gpio_clear_interrupt(pin_t pin):清除GPIO中断(pin表示当前IO管脚)。

2. 例程

2.1 LED灯

#include "boards.h"
#include "pinctrl.h"
#include "gpio.h"
#include "soc_osal.h"
#include "app_init.h"#define BLINKY_DURATION_MS        500#define BLINKY_TASK_PRIO          24
#define BLINKY_TASK_STACK_SIZE    0x1000static int blinky_task(const char *arg)
{unused(arg);uapi_pin_set_mode(CONFIG_SAMPLE_BLINKY_PIN, HAL_PIO_FUNC_GPIO);uapi_gpio_set_dir(CONFIG_SAMPLE_BLINKY_PIN, GPIO_DIRECTION_OUTPUT);uapi_gpio_set_val(CONFIG_SAMPLE_BLINKY_PIN, GPIO_LEVEL_LOW);while (1) {osal_msleep(BLINKY_DURATION_MS);uapi_gpio_toggle(CONFIG_SAMPLE_BLINKY_PIN);osal_printk("Blinky working.\r\n");}return 0;
}static void blinky_entry(void)
{osal_task *task_handle = NULL;osal_kthread_lock();task_handle = osal_kthread_create((osal_kthread_handler)blinky_task, 0, "BlinkyTask", BLINKY_TASK_STACK_SIZE);if (task_handle != NULL) {osal_kthread_set_priority(task_handle, BLINKY_TASK_PRIO);}osal_kthread_unlock();
}/* Run the blinky_entry. */
app_run(blinky_entry);

         LiteOS 里面,用户应用程序的初始化入口是通过 app_run 宏定义进行绑定的;例程中绑定到 blinky_entry 函数,函数里面就是创建一个LED灯的任务。

        blinky_task 函数即任务的执行函数,调用 uapi_pin_set_mode 函数设置管脚模式,HAL_PIO_FUNC_GPIO 表示初始化为普通IO;调用 uapi_gpio_set_dir 函数设置 GPIO 为输出模式;调用 uapi_gpio_set_val 函数设置 GPIO 的初始值。

        任务主循环每隔一段时间调用 uapi_gpio_toggle 去反向 GPIO 的值。

        编译例程前还需要配置Kconfig,修改管脚号为开发板上LED灯的管脚,我这里对应的是GPIO31。

         下面为运行时的系统log。

2.2 按键输入 

        SDK中有提供按键输入的例程,但是莫名其妙缺少了头文件和部分实现,所以需要把下面代码覆盖fbb_bs2x\src\application\samples\peripheral\button\button.c源文件。

#include "boards.h"
#include "pinctrl.h"
#include "gpio.h"
#include "soc_osal.h"
#include "app_init.h"static int button_task(void* args)
{unused(args);uapi_pin_set_mode(CONFIG_SAMPLE_BUTTON_PIN, HAL_PIO_FUNC_GPIO);uapi_pin_set_pull(CONFIG_SAMPLE_BUTTON_PIN, PIN_PULL_UP);uapi_gpio_set_dir(CONFIG_SAMPLE_BUTTON_PIN, GPIO_DIRECTION_INPUT);while (1) {if (uapi_gpio_get_val(CONFIG_SAMPLE_BUTTON_PIN) == GPIO_LEVEL_LOW) {while (uapi_gpio_get_val(CONFIG_SAMPLE_BUTTON_PIN) == GPIO_LEVEL_LOW) {osal_msleep(10);}osal_printk("Button pressed\r\n");}osal_msleep(10);}return 0;
}static void button_entry(void)
{osal_task *task_handle = NULL;osal_kthread_lock();task_handle = osal_kthread_create(button_task, NULL, "ButtonTask", 4096);if (task_handle != NULL) {osal_kthread_set_priority(task_handle, 24);}osal_kthread_unlock();
}/* Run the button_entry. */
app_run(button_entry);

        应用入口函数与前面一致。

        任务开始先调用 uapi_pin_set_mode 配置管脚为普通 IO;再调用 uapi_pin_set_pull 配置管脚上拉;最后调用 uapi_gpio_set_dir 配置管脚为输出。

        任务循环里面调用 uapi_gpio_get_val 不断获取管脚的输入,后面带一个软件去抖动操作,这样当我们松开按钮程序才会真正判断为按钮按下。

任务循环的最后一定要加一个延时,不加的话会因为空闲任务一直无法运行而导致看门狗超时。

        编译前还需要通过Kconfig配置按键的管脚号,这里配置为GPIO11。

        因为开发板是没有预留用户按键的,所以测试就只能用杜邦线连接地线和IO11。

http://www.dtcms.com/a/267815.html

相关文章:

  • 字符函数和字符串函数(下)- 暴力匹配算法
  • python pip 下载慢
  • 在 Dokploy 中为 PostgreSQL 搭建 PgBouncer 数据库连接池(图文)
  • 【influxdb3】如何使用 SQL 对时间序列数据进行聚合查询
  • Golang读取ZIP压缩包并显示Gin静态html网站
  • 51c大模型~合集150
  • 大型语言模型中的自动化思维链提示
  • unity校招岗面试题 天津某场 深圳某场
  • spring中@Transactional注解和事务的实战理解附代码
  • 蓝凌EKP产品:Hibernate懒加载检测与开发助手
  • LoRaWAN的设备类型有哪几种?
  • ABP VNext + Tye:本地微服务编排与调试
  • 1.线性神经网络--线性回归
  • Windows深色模式助手,定时自动切换
  • 热方程初边值问题解法
  • Qt之修改纯色图片的颜色
  • token设计方案
  • 大话网络协议 - HTTP不同版本的演进及其区别
  • 基于Excel的数据分析思维与分析方法
  • Java poi-tl 使用 word 模板 生成 word
  • 人工智能之数学基础:线性回归算法的矩阵参数求导
  • dubbo源码学习2-dubbo协议源码分析
  • C++:编译QXlsx库过程
  • 咕咚运动启动时弹出广告
  • Go语言--语法基础6--基本数据类型--切片类型
  • 【学习篇】SQL复杂查询学习
  • D3 面试题100道之(61-80)
  • React 英语单词消消乐一款专为英语学习设计的互动式记忆游戏
  • Flink ClickHouse 连接器:实现 Flink 与 ClickHouse 无缝对接
  • Scala 简介