OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇(上)

前言
下面我們繼續(xù)跟著架構(gòu)圖去學(xué)習(xí)另一個板塊——驅(qū)動,本片將介紹。
![OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū) OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū)](https://dl-harmonyos.51cto.com/images/202305/23a11a7181e91960c9608313424737143c449a.png?x-oss-process=image/resize,w_820,h_635)
驅(qū)動開發(fā)簡介
什么是驅(qū)動開發(fā)呢,回想我們之前介紹內(nèi)核的時候,內(nèi)核的作用是幫助我們完成對硬件的操控的,我們已經(jīng)通過KAL內(nèi)核抽象層提供的規(guī)范接口,實現(xiàn)了對內(nèi)核的一些基本控制,但是并沒有涉及到硬件設(shè)備,那么驅(qū)動開發(fā)的含意就呼之欲出了。
驅(qū)動開發(fā)是指為操作系統(tǒng)或硬件設(shè)備編寫軟件驅(qū)動程序的過程。驅(qū)動程序是一種特殊的軟件,它與操作系統(tǒng)或硬件設(shè)備進行交互,以使它們能夠有效地通信和協(xié)同工作。通俗點講就是IO控制硬件設(shè)備。IO流在讀寫文件時大家都會用到,我們的驅(qū)動也像IO流,只不過操作的對象不在是虛擬的文件,而是你手中的開發(fā)板,實實在在摸得到的硬件設(shè)備。
硬件設(shè)備介紹
硬件總覽
筆者使用的是智能家居開發(fā)套件:Hi3861
![OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū) OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū)](https://dl-harmonyos.51cto.com/images/202305/552e26051a0c3884d5c467ace4bac7165528ed.png?x-oss-process=image/resize,w_820,h_970)
硬件詳細介紹
底板
![OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū) OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū)](https://dl-harmonyos.51cto.com/images/202305/35cbe7c22ccc9749424535a628f5429c91576b.png?x-oss-process=image/resize,w_820,h_746)
核心板
![OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū) OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū)](https://dl-harmonyos.51cto.com/images/202305/f89b67377cbc7f3a9ff7285a9cbc66e2a3e094.png?x-oss-process=image/resize,w_820,h_643)
oled屏幕
![OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū) OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū)](https://dl-harmonyos.51cto.com/images/202305/a493c0b9417a956db5144720f6a6c92340b9dc.png?x-oss-process=image/resize,w_699,h_779)
交通燈
![OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū) OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū)](https://dl-harmonyos.51cto.com/images/202305/f207df5904c232a5c9e369a0e7d648aee6b853.png?x-oss-process=image/resize,w_618,h_756)
RGB燈板
![OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū) OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū)](https://dl-harmonyos.51cto.com/images/202305/b13067d136bf352a41e6819f900fa4aadb33d6.png?x-oss-process=image/resize,w_665,h_744)
環(huán)境檢測板
![OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū) OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū)](https://dl-harmonyos.51cto.com/images/202305/d5e80e01488f1f88a0b992bd1907b1e8c59b78.png?x-oss-process=image/resize,w_666,h_759)
NFC
![OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū) OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū)](https://dl-harmonyos.51cto.com/images/202305/b1a5a0b452397b7a66e327c480d90e4a267ab4.png?x-oss-process=image/resize,w_756,h_768)
驅(qū)動開發(fā)
GPIO
GPIO可以理解為數(shù)字I/O,是一種電平控制,由0和1表示,0表示低電平,1表示高電平。Hi3861芯片一共有15各個GPIO引腳,芯片內(nèi)部集成了GPIO模塊,方便我們?nèi)ナ褂谩?/p>
Hi3861 GPIO 引腳分布
![OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū) OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū)](https://dl-harmonyos.51cto.com/images/202305/9680b0c345f3b8d6c72282ded46b35d2e9dadd.png?x-oss-process=image/resize,w_820,h_830)
IoT接口
OprnHarmony提供了操作物聯(lián)網(wǎng)各種外接設(shè)備的一組API,方便我們?nèi)タ刂婆c外接設(shè)備的交互。一共有三類IoT接口。
- HAL硬件抽象層接口。
- HDF硬件驅(qū)動框架接口。
- 海思SDK接口。
其中HDF接口是主推接口,在上面的架構(gòu)圖中也能看到,海思的SDK是原廠商提供的底層接口。
![OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū) OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū)](https://dl-harmonyos.51cto.com/images/202305/824d62915b7d742ee38012d06ff18cd5cf6dc5.png?x-oss-process=image/resize,w_820,h_711)
GPIO控制流程
![OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū) OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū)](https://dl-harmonyos.51cto.com/images/202305/e3031ee228d9b9dcdf9027d4d7f925aaa3b6ca.png?x-oss-process=image/resize,w_820,h_443)
IoT編程工作環(huán)境補充
在源碼目錄生成的 .vscode的目錄下的 c_cpp_properties.json 文件中做出如下添加。
[注:目錄可能因為源碼版本不同而不一致,這里可以手動搜索文件來確定庫的存放位置]。
![OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū) OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū)](https://dl-harmonyos.51cto.com/images/202305/d2cbb14340ec76779f8735525e4be7a562dbcb.png?x-oss-process=image/resize,w_820,h_1409)
打開 usr_config.mk 文件 修改如下配置,防止后續(xù)的操作中出現(xiàn)編譯錯誤,筆者報錯時,也是在這卡了很久。這個配置項默認是關(guān)閉的,就會導(dǎo)致某些庫中的方法無法被識別,編譯就會出問題,主要是pwm模塊的使用,這里提前說一下。
![OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū) OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū)](https://dl-harmonyos.51cto.com/images/202305/6789b7705f2b3021957618114e793b22e69cc2.png?x-oss-process=image/resize,w_820,h_1393)
GPIO-API
- GPIO初始化。
unsigned int IoTGpioInit(unsigned int id);參數(shù)解釋:
- id: GPIO的引腳編號。
返回值:
- IOT_SUCCESS:如果GPIO設(shè)備成功初始化,則返回該值。
- IOT_FAILURE:如果GPIO設(shè)備初始化失敗,則返回該值。
- GPIO參數(shù)設(shè)置。
unsigned int IoTGpioSetDir(unsigned int id, IotGpioDir dir);參數(shù)解釋:
- id: GPIO的引腳編號。
- dir: 設(shè)置GPIO為輸入/輸出。
返回值:
- IOT_SUCCESS:如果GPIO設(shè)備成功設(shè)置,則返回該值。
- IOT_FAILURE:如果GPIO設(shè)備設(shè)置失敗,則返回該值。
其中,IotGPIODir 的定義如下的枚舉類型:
typedef enum {
/** Input */
IOT_GPIO_DIR_IN = 0,
/** Output */
IOT_GPIO_DIR_OUT
} IotGpioDir;- 設(shè)置GPIO輸出狀態(tài)。
unsigned int IoTGpioSetOutputVal(unsigned int id, IotGpioValue val);參數(shù)解釋:
- id: GPIO的引腳編號。
- val: 輸出的電平值。
返回值:
- IOT_SUCCESS:如果GPIO設(shè)備成功設(shè)置,則返回該值。
- IOT_FAILURE:如果GPIO設(shè)備設(shè)置失敗,則返回該值。
其中,IotGPIOValue的定義如下的枚舉類型:
typedef enum {
/** Low GPIO level */
IOT_GPIO_VALUE0 = 0,
/** High GPIO level */
IOT_GPIO_VALUE1
} IotGpioValue;- 解除GPIO。
unsigned int IoTGpioDeinit(unsigned int id);參數(shù)解釋:
- id: GPIO的引腳編號
返回值:
- IOT_SUCCESS:如果GPIO設(shè)備成功解除,則返回該值。
- IOT_FAILURE:如果GPIO設(shè)備解除失敗,則返回該值。
- 獲取GPIO引腳狀態(tài)。
unsigned int IoTGpioGetOutputVal(unsigned int id, IotGpioValue *val);參數(shù)解釋:
- id: GPIO的引腳編號
- *val: 獲取輸出的電平值的指針
返回值:
- IOT_SUCCESS:如果GPIO設(shè)備成功獲取,則返回該值。
- IOT_FAILURE:如果GPIO設(shè)備獲取失敗,則返回該值。
這個API和設(shè)置GPIO引腳的API很像,只不過val屬性變成了個指針,也就通過這個指針幫我們獲取到GPIO的引腳狀態(tài)的。
- 引腳中斷函數(shù)注冊。
unsigned int IoTGpioRegisterIsrFunc(unsigned int id, IotGpioIntType intType, IotGpioIntPolarity intPolarity,
GpioIsrCallbackFunc func, char *arg);參數(shù)解釋:
- id:GPIO引腳的編號。
- intType:中斷類型。
- intPolarity:中斷極性。
- func:中斷回調(diào)函數(shù)。
- arg:中斷回調(diào)函數(shù)中使用的參數(shù)的指針。
返回值:
- IOT_SUCCESS:如果成功啟用GPIO引腳的中斷功能,則返回該值。
- IOT_FAILURE:如果啟用GPIO引腳的中斷功能失敗,則返回該值。
其中 IotGpioIntType 定義如下的枚舉類型。
typedef enum {
/** Level-sensitive interrupt */
IOT_INT_TYPE_LEVEL = 0,
/** Edge-sensitive interrupt */
IOT_INT_TYPE_EDGE
} IotGpioIntType;IOT_INT_TYPE_LEVEL:表示電平觸發(fā)的中斷類型。這種中斷類型基于GPIO引腳的電平狀態(tài)進行觸發(fā),即當(dāng)引腳的電平為特定的電平(例如高電平或低電平)時觸發(fā)中斷。
IOT_INT_TYPE_EDGE:表示邊沿觸發(fā)的中斷類型。這種中斷類型基于GPIO引腳的電平變化進行觸發(fā),即當(dāng)引腳的電平從一個狀態(tài)變化到另一個狀態(tài)(例如從低電平到高電平或從高電平到低電平)時觸發(fā)中斷。
IotGpioIntPolarity 定義如下的枚舉類型。
typedef enum {
/** Interrupt at a low level or falling edge */
IOT_GPIO_EDGE_FALL_LEVEL_LOW = 0,
/** Interrupt at a high level or rising edge */
IOT_GPIO_EDGE_RISE_LEVEL_HIGH
} IotGpioIntPolarity;IOT_GPIO_EDGE_FALL_LEVEL_LOW:表示在低電平或下降沿觸發(fā)中斷。這意味著當(dāng)GPIO引腳的電平為低電平時或引腳的電平從高電平變?yōu)榈碗娖綍r,觸發(fā)中斷。
IOT_GPIO_EDGE_RISE_LEVEL_HIGH:表示在高電平或上升沿觸發(fā)中斷。這意味著當(dāng)GPIO引腳的電平為高電平時或引腳的電平從低電平變?yōu)楦唠娖綍r,觸發(fā)中斷。
當(dāng)我們向外界設(shè)備進行輸入流操作時,需要處理一些業(yè)務(wù)邏輯,在中斷函數(shù)中完成,后面會后案例讓大家體會。
- 引腳中斷函數(shù)解除。
unsigned int IoTGpioUnregisterIsrFunc(unsigned int id);參數(shù)解釋:
- id:GPIO引腳的編號。
返回值:
- IOT_SUCCESS:如果成功解除GPIO引腳的中斷功能,則返回該值。
- IOT_FAILURE:如果解除GPIO引腳的中斷功能失敗,則返回該值。
解除類型的API都比較簡單。
- 設(shè)置引腳的功能復(fù)用。
hi_u32 hi_io_set_func(hi_io_name id, hi_u8 val);參數(shù)解釋:
- id:硬件管腳的枚舉類型 hi_io_name,表示要設(shè)置復(fù)用功能的IO索引。
- val:復(fù)用功能的枚舉類型 hi_u8,表示要設(shè)置的復(fù)用功能。根據(jù)待設(shè)置的硬件管腳,從給定的枚舉值中選擇相應(yīng)的功能。
返回值:
- 0:成功設(shè)置復(fù)用功能。
- HI_ERR_GPIO_INVALID_PARAMETER:設(shè)置復(fù)用功能失敗,輸入?yún)?shù)無效或不支持的功能。
其中 hi_io_name 的美劇類型定義如下:
typedef enum {
HI_IO_NAME_GPIO_0, /**< GPIO0 */
HI_IO_NAME_GPIO_1, /**< GPIO1 */
HI_IO_NAME_GPIO_2, /**< GPIO2 */
HI_IO_NAME_GPIO_3, /**< GPIO3 */
HI_IO_NAME_GPIO_4, /**< GPIO4 */
HI_IO_NAME_GPIO_5, /**< GPIO5 */
HI_IO_NAME_GPIO_6, /**< GPIO6 */
HI_IO_NAME_GPIO_7, /**< GPIO7 */
HI_IO_NAME_GPIO_8, /**< GPIO8 */
HI_IO_NAME_GPIO_9, /**< GPIO9 */
HI_IO_NAME_GPIO_10, /**< GPIO10 */
HI_IO_NAME_GPIO_11, /**< GPIO11 */
HI_IO_NAME_GPIO_12, /**< GPIO12 */
HI_IO_NAME_GPIO_13, /**< GPIO13 */
HI_IO_NAME_GPIO_14, /**< GPIO14 */
HI_IO_NAME_SFC_CSN, /**< SFC_CSN */
HI_IO_NAME_SFC_IO1, /**< SFC_IO1 */
HI_IO_NAME_SFC_IO2, /**< SFC_IO2 */
HI_IO_NAME_SFC_IO0, /**< SFC_IO0 */
HI_IO_NAME_SFC_CLK, /**< SFC_CLK */
HI_IO_NAME_SFC_IO3, /**< SFC_IO3 */
HI_IO_NAME_MAX,
} hi_io_name;hi_u8 的定義如下:
typedef unsigned char hi_u8;Hi3861的引腳數(shù)量少,很多功能都是被集成在同一個引腳上的,因此需要我們?nèi)ミx擇引腳配置。
- 啟用某個IO引腳的上下拉功能。
hi_u32 hi_io_set_pull(hi_io_name id, hi_io_pull val);參數(shù)解釋:
- id:硬件管腳的枚舉類型 hi_io_name,表示要設(shè)置上下拉功能的IO引腳的索引。
- val:上下拉狀態(tài)的枚舉類型 hi_io_pull,表示要設(shè)置的上下拉狀態(tài)。
返回值:
- 0:成功設(shè)置上下拉功能。
- HI_ERR_GPIO_INVALID_PARAMETER:設(shè)置上下拉功能失敗,輸入?yún)?shù)無效或不支持的功能。
其中 hi_io_pull 的定義如下的枚舉類型:
typedef enum {
HI_IO_PULL_NONE, /**< Disabled.CNcomment:無拉CNend */
HI_IO_PULL_UP, /**< Pull-up enabled.CNcomment:上拉CNend */
HI_IO_PULL_DOWN, /**< Pull-down enabled.CNcomment:下拉CNend */
HI_IO_PULL_MAX, /**< Invalid.CNcomment:無效值CNend */
} hi_io_pull;上下拉功能可用于確定GPIO引腳的輸入電平狀態(tài)。例如,通過啟用上拉功能,可以將引腳的輸入電平拉高,使其在未連接外部設(shè)備時保持為高電平狀態(tài)。這樣,在檢測外部設(shè)備連接時,可以通過讀取引腳的輸入電平狀態(tài)來確定設(shè)備的連接狀態(tài)。
GPIO控制LED案例
能夠使用我們的user按鍵控制可編程led燈的熄滅與點亮。
思路:通過讀取按鍵的電平狀態(tài),觸發(fā)中斷回調(diào)函數(shù),修改led的電平。
- 新建樣例目錄。
applications/sample/wifi-iot/app/led_gpio_demo - 新建源文件和gn文件。
applications/sample/wifi-iot/app/led_gpio_demo/ledGpio.c
applications/sample/wifi-iot/app/led_gpio_demo/BUILD.gn - 編寫源文件,ledGpio.c [筆者加了詳細的注釋,就直接上代碼了]。
// C語言標(biāo)準(zhǔn)庫
#include <stdio.h>
// 初始化庫
#include "ohos_init.h"
// 內(nèi)核編程標(biāo)準(zhǔn)接口
#include "cmsis_os2.h"
// IoT接口 GPIO
#include "iot_gpio.h"
// 海思SDK IO
#include "hi_io.h"
// 定義引腳的編號
#define LED_GPIO 9
#define BUTTON_GPIO 5
// 定義ledPin(電平)低電平led點亮,高電平led熄滅,高低電平的定義在之前的api中已經(jīng)介紹過了,是一個枚舉類型。
static IotGpioValue ledPin = IOT_GPIO_VALUE0;
//GPIO5的中斷處理函數(shù),當(dāng)我們點擊user按鈕時,系統(tǒng)的內(nèi)核就會暫停手頭的工作來執(zhí)行我們這里的中斷函數(shù)。
static void ButtonPressed(char* atgs){
// 我們的業(yè)務(wù)邏輯是讓led熄滅點亮熄滅點亮,因此只需要修改上方我們定義的ledPin值即可
if(ledPin == IOT_GPIO_VALUE0){
ledPin = IOT_GPIO_VALUE1;
} else {
ledPin = IOT_GPIO_VALUE0;
}
/**
* 當(dāng)然看過源碼的你也可以簡寫成:
* ledPin = !ledPin;
*/
}
// 主函數(shù)
static void GpioInitMain(void){
// 在主函數(shù)中我們通常完成一些GPIO的注冊和設(shè)置,主要就是用一些介紹給大家的API即可
// GPIO初始化 ——> IoTGpioInit 接口
IoTGpioInit(LED_GPIO);
IoTGpioInit(BUTTON_GPIO);
// 設(shè)置引腳的功能,因為hi3861的引腳數(shù)少,一個引腳上集成了很多功能,需要我們手動設(shè)置,選擇其中的一項功能
hi_io_set_func(LED_GPIO, HI_IO_FUNC_GPIO_9_GPIO);
hi_io_set_func(BUTTON_GPIO, HI_IO_FUNC_GPIO_5_GPIO);
// 設(shè)置GPIO的輸入輸出模式 led為輸出模式,button為輸入模式
IoTGpioSetDir(LED_GPIO, IOT_GPIO_DIR_OUT);
IoTGpioSetDir(BUTTON_GPIO, IOT_GPIO_DIR_IN);
// 設(shè)置GPIO5為上拉模式
hi_io_set_pull(BUTTON_GPIO, HI_IO_PULL_UP);
// 注冊中斷函數(shù)
IoTGpioRegisterIsrFunc(BUTTON_GPIO, IOT_INT_TYPE_EDGE, IOT_GPIO_EDGE_FALL_LEVEL_LOW, ButtonPressed, NULL);
// 循環(huán)設(shè)置led的電平
while(1){
IoTGpioSetOutputVal(LED_GPIO, ledPin);
osDelay(10);
}
}
// 測試入口
static void GpioTest(void){
// 創(chuàng)建線程,大家還記得怎么創(chuàng)建的嗎
osThreadAttr_t attr = {"GpioInitMain", 0, NULL, 0, NULL, 1024, osPriorityNormal, 0, 0};
osThreadNew((osThreadFunc_t)GpioInitMain, NULL, &attr);
}
APP_FEATURE_INIT(GpioTest);- 編寫B(tài)IULD.gn文件。
static_library("led_gpio_demo"){
sources = [
"ledGpio.c"
]
include_dirs = [
"http://commonlibrary/utils_lite/include/",
"http://device/soc/hisilicon/hi3861v100/hi3861_adapter/kal/cmsis",
"http://base/iothardware/peripheral/interfaces/inner_api",
"http://device/soc/hisilicon/hi3861v100/sdk_liteos/include/"
]
}- 編寫app目錄下的BUILD.gn文件。
![OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū) OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū)](https://dl-harmonyos.51cto.com/images/202305/638e95f97846890f78749152cdd46dd103bb65.png?x-oss-process=image/resize,w_820,h_564)
- 編譯,燒錄。
- 重啟開發(fā)板,點擊user按鈕,觀察可編程led的狀態(tài)。
PWM
除了GPIO外,我們還可以通過PWM進行外部設(shè)備的控制,PWM是一種脈沖調(diào)制技術(shù),用于控制數(shù)字系統(tǒng)中的模擬信號。通過改變信號的占空比,PWM可以模擬出不同的電壓或電流值。在PWM信號中,周期固定,但高電平和低電平的持續(xù)時間可以不同。例如,一個50%的占空比意味著高電平和低電平各占一個周期的一半時間。當(dāng)占空比增加時,高電平的持續(xù)時間增加,低電平的持續(xù)時間減少,平均輸出功率也相應(yīng)增加。因此,我們還可以用PWM控制led的亮度,因為占空比會直接影響輸出的功率,功率會影響燈的亮度,算是中學(xué)物理了。廣泛應(yīng)用于電機控制、LED調(diào)光、音頻生成等。
占空比與燈泡亮度
![OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū) OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū)](https://dl-harmonyos.51cto.com/images/202305/716b2ff63f22299c38b5869928af12a6368cda.png?x-oss-process=image/resize,w_820,h_236)
![OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū) OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū)](https://dl-harmonyos.51cto.com/images/202305/c99a7fb37f683497c5c034f23e604379c244d1.png?x-oss-process=image/resize,w_648,h_253)
![OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū) OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū)](https://dl-harmonyos.51cto.com/images/202305/c89dbea17cf707fda509291a3e624e52e386ac.png?x-oss-process=image/resize,w_653,h_302)
總結(jié)
PWM有兩個重要的參數(shù),第一個是輸出頻率,頻率越高,則模擬的效果越好;第二個是占空比,占空比就是改變輸出模擬效果的電壓大小,占空比越大則模擬出的電壓越大。
PWM-API
很多基礎(chǔ)的IoT接口都已經(jīng)在GPIO-API上講到了,這里的介紹就相對簡單一點。
- 初始化PWM。
unsigned int IoTPwmInit(unsigned int port);通過參數(shù)port,指定PWM的端口號。
- 啟用PWM。
unsigned int IoTPwmStart(unsigned int port, unsigned short duty, unsigned int freq);參數(shù)解釋:
- port:PWM的端口號
- duty:PWM輸出的占空比
- freq:PWM輸出的頻率
- 停止PWM。
unsigned int IoTPwmStop(unsigned int port);通過參數(shù)port,停止PWM的輸出。
結(jié)合GPIO和PWM我們已經(jīng)可以去控制一些板子了,就不單獨設(shè)計PWM的案例了。
交通燈板的控制
交通燈板上一共有3個小板塊,紅綠燈,蜂鳴器,按鈕。下面逐個為大家講解如何使用對應(yīng)的API去控制他們。(涉及 GPIO控制設(shè)備和中斷函數(shù)處理 )
按鈕控制蜂鳴器
按一下按鈕,蜂鳴器鳴叫3秒。
- 新建樣例目錄。
applications/sample/wifi-iot/app/pwm_out_demo - 新建源文件和gn文件。
applications/sample/wifi-iot/app/pwm_out_demo/pwm.c
applications/sample/wifi-iot/app/pwm_out_demo/BUILD.gn - 編寫源文件,pwm.c。
#include <stdio.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "hi_io.h"
#include "iot_gpio.h"
// pwm接口
#include "iot_pwm.h"
#include "hi_pwm.h"
#define BUTTON_GPIO 8
#define BEE_GPIO 9
static int flag = 0;
// GPIO8中斷函數(shù)
static void ButtonPressed(char* atgs){
// 業(yè)務(wù)邏輯是讓蜂鳴器響三秒
if(flag == 0){
flag = 1;
}
}
// 主線程函數(shù)
static void PwmInitMain(void){
// 初始化GPIO模塊
IoTGpioInit(BUTTON_GPIO);
IoTGpioInit(BEE_GPIO);
// 設(shè)置引腳功能
hi_io_set_func(BEE_GPIO, HI_IO_FUNC_GPIO_9_PWM0_OUT);
hi_io_set_func(BUTTON_GPIO, HI_IO_FUNC_GPIO_8_GPIO);
// 設(shè)置GPIO輸出模式
IoTGpioSetDir(BEE_GPIO, IOT_GPIO_DIR_OUT);
IoTGpioSetDir(BUTTON_GPIO, IOT_GPIO_DIR_IN);
// 設(shè)置引腳上拉
hi_io_set_pull(BUTTON_GPIO, HI_IO_PULL_UP);
// 注冊中斷函數(shù)
IoTGpioRegisterIsrFunc(BUTTON_GPIO, IOT_INT_TYPE_EDGE, IOT_GPIO_EDGE_FALL_LEVEL_LOW, ButtonPressed, NULL);
// 循環(huán)監(jiān)聽flag,當(dāng)按鈕被按下時,flag會置為1,蜂鳴器工作3秒
while(1){
if(flag){
// 初始化PWM模塊
IoTPwmInit(HI_PWM_PORT_PWM0);
// 設(shè)置信號輸出, 端口,占空比,頻率
IoTPwmStart(HI_PWM_PORT_PWM0, 50, 4000);
// 鳴3秒
osDelay(300);
// 停止信號輸出
IoTPwmStop(HI_PWM_PORT_PWM0);
flag = 0;
}
osDelay(100);
}
}
// 測試入口
static void PwmTest(void){
osThreadAttr_t attr = {"GpioInitMain", 0, NULL, 0, NULL, 1024, osPriorityNormal, 0, 0};
osThreadNew((osThreadFunc_t)PwmInitMain, NULL, &attr);
}
APP_FEATURE_INIT(PwmTest);- 編寫B(tài)IULD.gn文件。
static_library("pwm_out_demo"){
sources = [
"pwm.c"
]
include_dirs = [
"http://commonlibrary/utils_lite/include/",
"http://device/soc/hisilicon/hi3861v100/hi3861_adapter/kal/cmsis",
"http://base/iothardware/peripheral/interfaces/inner_api",
"http://device/soc/hisilicon/hi3861v100/sdk_liteos/include/"
]
}- 編寫app目錄下的BUILD.gn文件。
![OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū) OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū)](https://dl-harmonyos.51cto.com/images/202305/42c538f658284b9d0091187e478d84ff5b41eb.png?x-oss-process=image/resize,w_752,h_535)
- 編譯,燒錄。
- 重啟開發(fā)板,點擊s1按鈕,可以聽到蜂鳴器鳴叫。
按鈕切換紅綠燈
按一下按鈕,紅綠燈順次切換。
- 新建樣例目錄。
applications/sample/wifi-iot/app/traffic_demo - 新建源文件和gn文件。
applications/sample/wifi-iot/app/traffic_demo/traffic.c
applications/sample/wifi-iot/app/traffic_demo/BUILD.gn - 編寫源文件,traffic.c。
#include <stdio.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "hi_io.h"
#include "iot_gpio.h"
#define BUTTON_GPIO 8
#define RED_GPIO 10
#define GREEN_GPIO 11
#define YELLOW_GPIO 12
// 每個燈的引腳編號
static int lights[3] = {RED_GPIO, GREEN_GPIO, YELLOW_GPIO};
// 每個燈的狀態(tài)
static int lightsStauts[3] = {0, 0, 0};
// 燈的索引
static int lightsIndex = 0;
// 中斷函數(shù)
static void ButtonPress(char *args){
// 點擊按鈕,要能夠切換紅綠燈,修改燈的狀態(tài)數(shù)組即可
for(unsigned int i = 0; i < 3; i++){
if(i == lightsIndex){
lightsStauts[i] = 1;
} else {
lightsStauts[i] = 0;
}
}
lightsIndex++;
if(lightsIndex >= 3){
lightsIndex = 0;
}
}
// 主函數(shù)
static void TrafficInitMain(void){
// GPIO初始化
IoTGpioInit(BUTTON_GPIO);
IoTGpioInit(RED_GPIO);
IoTGpioInit(GREEN_GPIO);
IoTGpioInit(YELLOW_GPIO);
// GPIO功能設(shè)置
hi_io_set_func(BUTTON_GPIO, HI_IO_FUNC_GPIO_8_GPIO);
hi_io_set_func(RED_GPIO, HI_IO_FUNC_GPIO_10_GPIO);
hi_io_set_func(GREEN_GPIO, HI_IO_FUNC_GPIO_11_GPIO);
hi_io_set_func(YELLOW_GPIO, HI_IO_FUNC_GPIO_12_GPIO);
// PGPIO輸入輸出設(shè)置
IoTGpioSetDir(BUTTON_GPIO, IOT_GPIO_DIR_IN);
IoTGpioSetDir(RED_GPIO, IOT_GPIO_DIR_OUT);
IoTGpioSetDir(GREEN_GPIO, IOT_GPIO_DIR_OUT);
IoTGpioSetDir(YELLOW_GPIO, IOT_GPIO_DIR_OUT);
// 引腳上拉
hi_io_set_pull(BUTTON_GPIO, HI_IO_PULL_UP);
// 中斷回調(diào)函數(shù)注冊
IoTGpioRegisterIsrFunc(BUTTON_GPIO, IOT_INT_TYPE_EDGE, IOT_GPIO_EDGE_FALL_LEVEL_LOW, ButtonPress, NULL);
while(1){
// 設(shè)置輸出電平,即可控制燈的點亮熄滅,其實和之前控制led一樣,只不過這次一下控制3個,用數(shù)組而已
for(unsigned int i = 0; i < 3; i++){
IoTGpioSetOutputVal(lights[i], lightsStauts[i]);
}
osDelay(100);
}
}
// 測試入口
static void TrafficTest(void){
osThreadAttr_t attr = {"TrafficInitMain", 0, NULL, 0, NULL, 1024, osPriorityNormal, 0, 0};
osThreadNew((osThreadFunc_t)TrafficInitMain, NULL, &attr);
}
APP_FEATURE_INIT(TrafficTest);- 編寫B(tài)IULD.gn文件。
static_library("traffic_demo"){
sources = [
"traffic.c"
]
include_dirs = [
"http://commonlibrary/utils_lite/include/",
"http://device/soc/hisilicon/hi3861v100/hi3861_adapter/kal/cmsis",
"http://base/iothardware/peripheral/interfaces/inner_api",
"http://device/soc/hisilicon/hi3861v100/sdk_liteos/include/"
]
}- 編寫app目錄下的BUILD.gn文件。
![OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū) OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·上]-開源基礎(chǔ)軟件社區(qū)](https://dl-harmonyos.51cto.com/images/202305/c3faefb881d40e0fac1804b6cc7683a64cf42b.png?x-oss-process=image/resize,w_820,h_623)
- 編譯,燒錄。
- 重啟開發(fā)板,點擊s1按鈕,可以看到紅綠燈正在切換。大家也可以修改代碼,實現(xiàn)有紅黃綠,綠黃紅那樣變化。
至此,交通燈板的三個小模塊就給大家介紹到這里,這些都是基本操作,僅在如何控制設(shè)備,與設(shè)備交互,大家可以根據(jù)自己的想法,創(chuàng)新一些業(yè)務(wù)邏輯,使用該功能板完成相應(yīng)的場景業(yè)務(wù)。
結(jié)束語
本片主要介紹了GPIO,PWM控制驅(qū)動的方案,并在交通燈板上進行了實際演示,以及三色燈的使用。后續(xù)的開發(fā)板硬件設(shè)備會在OpenHarmony智能開發(fā)套件[驅(qū)動開發(fā)篇·下]中詳細講解,包括人體紅外感應(yīng),光敏電阻,RGB燈效,溫濕度傳感器,oled屏幕的點亮。
[本來每一個案例后面都做了實際效果演示視頻的,但是視頻好像上傳不了,那暫時就沒有視頻演示了。]






























