写在前面:本篇是系列文章《基于 OpenHarmony 5.0 的星闪轻量型设备应用开发》的第 3 章。本篇从 GPIO、PWM、I2C、UART 以及 ADC 等方面对基于 OpenHarmony 5.0 的 WS63 设备驱动开发进行了详细的介绍。本篇的篇幅较长,建议先收藏再阅读。
“设备”是相对于 WS63E 模组而言的其他硬件资源。
这些“设备”可以是 LED 灯,也可以是蜂鸣器,亦或是温湿度传感器。如果想通过编写运行在 WS63E 上的 OpenHarmony 框架代码,用于控制这些设备的工作状态或能力,就需要进行设备驱动的开发。
对 WS63E 而言,这些设备与之进行数据交互的通道就是 IO 引脚。基于 OpenHarmony 的 WS63E 设备驱动开发就是通过对相应 IO 引脚进行模式配置,数据赋值,数据读取,中断配置等一系列的操作。
从本章开始,将以石院星闪物联网教学开发板为例,介绍 OpenHarmony 的设备驱动开发。主要包括:GPIO、I2C、PWM、UART、ADC等。
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-3 开发板载 LED 电路原理图
开发板上有两个可编程 LED,其正极分别与核心芯片的 GPIO-00 以及 GPIO-01 连接。若要 LED 亮,则需要在 GPIO-00 以及 GPIO-01 上分别提供正向电压,即高电平,方可使电路导通;若要 LED 灭,则反之提供低电平,电路无法导通即可。
GPIO 编程的一般步骤为:
void uapi_pin_init(void);errcode_t uapi_pin_set_mode(pin_t pin, pin_mode_t mode);若要写出正确的 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 uapi_gpio_set_dir(pin_t pin, gpio_direction_t dir);errcode_t uapi_gpio_set_val(pin_t pin, gpio_level_t level);errcode_t uapi_gpio_toggle(pin_t pin);基于 OpenHarmony 的设备驱动开发需要创建工程、编写功能代码、编写和修改配置文件、编译和烧写等步骤,以下将逐一进行介绍。
OpenHarmony 的工程目录一般存放在 application/sample/wifi-iot/app 目录下,以下将该目录统称为“工程目录”。
在工程目录下新建 “01_LED_DEMO” 文件夹,并在该文件夹中新建“led_demo.c”文件和“BUILD.gn”文件。
led_demo.c 的代码如下:
该项目目录下的 BUILD.gn 的代码如下:
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"
在 VS Code 工具中,打开内置终端工具,进入当前OpenHarmony 的源码目录下,输入命令 rm -rf out && hb set -p nearlink_dk_3863 && hb build -f ,等待编译完成。

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

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

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

图 3.3-3 开发板上 KEY 的电路原理图
【说明】这种状态的变化,可以作为一个触发信号,向 CPU 提出需要执行某个特定功能的请求,一旦 CPU
捕获到这种请求,则会根据实际情况决定是否要响应该请求。如果 CPU
决定响应该请求,则会做一些“现场保护”的工作后(这些都是由编译器自动完成的固定动作,无需开发人员进行代码编写),转向“被请求的功能”处执行代码,当功能执行完毕后,又会“返回到”之前的“断点”处继续执行原来的代码。这,就是系统的外部中断机制。
GPIO 的外部中断功能编程步骤是在其作为“通用 IO”编程步骤的基础上增加了:
errcode_t uapi_gpio_set_isr_mode(pin_t pin, uint32_t trigger);errcode_t uapi_gpio_register_isr_func(pin_t pin, uint32_t trigger, gpio_callback_t callback);errcode_t uapi_gpio_unregister_isr_func(pin_t pin);errcode_t uapi_gpio_enable_interrupt(pin_t pin);errcode_t uapi_gpio_disable_interrupt(pin_t pin);在工程目录下新建 “02_KEY_DEMO” 文件夹,并在该文件夹中新建“key_demo.c”文件和“BUILD.gn”文件。
key_demo.c 的代码如下:
原文作者:ursamjnor;如有侵权,请联系管理员删除。