0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

i.MX6ULL 驅(qū)動開發(fā)7—按鍵輸入捕獲與GPIO輸入配置與高低電平讀取

碼農(nóng)愛學習 ? 來源:碼農(nóng)愛學習 ? 作者:碼農(nóng)愛學習 ? 2022-05-24 09:11 ? 次閱讀

前面幾篇文章,從最基礎(chǔ)的寄存器點燈,到設備樹點燈,再到GPIO子系統(tǒng)點燈,一步步了解嵌入式Linux開發(fā)的各種點燈原理。

點燈用到的都是GPIO的輸出功能,這篇,通過按鍵的使用,來學習GPIO輸入功能的使用。

1 硬件介紹

1.1 板子上按鍵原理圖

先來看原理圖,我板子上有4個按鍵sw1~sw4:

1.1.1 SW1

SW1是板子的系統(tǒng)復位按鍵,不可編程使用

poYBAGKLpYCAWgGbAABoFfKP0ZQ203.png

1.1.2 SW2、SW3

SW2:SNVS_TAMPER1,GPIO5_1

平時是低電平,按下去是高電平。

SW3:ONOFF

它也是系統(tǒng)級的按鍵,用于長按進行開關(guān)機。

poYBAGKLpYiAIG8MAAEcqcr0uho168.png

1.1.3 SW4

SW4是BOOT_MODE1腳,用來進行串行燒錄模式切換,需要再與復位鍵配合使用。

本篇僅測試按鍵功能,因此可以該按鍵。

pYYBAGKLpZGAK9H6AAC3fSuYo7o389.png

1.1.4 使用其中2個按鍵

板子上這4個按鍵的功能特性如下表:

poYBAGKLpZiAd5wyAAGktTu1GEw782.png

本實驗使用SW2和SW4這兩個按鍵來進行實驗。

pYYBAGKLpaCAGqlpAAYpy1niae8060.png

2 軟件編寫

2.1 修改設備樹文件

2.1.1 修改iomuxc節(jié)點

修改imx6ull-myboard.dts,在iomuxc節(jié)點的imx6ull-evk字節(jié)點下創(chuàng)建一個名為pinctrl_key的子節(jié)點,節(jié)點內(nèi)容如下:

pinctrl_key: keygrp { 
    fsl,pins = < 
        MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01    0x3080 /* SW2 */
        MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11      0xF080 /* SW4 */
    >; 
};

這部分是對引腳進行配置,這兩個引腳的定義是在imx6ull-pinfunc-snvs.h文件中:

poYBAGKLpamAHMjzAAHyvI3nUkY061.png

引腳宏定義后面的值,是對引腳功能的配置:

SW2:0x3080,即0011 0000 1000 0000

SW4:0xF080,即1000 0000 1000 0000

對照之前講解GPIO的PAD寄存器的配置,根據(jù)兩個按鍵的實際電路配置上拉或下拉。

/*
*bit 16:0 HYS關(guān)閉
*bit [15:14]: [00]下拉 [01]47k上拉 [10]100k上拉 [11]22k上拉 <---
*bit [13]: [0]kepper功能 [1]pull功能
*bit [12]: [0]pull/keeper-disable [1]pull/keeper-enable
*bit [11]: 0 關(guān)閉開路輸出
*bit [10:8]: 00 保留值
*bit [7:6]: 10 速度100Mhz
*bit [5:3]: 000 輸出disable <---
*bit [2:1]: 00 保留值
*bit [0]: 0 低轉(zhuǎn)換率
*/

注:SW4 (MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11)這個GPIO,在設備中實際已經(jīng)被其它設備(spi4)使用了。

在imx6ull-myboard.dts的300多行處,有:

pinctrl_spi4: spi4grp {
 fsl,pins = <
     MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10        0x70a1
     MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11        0x70a1
     MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07      0x70a1
     MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08      0x80000000
     >;
};

理論上我們應該把這里的配置給注釋掉,因為1個IO是不能同時進行2種功能的。由于本次實驗不使用spi4,暫且也先不管它,看看會有什么影響,如果影響了本實驗,再給把這里的配置給注掉。

2.1.2 添加key節(jié)點

在根節(jié)點下創(chuàng)建名為key的按鍵節(jié)點,內(nèi)容如下:

key { 
    #address-cells = <1>; 
    #size-cells = <1>; 
    compatible = "myboard-key"; 
    pinctrl-names = "default"; 
    pinctrl-0 = <&pinctrl_key>; 
    key1-gpio = <&gpio5 1 GPIO_ACTIVE_HIGH>;   /* SW2 */
    key2-gpio = <&gpio5 11 GPIO_ACTIVE_LOW>;   /* SW4 */
    status = "okay"; 
}; 

2.2 編寫按鍵驅(qū)動程序

按鍵驅(qū)動,也屬于字符設備驅(qū)動,和之前的字符設備驅(qū)動的框架一樣,主要的修改點在按鍵的硬件初始化配置已經(jīng)按鍵的讀取。

新建一個key-Bsp.c

2.2.1 按鍵的硬件初始化

初始化的流程,就是使用OF函數(shù)來從設備樹中獲取key節(jié)點,然后使用GPIO子系統(tǒng)的API函數(shù),將GPIO配置為輸入。

static int keyio_init(void)
{
    keydev.nd = of_find_node_by_path("/key");
    if (keydev.nd== NULL) 
    {
        return -EINVAL;
    }

    keydev.key1_gpio = of_get_named_gpio(keydev.nd ,"key1-gpio", 0);
    keydev.key2_gpio = of_get_named_gpio(keydev.nd ,"key2-gpio", 0);
    if ((keydev.key1_gpio < 0)||(keydev.key2_gpio < 0))
    {
        printk("can't get key\r\n");
        return -EINVAL;
    }
    printk("key1_gpio=%d, key2_gpio=%d\r\n", keydev.key1_gpio, keydev.key2_gpio);

    /* 初始化key所使用的IO */
    gpio_request(keydev.key1_gpio, "key1");    /* 請求IO */
    gpio_request(keydev.key2_gpio, "key2");    /* 請求IO */
    gpio_direction_input(keydev.key1_gpio);    /* 設置為輸入 */
    gpio_direction_input(keydev.key2_gpio);    /* 設置為輸入 */
    return 0;
}

2.2.2 讀取按鍵的值

讀取按鍵的值,也是GPIO子系統(tǒng)的API函數(shù)來讀取。讀取到按鍵的值后,將該值傳遞出來給應用層使用,注意這里使用了原子操作的方式atomic_set和atomic_read實現(xiàn)數(shù)據(jù)的寫入和讀取。

/* 定義按鍵值 */
#define KEY1VALUE      0X01    /* 按鍵值       */
#define KEY2VALUE      0X02    /* 按鍵值       */
#define INVAKEY        0X00    /* 無效的按鍵值 */

static ssize_t key_read(struct file *filp, char __user *buf, size_t cnt, loff_t *offt)
{
    int ret = 0;
    int value;
    struct key_dev *dev = filp->private_data;

    if (gpio_get_value(dev->key1_gpio) == 1)         /* key1按下 */
    {
        printk("get key1: high\r\n");
        while(gpio_get_value(dev->key1_gpio));       /* 等待按鍵釋放 */
        atomic_set(&dev->keyvalue, KEY1VALUE);
    }
    else if (gpio_get_value(dev->key2_gpio) == 0)    /* key2按下 */
    {
        printk("get key2: low\r\n");
        while(!gpio_get_value(dev->key2_gpio));      /* 等待按鍵釋放 */
        atomic_set(&dev->keyvalue, KEY2VALUE);
    }
    else
    {
        atomic_set(&dev->keyvalue, INVAKEY);        /* 無效的按鍵值 */
    }

    value = atomic_read(&dev->keyvalue);
    ret = copy_to_user(buf, &value, sizeof(value));
    return ret;
}

2.3 編寫按鍵應用程序

新建一個key-App.c

按鍵的應用層程序,主要就通過驅(qū)動程序提供的按鍵讀取接口,來循環(huán)讀取按鍵的值,并在按鍵按下時,將按鍵的值打印出來。

/* 定義按鍵值 */
#define KEY1VALUE   0X01
#define KEY2VALUE   0X02
#define INVAKEY     0X00

int main(int argc, char *argv[])
{
    int fd, ret;
    char *filename;
    int keyvalue;

    if(argc != 2)
    {
        printf("Error Usage!\r\n");
        return -1;
    }

    filename = argv[1];

    /* 打開key驅(qū)動 */
    fd = open(filename, O_RDWR);
    if(fd < 0)
    {
        printf("file %s open failed!\r\n", argv[1]);
        return -1;
    }

    /* 循環(huán)讀取按鍵值數(shù)據(jù)! */
    while(1)
    {
        read(fd, &keyvalue, sizeof(keyvalue));
        if (keyvalue == KEY1VALUE)
        {
            printf("KEY1 Press, value = %#X\r\n", keyvalue);
        }
        else if (keyvalue == KEY2VALUE)
        {
            printf("KEY2 Press, value = %#X\r\n", keyvalue);
        }
    }

    ret= close(fd); /* 關(guān)閉文件 */
    if(ret < 0)
    {
        printf("file %s close failed!\r\n", argv[1]);
        return -1;
    }
    return 0;
}

3 實驗測試

3.1 編譯程序

3.1.1 編譯設備樹

編譯設備樹文件,并將編譯出的dtb文件復制到啟動文件夾:

pYYBAGKLpbiAQbODAAE2bDoXQB8818.png

網(wǎng)絡方式啟動開發(fā)板,查看key節(jié)點:

poYBAGKLpb-ALdDQAAB4JCpPP_g827.png

3.1.2 編譯按鍵驅(qū)動程序

pYYBAGKLpcWAA4N1AAGM4BH_H_4238.png

3.1.3 編譯按鍵應用程序

poYBAGKLpcyAbDOhAADtMDDW8fo238.png

3.2 測試

pYYBAGKLpdKAcp5JAACb4X-uFHc021.png

3.3 查看CPU占用率

先Ctrl+C結(jié)束掉此按鍵進程,然后使用如下指令來后臺運行按鍵程序:

./key-App /dev/key &

然后再使用指令:

top

來查看CPU是使用情況。從下圖可以看出,此時CPU的使用率是99.8%,全被按鍵檢查程序占用了,因為按鍵程序中有個while循環(huán)在一直讀取按鍵的值。

poYBAGKLpdqAU5h5AAD4q6Bv6d0467.png

使用指令:

ps

查看按鍵的進程號,如下圖為149,再使用:

kill -9 149

來殺掉按鍵進程,然后再使用top指令查看,可以看到CPU的使用率又變回了0。

pYYBAGKLpfSAPYlbAAC5aLytSzg805.png

實際的按鍵使用中,一般不會使用本篇的這種持續(xù)檢測導致CPU占滿的方式,本篇只是先來介紹GPIO的輸入功能的使用,后續(xù)會使用更加高效的按鍵檢測機制來實現(xiàn)按鍵檢測功能。

4 總結(jié)

本篇主要介紹了i.MX6ULL的按鍵檢測的使用,主要的知識點是設備樹的修改,以及GPIO的輸入配置與高低電平的讀取。

poYBAGKLpf2AEdaoAADLKUk862g915.png

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 嵌入式
    +關(guān)注

    關(guān)注

    5052

    文章

    18910

    瀏覽量

    300746
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11161

    瀏覽量

    208468
  • GPIO
    +關(guān)注

    關(guān)注

    16

    文章

    1182

    瀏覽量

    51738
  • i.MX6
    +關(guān)注

    關(guān)注

    1

    文章

    37

    瀏覽量

    16262
收藏 人收藏

    評論

    相關(guān)推薦

    使用i.MX6ULL開發(fā)板進行Linux根文件系統(tǒng)的完善

    上一篇推文講了怎么移植根文件系統(tǒng),并在i.MX6ULL開發(fā)板中運行起來,但是會出現(xiàn)一些提示,現(xiàn)在來進行根文件的完善。
    發(fā)表于 10-17 11:13 ?740次閱讀

    移植NXP官方linux 5.4內(nèi)核到i.MX6ULL開發(fā)

    本文描述移植NXP官方 linux 5.4 內(nèi)核到i.MX6ULL開發(fā)板。
    發(fā)表于 12-19 11:10 ?1966次閱讀

    移植5.4內(nèi)核到迅為I.MX6ULL開發(fā)

    編譯器的搭建,可以參考“i.mx6ull終結(jié)者開發(fā)板使用手冊”的4.3章節(jié)“搭建交叉編譯環(huán)境”和29.1章節(jié) 安裝第三方庫。編譯內(nèi)核為了編譯方便,我們可以創(chuàng)建一個腳本,我們在命令行輸入“vi
    發(fā)表于 06-29 10:13

    迅為i.MX6ULL開發(fā)板資料下載,讓Linux學習更輕松

    引腳 i.MX6ULL開發(fā)板底板資源 I.MX6ULL 開發(fā)板板載資源非常豐富,幾乎已經(jīng)把 i.MX6ULL 的功能發(fā)揮到了極致。1. 電
    發(fā)表于 09-23 18:07

    i.MX6ULL開發(fā)板硬件資源

    迅為i.MX6ULL 終結(jié)者開發(fā)板硬件資源非常豐富,幾乎將 i.MX6ULL 芯片的所有資源都擴展引出到底板上了,底板提供了豐富的外設接口,開發(fā)板的尺寸是 190mm*125mm,充分
    發(fā)表于 12-29 06:18

    i.MX6ULL核心板資源

    路多功能音頻通道多路 SPI、IIC、定時器、PWM、DMA、RTC、看門狗等常用外設規(guī)格參數(shù):核心板配置CPU 型號 NXP i.MX6ULL(MCIMX6Y2C),ARM Cortex A
    發(fā)表于 07-12 17:50

    初識 i.MX6ULL 寄存器

    裸機開發(fā)_L1_匯編LED實驗0. 本節(jié)目標1. 硬件層電路2. 初識 i.MX6ULL 寄存器2.1 i.MX6ULL 時鐘控制寄存器2.2 i.MX6ULL IO復用寄存器2.3
    發(fā)表于 12-20 07:13

    關(guān)于i.MX6ULL配置GPIO

    處理器,它的GPIO外設應該如何配置呢?今天小編就將通過飛凌嵌入式的OKMX6ULL-S開發(fā)板來為大家詳細介紹。一、i.MX6ULL處理器的
    發(fā)表于 08-05 10:37

    飛凌i.MX6ULL開發(fā)板的評測,再次進階擁有更高的性價比

    處理器MCIMX6Y2開發(fā)設計,采用先進的ARMCortex-A7內(nèi)核,運行速度高達800MHz。i.MX6ULL應用處理器包括一個集成的電源管理模塊,降低了外接電源的復雜性,并簡化了
    發(fā)表于 10-27 11:55 ?1419次閱讀
    飛凌<b class='flag-5'>i.MX6ULL</b><b class='flag-5'>開發(fā)</b>板的評測,再次進階擁有更高的性價比

    STM32F103輸入捕獲--按鍵

    初始化七、中斷初始化八、中斷函數(shù)8.1 進入中斷的條件8.2 高電平捕獲的流程8.3 時間的計算8.4 偽代碼8.5 可執(zhí)行代碼九、結(jié)果展示十、存在的問題一、輸入捕獲
    發(fā)表于 11-30 13:51 ?28次下載
    STM32F103<b class='flag-5'>輸入</b><b class='flag-5'>捕獲</b>--<b class='flag-5'>按鍵</b>

    基于NXP i.MX6ULL處理器的FETMX6ULL-C核心板

    合作伙伴,飛凌不負美譽,基于i.MX6ULL匠心打造的FETMX6ULL-S核心板一經(jīng)問世便好評不斷,且已有數(shù)百家來自工業(yè)、醫(yī)療、電力、物聯(lián)網(wǎng)等行業(yè)的用戶采用此款核心板快速完成了整機產(chǎn)品的開發(fā)上市。
    發(fā)表于 04-11 15:05 ?1103次閱讀
    基于NXP <b class='flag-5'>i.MX6ULL</b>處理器的FETMX<b class='flag-5'>6ULL</b>-C核心板

    i.MX6ULL驅(qū)動開發(fā)4——點亮LED(寄存器版)

    本篇主要介紹了如何通過操作寄存器來點亮i.MX6ULL開發(fā)板上的led,通過編寫LED對應的驅(qū)動程序和應用程序,實現(xiàn)程序設計的分層。
    的頭像 發(fā)表于 05-21 21:26 ?2892次閱讀
    【<b class='flag-5'>i.MX6ULL</b>】<b class='flag-5'>驅(qū)動</b><b class='flag-5'>開發(fā)</b>4——點亮LED(寄存器版)

    i.MX6ULL學習筆記:GPIO按鍵輸入捕獲

    掌握GPIO輸入輸出是必備技能,這篇推文繼續(xù)來學習操作GPIO,這篇主要學習GPIO輸入,通過使用
    的頭像 發(fā)表于 04-06 10:37 ?1040次閱讀

    【北京迅為】i.MX6ULL開發(fā)板移植 Debian 文件系統(tǒng)

    【北京迅為】i.MX6ULL開發(fā)板移植 Debian 文件系統(tǒng)
    的頭像 發(fā)表于 02-10 15:34 ?1068次閱讀
    【北京迅為】<b class='flag-5'>i.MX6ULL</b><b class='flag-5'>開發(fā)</b>板移植 Debian 文件系統(tǒng)

    基于i.MX6ULL的掉電檢測設計與軟件測試

    基于i.MX6ULL的掉電檢測設計與軟件測試基于i.MX6ULL平臺設計實現(xiàn)掉電檢測功能,首先選擇一路IO,利用IO電平變化觸發(fā)中斷,在編寫驅(qū)動
    的頭像 發(fā)表于 11-09 10:40 ?750次閱讀
    基于<b class='flag-5'>i.MX6ULL</b>的掉電檢測設計與軟件測試