性无码一区二区三区在线观看,少妇被爽到高潮在线观看,午夜精品一区二区三区,无码中文字幕人妻在线一区二区三区,无码精品国产一区二区三区免费

程序員小哈
認(rèn)證:優(yōu)質(zhì)創(chuàng)作者
作者動(dòng)態(tài)
自動(dòng)洗碗機(jī)綜合實(shí)例第二講 - 最小系統(tǒng)核心板PCB繪制
2024-07-18 09:21
自動(dòng)洗碗機(jī)綜合實(shí)例第一講 - 最小系統(tǒng)核心板原理圖繪制
2024-07-16 09:40
線路板焊接的干貨都在這里呢
2024-07-14 12:08
基于單片機(jī)的智能風(fēng)扇DIY總結(jié)
2024-07-13 14:42
基于HAL庫(kù)實(shí)現(xiàn)按鍵(外部中斷)翻轉(zhuǎn)一個(gè)LED
2024-06-30 14:02

基于鴻蒙OS的按鍵驅(qū)動(dòng)

按鍵作為常用的輸入系統(tǒng),如何準(zhǔn)確并高效的獲取按鍵值,是一個(gè)經(jīng)常要面對(duì)的問(wèn)題,今天我們看看在鴻蒙系統(tǒng)中,如何得到獨(dú)立按鍵的按鍵值。

實(shí)現(xiàn)目標(biāo)

我們這次以Hi3861核心板左下角的USER按鍵S2為例,當(dāng)按鍵按下時(shí),通過(guò)USB Type-c對(duì)應(yīng)的串口輸出信息。

按鍵S2在實(shí)物中的對(duì)應(yīng)關(guān)系如下圖黃線所示:

按鍵原理圖

核心板左下角的按鍵S2的原理圖如下:

當(dāng)S2被按下之后,GPIO05與GND相連,此時(shí)GPIO05輸入為低電平。

代碼實(shí)現(xiàn)

實(shí)現(xiàn)方式一:讀取輸入IO的狀態(tài)
#include <stdio.h>

#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"
#include "wifiiot_errno.h"

static void Key_Task(const char* arg)
{	
    (void)arg;
	
    printf("Enter the Key_Task ... \n");
	
    while (1) 
    {
        WifiIotGpioValue wigv;

        GpioGetInputVal(WIFI_IOT_IO_NAME_GPIO_5,&wigv);

        if (wigv == WIFI_IOT_GPIO_VALUE0)
        {
            usleep(10*1000);        //10ms

            while(1)
            {
                GpioGetInputVal(WIFI_IOT_IO_NAME_GPIO_5,&wigv);
                if (wigv == WIFI_IOT_GPIO_VALUE1){
                    printf("[DEMO] GPIO05 Low level.\n");
                    break;
                }        
            }                           
        }
    }

    return;
}

static void KeyExampleEntry(void)
{
    unsigned int ret = 0;
    GpioInit();
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_5, WIFI_IOT_IO_FUNC_GPIO_5_GPIO);
    GpioSetDir(WIFI_IOT_GPIO_IDX_5, WIFI_IOT_GPIO_DIR_IN);

    if (ret != WIFI_IOT_SUCCESS)
    {
        printf("===== ERROR ======gpio -> GpioSetDir ret:%d\r\n", ret);
        return;
    }
	
    osThreadAttr_t attr = {0};
	
    attr.name = "Key_Task";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 1024;
    attr.priority = osPriorityNormal;
	
    if(osThreadNew((osThreadFunc_t)Key_Task,NULL,&attr) == NULL)
    {
        printf("Failed to create Key_Task !\n");
    }	
}

SYS_RUN(KeyExampleEntry);

編譯代碼:

python build.py wifiiot

更新固件之后重啟最小系統(tǒng)板,打開(kāi)串口助手,點(diǎn)擊核心板上的USER按鍵S2,串口助手輸出信息如下:

注意:此實(shí)例新建了一個(gè)任務(wù)用于循環(huán)讀取按鍵的狀態(tài),KeyExampleEntry作為應(yīng)用程序的入口函數(shù),不能隨意使用while(1)這種耗時(shí)的操作,必須快速返回,否則會(huì)妨礙鴻蒙OS中其他應(yīng)用程序的運(yùn)行,因此,在這個(gè)入口函數(shù)中創(chuàng)建一個(gè)按鍵狀態(tài)監(jiān)測(cè)的專屬任務(wù)(線程)用于判斷按鍵的狀態(tài)。

GPIO中斷

通過(guò)上面的原理圖我們可知,當(dāng)按鍵S2沒(méi)有被按下的時(shí)候,GPIO05為默認(rèn)狀態(tài)高電平,當(dāng)按鍵S2被按下時(shí),GPIO05與GND相連,GPIO05被拉低,當(dāng)松開(kāi)按鍵S2的時(shí)候,GPIO05又恢復(fù)高電平。

在此過(guò)程中,當(dāng)按鍵S2被按下時(shí),GPIO05會(huì)收到一個(gè)由高到低的電平變化,我們稱這個(gè)過(guò)程為下降沿;當(dāng)按鍵S2被松開(kāi)時(shí),GPIO05會(huì)收到一個(gè)由低到高的電平變化,我們稱這個(gè)過(guò)程為上升沿。

綜上所述,在不考慮抖動(dòng)影響的前提下,每次按鍵被按下,GPIO05將會(huì)收到一個(gè)下降沿;按鍵被釋放,GPIO05會(huì)收到一個(gè)上升沿。

我們?cè)贕PIO05這個(gè)引腳上注冊(cè)一個(gè)邊沿觸發(fā)函數(shù)(上升沿或者下降沿觸發(fā)都可以),那么這個(gè)注冊(cè)的邊沿觸發(fā)回調(diào)函數(shù)被調(diào)用一次,理論上就是有一次按鍵的動(dòng)作發(fā)生。

#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"
#include "wifiiot_errno.h"

/* gpio callback func */
void gpio5_isr_func(char *arg)
{
    (void)arg;
    printf("----- gpio05 isr success -----\r\n");
}

static void KeyExampleEntry(void)
{
    unsigned int ret = 0;
    GpioInit();
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_5, WIFI_IOT_IO_FUNC_GPIO_5_GPIO);
    GpioSetDir(WIFI_IOT_GPIO_IDX_5, WIFI_IOT_GPIO_DIR_IN);
    //IoSetPull(WIFI_IOT_GPIO_IDX_5,WIFI_IOT_IO_PULL_UP);
    
    if (ret != WIFI_IOT_SUCCESS) 
    {
        printf("===== ERROR ======gpio -> GpioSetDir ret:%d\r\n", ret);
        return;
    }
    ret = GpioRegisterIsrFunc(WIFI_IOT_GPIO_IDX_5,WIFI_IOT_INT_TYPE_EDGE,WIFI_IOT_GPIO_EDGE_RISE_LEVEL_HIGH, gpio5_isr_func, NULL);
    if (ret != WIFI_IOT_SUCCESS) 
    {
        printf("===== ERROR ======gpio -> hi_gpio_register_isr_function ret:%d\r\n", ret);
    }
}

SYS_RUN(KeyExampleEntry);
代碼說(shuō)明:
  1. WIFI_IOT_IO_NAME_GPIO_5是與按鍵S2相連的GPIO,要實(shí)現(xiàn)按鍵中斷捕獲,需要先使用IoSetFunc() 函數(shù)進(jìn)行端口功能重定義;

  2. 調(diào)用GpioSetDir()函數(shù),設(shè)置GPIO05為輸入,并通過(guò)IoSetPull() 函數(shù)將端口設(shè)置為上拉輸入(Pull Up);

  3. 調(diào)用GpioRegisterIsrFunc()函數(shù),完成GPIO05和回調(diào)函數(shù)gpio5_isr_func()的注冊(cè)綁定,設(shè)置觸發(fā)模式為上升沿觸發(fā):WIFI_IOT_GPIO_EDGE_RISE_LEVEL_HIGH,當(dāng)按鍵S2被抬起的時(shí)候,產(chǎn)生上升沿,觸發(fā)回調(diào)函數(shù)gpio5_isr_func()工作。

通過(guò)上面兩種方式,我們學(xué)會(huì)了獨(dú)立按鍵狀態(tài)的獲取、鴻蒙系統(tǒng)中如何創(chuàng)建任務(wù)和外部中斷的使用,利用此代碼,我們還可以用于識(shí)別熱釋紅外傳感器的響應(yīng)信號(hào)。

小哈有話說(shuō)

最近在鴻蒙交流群中看到下面一大批開(kāi)發(fā)板要移植鴻蒙操作系統(tǒng)了,等到這些廠商將板卡移植好了,那么鴻蒙就真的成氣候了,作為一個(gè)嵌入式開(kāi)發(fā)者,學(xué)習(xí)一個(gè)實(shí)時(shí)操作系統(tǒng)是必不可少的,學(xué)什么都是學(xué),為什么不學(xué)一個(gè)有前途的呢?

歡迎關(guān)注

程序員小哈帶你玩轉(zhuǎn)嵌入式,搜索:嵌入式從0到1,更多干貨等著你。

聲明:本內(nèi)容為作者獨(dú)立觀點(diǎn),不代表電子星球立場(chǎng)。未經(jīng)允許不得轉(zhuǎn)載。授權(quán)事宜與稿件投訴,請(qǐng)聯(lián)系:editor@netbroad.com
覺(jué)得內(nèi)容不錯(cuò)的朋友,別忘了一鍵三連哦!
贊 1
收藏 2
關(guān)注 69
成為作者 賺取收益
全部留言
0/200
成為第一個(gè)和作者交流的人吧