ITPub博客

首页 > 数据库 > 数据库开发技术 > 基于 OpenHarmony 5.0 的星闪轻量型设备应用开发——Ch3 设备驱动开发

基于 OpenHarmony 5.0 的星闪轻量型设备应用开发——Ch3 设备驱动开发

数据库开发技术 作者:LinuxWizard 时间:2026-08-06 20:35:48 0 删除 编辑

写在前面:本篇是系列文章《基于 OpenHarmony 5.0 的星闪轻量型设备应用开发》的第 3 章。本篇从 GPIO、PWM、I2C、UART 以及 ADC 等方面对基于 OpenHarmony 5.0 的 WS63 设备驱动开发进行了详细的介绍。本篇的篇幅较长,建议先收藏再阅读。

3.1 OpenHarmony WS63 设备驱动开发介绍

“设备”是相对于 WS63E 模组而言的其他硬件资源。

这些“设备”可以是 LED 灯,也可以是蜂鸣器,亦或是温湿度传感器。如果想通过编写运行在 WS63E 上的 OpenHarmony 框架代码,用于控制这些设备的工作状态或能力,就需要进行设备驱动的开发。

对 WS63E 而言,这些设备与之进行数据交互的通道就是 IO 引脚。基于 OpenHarmony 的 WS63E 设备驱动开发就是通过对相应 IO 引脚进行模式配置,数据赋值,数据读取,中断配置等一系列的操作。

从本章开始,将以石院星闪物联网教学开发板为例,介绍 OpenHarmony 的设备驱动开发。主要包括:GPIO、I2C、PWM、UART、ADC等。

3.2 GPIO 基本功能——以控制 LED 亮灭为例

GPIO(General-purpose input/output)是通用输入输出的缩写,是一种通用的 I/O 接口标准。可以配置为输入或输出模式,以便控制外部设备或与其他设备通信。可用于连接各种设备,如 LED 灯、传感器、执行器等。

使用 WS63 的 GPIO 功能,需要通过与之有关的引脚控制接口(pinctrl 驱动模块)和 GPIO 功能接口(gpio 驱动模块)来实现。

本节以开发板上两个可编程的 LED 为例,介绍使用 OpenHarmony 开发GPIO 的通用 IO 功能的基本流程。

图 3.2-1 LED 灯珠(长脚为正极,短脚为负极)

图 3.2-2 贴片 LED 灯珠(带正负极说明)

LED是发光二极管,是20世纪中期发展起来的新技术。它依靠半导体异质结中的电子通过势垒产生的能量迁越直接发光。通过LED制作的灯具由于发光过程不产生热量,能量转换效率接近百分之百,寿命超长,是照明技术的发展方向。

发光二极管的核心部分是由p型半导体和n型半导体组成的晶片,在p型半导体和n型半导体之间有一个过渡层,称为p-n结。在某些半导体材料的PN结中,注入的少数载流子与多数载流子复合时会把多余的能量以光的形式释放出来,从而把电能直接转换为光能。PN结加反向电压,少数载流子难以注入,故不发光。这种利用注入式电致发光原理制作的二极管叫发光二极管,通称LED。 当它处于正向工作状态时(即两端加上正向电压),电流从LED阳极流向阴极时,半导体晶体就发出从紫外到红外不同颜色的光线,光的强弱与电流有关。

3.2.1 板载 LED 电路原理图

图 3.2-3 开发板载 LED 电路原理图

开发板上有两个可编程 LED,其正极分别与核心芯片的 GPIO-00 以及 GPIO-01 连接。若要 LED 亮,则需要在 GPIO-00 以及 GPIO-01 上分别提供正向电压,即高电平,方可使电路导通;若要 LED 灭,则反之提供低电平,电路无法导通即可。

3.2.2 GPIO 用作通用 IO 的编程步骤

GPIO 编程的一般步骤为:

  • 初始化 pinctrl
  • 设置指定 IO 的复用模式为通用 IO 功能
  • 设置指定 IO 的数据输入输出方向
    • 若指定为输出,则根据功能需求向指定 IO 发送“0”或者“1”分别输出低电平或高电平
    • 若指定为输入,则根据功能需求从指定 IO 读取当前的电平值。若开启 IO 中断功能,则还需要配置中断触发方式以及对应的中断服务程序功能。

3.2.3 功能开发所涉及的接口介绍

(1)初始化 pinctrl
  • 原型:void uapi_pin_init(void);
  • 位置:SDK 目录/include/driver/pinctrl.h
  • 参数:无
  • 返回值:无
  • 调用:该函数应该在其他 pinctrl 模块函数被调用前执行。
(2)设置指定 IO 复用模式接口
  • 原型:errcode_t uapi_pin_set_mode(pin_t pin, pin_mode_t mode);
  • 位置:SDK 目录/include/driver/pinctrl.h
  • 参数:
    • pin 的数据类型是 pin_t,该类型是一个枚举类型,定义了 WS63 可以使用的 pin 的名称编号,具体的定义在文件 “SDK 目录/drivers/chips/ws63/include/platform_core_rom.h” 中,内容见代码 3.2-1:
    • mode 的数据类型是 pin_mode_t ,该类型也是一个枚举类型,定义了 pin 可以被复用的名称编号,具体的定义在文件 “SDK 目录/dirvers/chips/ws63/porting/pinctrl/pinctrl_porting.h” 中,具体内容见代码 3.2-2:

若要写出正确的 pin 复用代码,还需要知道 WS63 的 IO 复用关系,具体如下表所示。

表 3.2-1 IO 复用关系表

IO/MODE 0 1 2 3 4 5 6 7
GPIO_00 GPIO_00 PWM0 DIAG[0] SPI1_CSN JTAG_TDI
GPIO_01 GPIO_01 PWM1 DIAG[1] SPI1_IO0 JTAG_MODE BT_SAMPLE
GPIO_02 GPIO_02 PWM2 DIAG[2] SPI1_IO3 WIFI_TSF_SYNC WL_GLP_SYNC_PULSE BGLE_GLP_SYNC_PULSE
GPIO_03 GPIO_03 PWM3 PMU_32K_TEST SPI1_IO1 HW_ID[0] DIAG[3]
GPIO_04 SSI_CLK PWM4 GPIO_04 SPI1_IO1 JTAG_ENABLE DFT_JTAG_TMS
GPIO_05 SSI_DATA PWM5 UART2_CTS SPI1_IO2 GPIO_05 SPI0_IN DFT_JTAG_TCK
GPIO_06 GPIO_06 PWM6 UART2_RTS SPI1_SCK REFCLK_FREQ_STATUS DIAG[4] SPIO0_OUT DFT_JTAG_TDI
GPIO_07 GPIO_07 PWM7 UART2_RXD SPI0_SCK I2S_MCLK DIAG[5]
GPIO_08 GPIO_08 PWM0 UART2_TXD SPI0_CS1_N DIAG[6]
GPIO_09 GPIO_09 PWM1 RADAR_ANT0_SW SPI0_OUT I2S_DO HW_ID[1] DIAG[7] JTAG_TD0
GPIO_10 GPIO_10 PWM2 ANT0_SW SPI0_CS0_N I2S_SCLK DIAG[0]
GPIO_11 GPIO_11 PWM3 RADAR_ANT1_SW SPI0_IN I2S_LRCLK DIAG[1] HW_ID[2]
GPIO_12 GPIO_12 PWM4 ANT1_SW I2S_DI HW_ID[3]
GPIO_13 GPIO_13 UART1_CTS RADAR_ANT0_SW DFT_JTAG_TD0 JTAG_TMS
GPIO_14 GPIO_14 UART1_RTS RADAR_ANT1_SW DFT_JTAG_TRSTN JTAG_TCK
UART1_TXD GPIO_15 UART1_TXD I2C1_SDA
UART1_RXD GPIO_16 UART1_RXD I2C1_SCL
UART0_TXD GPIO_17 UART0_TXD I2C0_SDA
UART0_RXD GPIO_18 UART0_RXD I2C0_SCL
  • 返回值:errcode_t 类型的值,定义在文件 “SDK 目录/include/errcode.h” 中
    • 如果成功,返回值为 ERRCODE_SUCC(即 0)
    • 如果失败,返回值非 0,可根据返回值在 errcode_t 类型中查看出错类型。
  • 调用:如图 3.2-3 的 LED 电路原理图所示,需要将 GPIO_00 和 GPIO_01 复用为普通 IO模式,也就是模式 0,对应的代码如下所示:
(3)设置指定 IO 的数据输入输出方向
  • 原型:errcode_t uapi_gpio_set_dir(pin_t pin, gpio_direction_t dir);
  • 位置:SDK 目录/include/driver/gpio.h
  • 参数:
    • 参数 pin 用来指定 GPIO 的引脚编号。
    • 参数 dir 的数据类型是 gpio_direction_t ,该类型是枚举类型,定义了 GPIO 的输入输入方向,具体的定义在文件 “SDK 目录/drivers/drivers/hal/gpio/hal_gpio.h ”中 ,内容如下:
  • 返回值:
    • 如果成功,返回值为 ERRCODE_SUCC(即 0)
    • 如果失败,返回值非 0,可根据返回值在 errcode_t 类型中查看出错类型。
  • 调用:如图 3.2-3 的 LED 电路原理图所示,需要将 GPIO_00 和 GPIO_01 的方向设置为输出,对应的代码如下:
(4)向指定 IO 发送数据
  • 原型:errcode_t uapi_gpio_set_val(pin_t pin, gpio_level_t level);
  • 位置:SDK 目录/include/driver/gpio.h
  • 参数:
    • 参数 pin 用于指定 GPIO 的名称编号。
    • 参数 level 的数据类型是 gpio_level_t ,该类型是枚举类型,定义了 GPIO 的高低电平,具体的定义在文件 “SDK 目录/drivers/drivers/hal/gpio/hal_gpio.h” 中 ,内容如下:
  • 返回值:
    • 如果成功,返回值为 ERRCODE_SUCC(即 0)
    • 如果失败,返回值非 0,可根据返回值在 errcode_t 类型中查看出错类型。
  • 调用:如图 3.2-3 的 LED 电路原理图所示, 若要 LED_L 亮,需要向 GPIO_00 发送高电平,若要 LED_L 灭,需要向 GPIO_00 发送低电平(LED_R 同理)。对应的代码如下:
(5)向指定 IO 发送翻转数据
  • 原型:errcode_t uapi_gpio_toggle(pin_t pin);
  • 位置:SDK 目录/include/driver/gpio.h
  • 参数:
    • 参数 pin 用于指定 GPIO 的引脚名称编号
  • 返回值:
    • 如果成功,返回值为 ERRCODE_SUCC(即 0)
    • 如果失败,返回值非 0,可根据返回值在 errcode_t 类型中查看出错类型。
  • 调用:如图 3.2-3 的 LED 电路原理图所示, 若要 LED_L 的亮灭状态发生翻转,则对应的代码如下:

3.2.4 功能开发实现

基于 OpenHarmony 的设备驱动开发需要创建工程、编写功能代码、编写和修改配置文件、编译和烧写等步骤,以下将逐一进行介绍。

(1)创建工程

OpenHarmony 的工程目录一般存放在 application/sample/wifi-iot/app 目录下,以下将该目录统称为“工程目录”。

在工程目录下新建 “01_LED_DEMO” 文件夹,并在该文件夹中新建“led_demo.c”文件和“BUILD.gn”文件。

(2)编写功能代码

led_demo.c 的代码如下:

(3)编写配置文件

该项目目录下的 BUILD.gn 的代码如下:

(4)修改工程配置文件

1) 修改“工程目录”下的 BUILD.gn 文件,在 features 数组中添加 "01_LED_DEMO",

2)修改 SDK 目录/build/config/target_config/ws63/config.py 文件,在'ws63-liteos-app'中'ram_component': []'添加 "ledDemo",

3)修改 SDK 目录/libs_url/ws63/cmake/ohos.cmake 文件,在 COMPONENT_LIST 项中添加 "ledDemo"

(5)编译工程

在 VS Code 工具中,打开内置终端工具,进入当前OpenHarmony 的源码目录下,输入命令 rm -rf out && hb set -p nearlink_dk_3863 && hb build -f ,等待编译完成。

(6)烧写
  • 使用串口线将 **石院星闪物联网教学开发板 **的 USB 端口与 PC 机的 USB 端口连接(烧写前请先确认是否安装串口驱动,若没有,请参考第一章的内容完成驱动的安装)

  • 参考“第 1 章 1.4 镜像文件的烧写”一节的内容完成烧写。
(7)运行效果
  • 烧写结束后,会看到 开发板上的 LED_L 和 LED_R 在交替闪烁。

3.3 GPIO 中断功能——以按键(轻触开关)控制 LED 为例

本节介绍的案例功能是通过按动开发板上的“KEY”按键(轻触开关),控制两个 LED 的亮灭状态切换。

图 3.3-1 轻触开关实物图

如图 3.3-1 所示,在许多电路板中,都会使用这种正方形的轻触开关来实现电路的导通或断开功能。这类轻触开关一般都有四个焊接引脚,图 3.2-5 是轻触开关的外观尺寸以及内部结构示意图。

图 3.3-2 轻触开关内部结构示意图

3.3.1 开发板上 KEY 电路原理图

图 3.3-3 开发板上 KEY 的电路原理图

  • 通过原理图可以看出,在通常情况下,按键中的弹簧片悬高,1、2 引脚所在电路与 3、4 引脚所在电路属于断开状态。当开发板通电时,此时的 GPIO-02 处应当是高电平,若按下按键后,电路导通,则 GPIO-02 处是低电平。
  • 以上的描述也可以理解为默认情况下,GPIO-02 处始终是保持高电平状态,一旦按键被按下,则GPIO-02 的状态发生了变化,即从高电平变化为低电平。

【说明】这种状态的变化,可以作为一个触发信号,向 CPU 提出需要执行某个特定功能的请求,一旦 CPU
捕获到这种请求,则会根据实际情况决定是否要响应该请求。

如果 CPU
决定响应该请求,则会做一些“现场保护”的工作后(这些都是由编译器自动完成的固定动作,无需开发人员进行代码编写),转向“被请求的功能”处执行代码,当功能执行完毕后,又会“返回到”之前的“断点”处继续执行原来的代码。这,就是系统的外部中断机制。

  • 通常,将电平信号从高电平变化为低电平的这种过程称之为“下降沿”,反之为“上升沿”。

3.3.2 GPIO 的外部中断功能编程步骤

GPIO 的外部中断功能编程步骤是在其作为“通用 IO”编程步骤的基础上增加了:

  • 中断服务程序功能代码编写
  • 注册 IO 引脚的中断服务

3.3.3 功能开发所涉及的接口介绍

(1)设置指定 IO 的中断触发方式
  • 原型:errcode_t uapi_gpio_set_isr_mode(pin_t pin, uint32_t trigger);
  • 位置:SDK 目录/include/driver/gpio.h
  • 参数:
    • 参数 pin 用于指定 GPIO 的名称编号。
    • 参数 trigger 是 uint32_t 类型的数据,其值表示 GPIO 的中断触发方式:
      • 1:上升沿触发
      • 2:下降沿触发
      • 3:双边沿触发
      • 4:低电平触发
      • 8:高电平触发
  • 返回值:
    • 如果成功,返回值为 ERRCODE_SUCC(即 0)
    • 如果失败,返回值非 0,可根据返回值在 errcode_t 类型中查看出错类型。
  • 调用:如图 3.3-3 的 KEY 用户按键电路原理图所示,GPIO-02 需要设置下降沿触发中断。对应的代码如下:
(2) 注册指定 IO 的中断服务
  • 原型:errcode_t uapi_gpio_register_isr_func(pin_t pin, uint32_t trigger, gpio_callback_t callback);
  • 位置:SDK 目录/include/driver/gpio.h
  • 参数:
    • 参数 pin 用于指定 GPIO 的引脚名称编号。
    • 参数 trigger 的值表示 GPIO 的中断触发方式(取值与uapi_gpio_set_isr_mode接口中规定的相同)。
    • 参数 callback 是 gpio_callback_t 类型,该类型是一个函数指针类型,具体定义在文件“SDK 目录/drivers/drivers/hal/gpio/hal_gpio.h”中,内容如下:
  • 返回值:
    • 如果成功,返回值为 ERRCODE_SUCC
    • 如果失败,返回值非 0,可根据返回值在 errcode_t 类型中查看出错类型。
  • 调用:注册 IO 引脚中断服务功能的函数在调用前,需要先定义好中断服务功能函数。以下代码是调用举例。
(3) 取消指定 IO 所注册的中断服务
  • 原型:errcode_t uapi_gpio_unregister_isr_func(pin_t pin);
  • 位置:SDK 目录/include/driver/gpio.h
  • 参数:
    • 参数 pin 用于指定 GPIO 的引脚名称编号。
  • 返回值:
    • 如果成功,返回值为 ERRCODE_SUCC
    • 如果失败,返回值非 0,可根据返回值在 errcode_t 类型中查看出错类型。
  • 调用:参考代码 3.2.2-3 中的代码。
(4) 使能指定 IO 的中断请求
  • 原型:errcode_t uapi_gpio_enable_interrupt(pin_t pin);
  • 位置:SDK 目录/include/driver/gpio.h
  • 参数:
    • 参数 pin 用于指定 GPIO 的引脚名称编号。
  • 返回值:
    • 如果成功,返回值为 ERRCODE_SUCC
    • 如果失败,返回值非 0,可根据返回值在 errcode_t 类型中查看出错类型。
  • 调用:默认情况下 GPIO 的中断请求都是开放的,但是在某些情况下由于开发需要,可能会将某些 IO 引脚的中断服务请求屏蔽,等需要的时候再开放,该接口就是用于开启 IO 引脚的中断请求,这样在 IO 引脚上产生的中断请求信号会被 CPU 捕捉,进而对其进行响应(即调用注册的中断服务函数)。
(5) 屏蔽指定 IO 的中断请求
  • 原型:errcode_t uapi_gpio_disable_interrupt(pin_t pin);
  • 位置:SDK 目录/include/driver/gpio.h
  • 参数:
    • 参数 pin 用于指定 GPIO 的引脚名称编号。
  • 返回值:
    • 如果成功,返回值为 ERRCODE_SUCC
    • 如果失败,返回值非 0,可根据返回值在 errcode_t 类型中查看出错类型。
  • 调用:在需要屏蔽 IO 中断请求的代码处调用该接口即可。

3.3.4 功能开发实现

(1)创建工程

在工程目录下新建 “02_KEY_DEMO” 文件夹,并在该文件夹中新建“key_demo.c”文件和“BUILD.gn”文件。

(2)编写功能代码

key_demo.c 的代码如下:

原文作者:ursamjnor;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2020-02-25

  • 博文量
    16
  • 访问量
    690