zigbee 中的按键驱动的设置

对于按键驱动修改不错的博文:https://wenku.baidu.com/view/12e61922aef8941ea66e05b9.html

https://blog.csdn.net/stone8761/article/details/79563594

此外,使用的TI BLE协议栈版本是1.3.2。

KEY服务API

KEY服务一共有7个API。分别是:

  • HalKeyInit()
  • HalKeyConfig()
  • HalKeyRead()
  • HalKeyEnterSleep()
  • HalKeyExitSleep()
  • HalKeyPoll()
  • HalKeyPressed()

其中,HalKeyInit()、HalKeyConfig()、HalKeyRead()、HalKeyPoll()是我们需要关注的。

1.五向按键的硬件原理

五向按键的五个方向:上、下、左、右、垂直向下。原理是只要五向按键有按压动作,在JOY_MOVE引脚会产生中断,此时再去采集JOY_LEVEL的电压,根据电压范围来判断当前的五向按键的方向。原理还是很简单的,电路倒是有点复杂。

此外,开发板还有一个单独的按键S1。

2.KEY服务API源码分析

因为我使用的是开发板的例程,五向按键部分的电路和官方是不一样的,因此使用开发板提供的修改文件hal_key.c。

2.1 HalKeyInit()

  1. /**************************************************************************************************

  2.  

    * @fn HalKeyInit

  3.  

    *

  4.  

    * @brief Initilize Key Service

  5.  

    *

  6.  

    * @param none

  7.  

    *

  8.  

    * @return None

  9.  

    **************************************************************************************************/

  10.  

    void HalKeyInit( void )

  11.  

    {

  12.  

    #if (HAL_KEY == TRUE)

  13.  

    /* Initialize previous key to 0 */

  14.  

    halKeySavedKeys = HAL_KEY_CODE_NOKEY;

  15.  

  16.  

    /* The advanced remote doesn‘t have the same 8X8 row/column matrix as in other

  17.  

    * products. Instead, a 3X16 row/column matrix is used, with the rows continuing

  18.  

    * to be utilized by GPIOs, but the columns are generated via a 16 bit

  19.  

    * shift register. Controls for the shift register are, however, utilized with

  20.  

    * GPIOs.

  21.  

    *

  22.  

    * Another difference is that the GPIOs utilized for the rows are split between

  23.  

    * P0 and P1.

  24.  

    */

  25.  

    //ghostyu from EM

  26.  

    HAL_KEY_SW_6_SEL &= ~(HAL_KEY_SW_6_BIT); /* Set pin function to GPIO */

  27.  

    HAL_KEY_SW_6_DIR &= ~(HAL_KEY_SW_6_BIT); /* Set pin direction to Input */

  28.  

    HAL_KEY_JOY_MOVE_SEL &= ~(HAL_KEY_JOY_MOVE_BIT); /* Set pin function to GPIO */

  29.  

    HAL_KEY_JOY_MOVE_DIR &= ~(HAL_KEY_JOY_MOVE_BIT); /* Set pin direction to Input */

  30.  

  31.  

    /* Initialize callback function */

  32.  

    <span style="font-size:10px;">pHalKeyProcessFunction = NULL;</span>

  33.  

  34.  

    /* Start with key is not configured */

  35.  

    HalKeyConfigured = FALSE;

  36.  

  37.  

    <span style="font-size:10px;">halKeyTimerRunning = FALSE;</span>

  38.  

    #endif /* HAL_KEY */

  39.  

    }

这里主要是对两个引脚(一个用于触发中断,一个用于AD采样)进行设置,并设置相关文件域的全局变量,包括pHalKeyProcessFunction、HalKeyConfigured、halKeyTimerRunning。在使用KEY服务前必须要调用该函数,在TI的例程中只要开启相关宏定义即可,这时会在HalDriverInit()中进行初始化:

2.2 HalKeyConfig()

  1. /**************************************************************************************************

  2.  

    * @fn HalKeyConfig

  3.  

    *

  4.  

    * @brief Configure the Key serivce

  5.  

    *

  6.  

    * @param interruptEnable - TRUE/FALSE, enable/disable interrupt

  7.  

    * cback - pointer to the CallBack function

  8.  

    *

  9.  

    * @return None

  10.  

    **************************************************************************************************/

  11.  

    void HalKeyConfig (bool interruptEnable, halKeyCBack_t cback)

  12.  

    {

  13.  

    #if (HAL_KEY == TRUE)

  14.  

    /* Enable/Disable Interrupt */

  15.  

    Hal_KeyIntEnable = interruptEnable;

  16.  

  17.  

    /* Register the callback fucntion */

  18.  

    pHalKeyProcessFunction = cback;

  19.  

  20.  

    /* Determine if interrupt is enabled or not */

  21.  

    if (Hal_KeyIntEnable)

  22.  

    {

  23.  

  24.  

    //ghostyu from EM

  25.  

    /* Rising/Falling edge configuratinn */

  26.  

    PICTL &= ~(HAL_KEY_SW_6_EDGEBIT); /* Clear the edge bit */

  27.  

    /* For rising edge, the bit must be set. */

  28.  

    PICTL &= ~(HAL_KEY_SW_6_EDGEBIT);

  29.  

  30.  

  31.  

  32.  

    /* Interrupt configuration:

  33.  

    * - Enable interrupt generation at the port

  34.  

    * - Enable CPU interrupt

  35.  

    * - Clear any pending interrupt

  36.  

    */

  37.  

    HAL_KEY_SW_6_ICTL |= HAL_KEY_SW_6_ICTLBIT;

  38.  

    HAL_KEY_SW_6_IEN |= HAL_KEY_SW_6_IENBIT;

  39.  

    HAL_KEY_SW_6_PXIFG = ~(HAL_KEY_SW_6_BIT);

  40.  

  41.  

  42.  

  43.  

    /* Rising/Falling edge configuratinn */

  44.  

  45.  

    HAL_KEY_JOY_MOVE_ICTL &= ~(HAL_KEY_JOY_MOVE_EDGEBIT); /* Clear the edge bit */

  46.  

    /* For falling edge, the bit must be set. */

  47.  

  48.  

    HAL_KEY_JOY_MOVE_ICTL |= HAL_KEY_JOY_MOVE_EDGEBIT;

  49.  

  50.  

  51.  

    /* Interrupt configuration:

  52.  

    * - Enable interrupt generation at the port

  53.  

    * - Enable CPU interrupt

  54.  

    * - Clear any pending interrupt

  55.  

    */

  56.  

    HAL_KEY_JOY_MOVE_ICTL |= HAL_KEY_JOY_MOVE_ICTLBIT;

  57.  

    HAL_KEY_JOY_MOVE_IEN |= HAL_KEY_JOY_MOVE_IENBIT;

  58.  

    HAL_KEY_JOY_MOVE_PXIFG = ~(HAL_KEY_JOY_MOVE_BIT);

  59.  

  60.  

  61.  

    /* Do this only after the hal_key is configured - to work with sleep stuff */

  62.  

    if (HalKeyConfigured == TRUE)

  63.  

    {

  64.  

    osal_stop_timerEx( Hal_TaskID, HAL_KEY_EVENT); /* Cancel polling if active */

  65.  

    }

  66.  

    }

  67.  

    else /* Interrupts NOT enabled */

  68.  

    {

  69.  

    HAL_KEY_SW_6_ICTL &= ~(HAL_KEY_SW_6_ICTLBIT); /* don‘t generate interrupt */

  70.  

    HAL_KEY_SW_6_IEN &= ~(HAL_KEY_SW_6_IENBIT); /* Clear interrupt enable bit */

  71.  

  72.  

  73.  

    osal_start_timerEx (Hal_TaskID, HAL_KEY_EVENT, HAL_KEY_POLLING_VALUE); /* Kick off polling */

  74.  

    }

  75.  

  76.  

    /* Key now is configured */

  77.  

    HalKeyConfigured = TRUE;

  78.  

    #endif /* HAL_KEY */

  79.  

    }

该函数对KEY服务进行配置,形参有2个:interruptEnable, cback。

interruptEnable用来选择按键的扫描方式,KEY服务的按键扫描方式有两种,一种是循环扫描,另外一种是中断扫描。循环扫描和中断扫描的具体过程后面会介绍。cback就是应用层传给HAL KEY服务的回调函数,用于通知应用层相关按键的触发动作。回调函数的原型是:

typedef void (*halKeyCBack_t) (uint8 keys, uint8 state);

keys表示哪个按键被按下,state表示按键是怎么被按下的,TI的HAL进行如下定义:

state中HAL_KEY_STATE_SHIFT好像不怎么用得到,用HAL_KEY_STATE_NORMAL比较多。

2.3 HalKeyConfig()

  1. /**************************************************************************************************

  2.  

    * @fn HalKeyRead

  3.  

    *

  4.  

    * @brief Read the current value of a key

  5.  

    *

  6.  

    * @param None

  7.  

    *

  8.  

    * @return keys - current keys status

  9.  

    **************************************************************************************************/

  10.  

    uint8 HalKeyRead ( void )

  11.  

    {

  12.  

    uint8 keys = 0;

  13.  

  14.  

    //注意这里的SW6对应SmartRF开发板上的S1,是高电平有效

  15.  

    if ((HAL_KEY_SW_6_PORT & HAL_KEY_SW_6_BIT)) /* Key is active HIGH */

  16.  

    {

  17.  

    keys |= HAL_KEY_SW_6;

  18.  

    }

  19.  

  20.  

    if ((HAL_KEY_JOY_MOVE_PORT & HAL_KEY_JOY_MOVE_BIT)) /* Key is active low */

  21.  

    {

  22.  

    keys |= halGetJoyKeyInput();

  23.  

    }

  24.  

    return keys;

  25.  

    }

该函数不需要应用层调用,是有HAL层调用的,在开发板的例程中,因为硬件上只有一个按键和一个五向按键,所以该函数的前面部分是通过IO口电平判断按键现在的状态,后面部分则是具体检测五向按键的状态。首先要确定五向按键被操作了,之后再执行函数halGetJoyKeyInput()。

  1. /**************************************************************************************************

  2.  

    * @fn halGetJoyKeyInput

  3.  

    *

  4.  

    * @brief Map the ADC value to its corresponding key.

  5.  

    *

  6.  

    * @param None

  7.  

    *

  8.  

    * @return keys - current joy key status

  9.  

    **************************************************************************************************/

  10.  

    uint8 halGetJoyKeyInput(void)

  11.  

    {

  12.  

    /* The joystick control is encoded as an analog voltage.

  13.  

    * Read the JOY_LEVEL analog value and map it to joy movement.

  14.  

    */

  15.  

    uint8 adc;

  16.  

    uint8 ksave0 = 0;

  17.  

    uint8 ksave1;

  18.  

  19.  

    /* Keep on reading the ADC until two consecutive key decisions are the same. */

  20.  

    do

  21.  

    {

  22.  

    ksave1 = ksave0; /* save previouse key reading */

  23.  

  24.  

    adc = HalAdcRead (HAL_KEY_JOY_CHN, HAL_ADC_RESOLUTION_8);

  25.  

  26.  

    if ((adc >= 2) && (adc <= 38))

  27.  

    {

  28.  

    ksave0 |= HAL_KEY_UP;

  29.  

    }

  30.  

    else if ((adc >= 74) && (adc <= 88))

  31.  

    {

  32.  

    ksave0 |= HAL_KEY_RIGHT;

  33.  

    }

  34.  

    else if ((adc >= 60) && (adc <= 73))

  35.  

    {

  36.  

    ksave0 |= HAL_KEY_LEFT;

  37.  

    }

  38.  

    else if ((adc >= 39) && (adc <= 59))

  39.  

    {

  40.  

    ksave0 |= HAL_KEY_DOWN;

  41.  

    }

  42.  

    else if ((adc >= 89) && (adc <= 100))

  43.  

    {

  44.  

    ksave0 |= HAL_KEY_CENTER;

  45.  

    }else{

  46.  

    ksave0=0;

  47.  

    }

  48.  

  49.  

    } while (ksave0 != ksave1);

  50.  

  51.  

    return ksave0;

  52.  

    }

2.4 HalKeyPoll()

  1. /**************************************************************************************************

  2.  

    * @fn HalKeyPoll

  3.  

    *

  4.  

    * @brief Called by hal_driver to poll the keys

  5.  

    *

  6.  

    * @param None

  7.  

    *

  8.  

    * @return None

  9.  

    **************************************************************************************************/

  10.  

    #define GHOSTYU_CODE_NOKEY 0x00

  11.  

    void HalKeyPoll (void)

  12.  

    {

  13.  

    #if (HAL_KEY == TRUE)

  14.  

  15.  

    uint8 keys = 0;

  16.  

    /*

  17.  

    * If interrupts are enabled, get the status of the interrupt-driven keys from ‘halSaveIntKey‘

  18.  

    * which is updated by the key ISR. If Polling, read these keys directly.

  19.  

    */

  20.  

    keys = HalKeyRead();

  21.  

  22.  

    /* Exit if polling and no keys have changed */

  23.  

    if (!Hal_KeyIntEnable)

  24.  

    {

  25.  

    if (keys == halKeySavedKeys)

  26.  

    {

  27.  

    return;

  28.  

    }

  29.  

    halKeySavedKeys = keys; /* Store the current keys for comparation next time */

  30.  

    }

  31.  

  32.  

    if(keys==0){

  33.  

    (pHalKeyProcessFunction) (0, HAL_KEY_STATE_NORMAL);

  34.  

    }

  35.  

  36.  

    /* Invoke Callback if new keys were depressed */

  37.  

    if ((keys != 0 /*HAL_KEY_CODE_NOKEY*/) && Hal_KeyIntEnable &&

  38.  

    (pHalKeyProcessFunction))

  39.  

    {

  40.  

    // When interrupt is enabled, send HAL_KEY_CODE_NOKEY as well so that

  41.  

    // application would know the previous key is no longer depressed.

  42.  

  43.  

    (pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL);

  44.  

  45.  

    }

  46.  

  47.  

    //如果使能了中断触发,在中断触发后,poll按键,先是去抖动,去抖动结束后,如果该按键仍存在,

  48.  

    //则调用按键回调函数,向用户传递按键数据

  49.  

    //然后执行下面的代码,再延时50ms,看时候该按键是否仍然没有释放。如果没有释放,则继续调用按键的回调函数。

  50.  

  51.  

    if (Hal_KeyIntEnable)

  52.  

    {

  53.  

    if (keys != 0/*HAL_KEY_CODE_NOKEY*/)

  54.  

    {

  55.  

    // In order to trigger callback again as far as the key is depressed,

  56.  

    // timer is called here.

  57.  

    osal_start_timerEx(Hal_TaskID, HAL_KEY_EVENT, 50);

  58.  

  59.  

    }

  60.  

    else

  61.  

    {

  62.  

    halKeyTimerRunning = FALSE;

  63.  

  64.  

    }

  65.  

    }

  66.  

    #endif /* HAL_KEY */

  67.  

  68.  

    }

该函数是对应开发板硬件修改的,它也是HAL层来执行,不需要应用层进行判断,主要功能是对按键的状态进行采集分析,并作回调。不过我看这个函数有些怪怪的,可以再优化下,增加可读性。另外,该函数和TI官方代码最大不同是,它增加了回调函数的一个功能,就是所有按键都释放时会有回调,此时state=0。下面贴一下官方的代码:

  1. /**************************************************************************************************

  2.  

    * @fn HalKeyPoll

  3.  

    *

  4.  

    * @brief Called by hal_driver to poll the keys

  5.  

    *

  6.  

    * @param None

  7.  

    *

  8.  

    * @return None

  9.  

    **************************************************************************************************/

  10.  

    void HalKeyPoll (void)

  11.  

    {

  12.  

    uint8 keys = 0;

  13.  

    uint8 notify = 0;

  14.  

    #if defined (CC2540_MINIDK)

  15.  

    if (!(HAL_KEY_SW_1_PORT & HAL_KEY_SW_1_BIT)) /* Key is active low */

  16.  

    {

  17.  

    keys |= HAL_KEY_SW_1;

  18.  

    }

  19.  

    if (!(HAL_KEY_SW_2_PORT & HAL_KEY_SW_2_BIT)) /* Key is active low */

  20.  

    {

  21.  

    keys |= HAL_KEY_SW_2;

  22.  

    }

  23.  

    #else

  24.  

    if (!(HAL_KEY_SW_6_PORT & HAL_KEY_SW_6_BIT)) /* Key is active low */

  25.  

    {

  26.  

    keys |= HAL_KEY_SW_6;

  27.  

    }

  28.  

  29.  

    if ((HAL_KEY_JOY_MOVE_PORT & HAL_KEY_JOY_MOVE_BIT)) /* Key is active HIGH */

  30.  

    {

  31.  

    keys = halGetJoyKeyInput();

  32.  

    }

  33.  

    #endif

  34.  

  35.  

    /* If interrupts are not enabled, previous key status and current key status

  36.  

    * are compared to find out if a key has changed status.

  37.  

    */

  38.  

    if (!Hal_KeyIntEnable)

  39.  

    {

  40.  

    if (keys == halKeySavedKeys)

  41.  

    {

  42.  

    /* Exit - since no keys have changed */

  43.  

    return;

  44.  

    }

  45.  

    else

  46.  

    {

  47.  

    notify = 1;

  48.  

    }

  49.  

    }

  50.  

    else

  51.  

    {

  52.  

    /* Key interrupt handled here */

  53.  

    if (keys)

  54.  

    {

  55.  

    notify = 1;

  56.  

    }

  57.  

    }

  58.  

  59.  

    /* Store the current keys for comparation next time */

  60.  

    halKeySavedKeys = keys;

  61.  

  62.  

    /* Invoke Callback if new keys were depressed */

  63.  

    if (notify && (pHalKeyProcessFunction))

  64.  

    {

  65.  

    (pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL);

  66.  

  67.  

    }

  68.  

    }

不过,TI的代码好像也有问题:

  1. #else

  2.  

    if (!(HAL_KEY_SW_6_PORT & HAL_KEY_SW_6_BIT)) /* Key is active low */

  3.  

    {

  4.  

    keys |= HAL_KEY_SW_6;

  5.  

    }

  6.  

  7.  

    if ((HAL_KEY_JOY_MOVE_PORT & HAL_KEY_JOY_MOVE_BIT)) /* Key is active HIGH */

  8.  

    {

  9.  

    keys = halGetJoyKeyInput();

  10.  

    }

  11.  

    #endif

keys = halGetJoyKeyInput();

应该改为:

keys |= halGetJoyKeyInput();

剩下的3个API:HalKeyEnterSleep()和HalKeyExitSleep()是没有内容的,HalKeyPressed()只找到声明没找到定义,就不管了。

3.KEY服务的工作流程

前面已经大概介绍了几个API的主要功能,现在来说说他们是怎么被HAL层使用的。

首先,当按键服务宏定义被打开后,HalKeyInit()函数会被调用(前面有介绍),之后,一般在设备启动任务中对KEY服务进行配置。

这里就有两个分支了,一个是当KEY_INT_ENABLED时,使用的是中断扫描,否则使用循环扫描方式,他们再HAL层工作流程就不太一样。

3.1 循环扫描

当使用循环扫描时,HalKeyConfig()在最后会触发HAL_KEY_EVENT事件:

  1. /* Do this only after the hal_key is configured - to work with sleep stuff */

  2.  

    if (HalKeyConfigured == TRUE)

  3.  

    {

  4.  

    osal_stop_timerEx(Hal_TaskID, HAL_KEY_EVENT); /* Cancel polling if active */

  5.  

    }

  6.  

    }

  7.  

    else /* Interrupts NOT enabled */

  8.  

    {

  9.  

    #if defined ( CC2540_MINIDK )

  10.  

    HAL_KEY_SW_1_ICTL &= ~(HAL_KEY_SW_1_ICTLBIT); /* don‘t generate interrupt */

  11.  

    HAL_KEY_SW_1_IEN &= ~(HAL_KEY_SW_1_IENBIT); /* Clear interrupt enable bit */

  12.  

    HAL_KEY_SW_2_ICTL &= ~(HAL_KEY_SW_2_ICTLBIT); /* don‘t generate interrupt */

  13.  

    HAL_KEY_SW_2_IEN &= ~(HAL_KEY_SW_2_IENBIT); /* Clear interrupt enable bit */

  14.  

    #else

  15.  

    HAL_KEY_SW_6_ICTL &= ~(HAL_KEY_SW_6_ICTLBIT); /* don‘t generate interrupt */

  16.  

    HAL_KEY_SW_6_IEN &= ~(HAL_KEY_SW_6_IENBIT); /* Clear interrupt enable bit */

  17.  

    #endif // !CC2540_MINIDK

  18.  

  19.  

    osal_set_event(Hal_TaskID, HAL_KEY_EVENT);

  20.  

    }

而在HAL任务中,会进行如下工作:

  1. if (events & HAL_KEY_EVENT)

  2.  

    {

  3.  

    #if (defined HAL_KEY) && (HAL_KEY == TRUE)

  4.  

    /* Check for keys */

  5.  

    HalKeyPoll();

  6.  

  7.  

    /* if interrupt disabled, do next polling */

  8.  

    if (!Hal_KeyIntEnable)

  9.  

    {

  10.  

    osal_start_timerEx( Hal_TaskID, HAL_KEY_EVENT, 100);

  11.  

    }

  12.  

    #endif

  13.  

    return events ^ HAL_KEY_EVENT;

  14.  

    }

这里我们可以注意到,当使用循环扫描时,扫描周期为100ms,每次处理该事件时调用的函数就是HalKeyPoll()。

3.2 中断扫描

和循环扫描所不同的是,它不会定时扫描,只有当中断触发时才会设置HAL_KEY_EVENT事件。

在中断处理中,当检测到是相应开关触发的中断后,会调用函数halProcessKeyInterrupt():

  1. /**************************************************************************************************

  2.  

    * @fn halProcessKeyInterrupt

  3.  

    *

  4.  

    * @brief Checks to see if it‘s a valid key interrupt, saves interrupt driven key states for

  5.  

    * processing by HalKeyRead(), and debounces keys by scheduling HalKeyRead() 25ms later.

  6.  

    *

  7.  

    * @param

  8.  

    *

  9.  

    * @return

  10.  

    **************************************************************************************************/

  11.  

    void halProcessKeyInterrupt (void)

  12.  

    {

  13.  

  14.  

    #if (HAL_KEY == TRUE)

  15.  

    //ghostyu from EM

  16.  

    bool valid=FALSE;

  17.  

    if (HAL_KEY_SW_6_PXIFG & HAL_KEY_SW_6_BIT) /* Interrupt Flag has been set */

  18.  

    {

  19.  

    HAL_KEY_SW_6_PXIFG = ~(HAL_KEY_SW_6_BIT); /* Clear Interrupt Flag */

  20.  

    valid = TRUE;

  21.  

    }

  22.  

  23.  

    if (HAL_KEY_JOY_MOVE_PXIFG & HAL_KEY_JOY_MOVE_BIT) /* Interrupt Flag has been set */

  24.  

    {

  25.  

    HAL_KEY_JOY_MOVE_PXIFG = ~(HAL_KEY_JOY_MOVE_BIT); /* Clear Interrupt Flag */

  26.  

    valid = TRUE;

  27.  

    }

  28.  

  29.  

    if (valid)

  30.  

    {

  31.  

    if (!halKeyTimerRunning)

  32.  

    {

  33.  

    halKeyTimerRunning = TRUE;

  34.  

    osalTimeUpdate();

  35.  

    osal_start_timerEx (Hal_TaskID, HAL_KEY_EVENT, HAL_KEY_DEBOUNCE_VALUE);

  36.  

    }

  37.  

    }

  38.  

    #endif /* HAL_KEY */

  39.  

    }

原文地址:https://www.cnblogs.com/F-beifeng/p/9739297.html

时间: 2024-11-06 07:25:44

zigbee 中的按键驱动的设置的相关文章

13.Linux键盘按键驱动 (详解)

版权声明:本文为博主原创文章,未经博主允许不得转载. 在上一节分析输入子系统内的intput_handler软件处理部分后,接下来我们开始写input_dev驱动 本节目标: 实现键盘驱动,让开发板的4个按键代表键盘中的L.S.空格键.回车键 1.先来介绍以下几个结构体使用和函数,下面代码中会用到 1)input_dev驱动设备结构体中常用成员如下: struct input_dev { void *private; const char *name; //设备名字 const char *ph

OSAL之按键驱动

本博文根据协议栈1.3.2,尊重原创,注明出处,欢迎转载 学习按键驱动的主要有两大块: 第一:按键引脚设置: 第二:按键事件的触发检测与轮询,以及按键消息的发送 先说明第一大块,按键引脚设置, 超出cc2540片子从机的按键两个按键,按键是共地.所以它的触发方式是下降沿触发按键中断,同时程序对按键按下这个动作检测是中断方式检测,一旦有按键按下,触发一个按键轮询函数执行,同时把对按键的检测方式换成轮询模式.所以对按键引脚设置的内容也就出来了.主要一下几个方面: 1.设置按键映射到的物理引脚GPIO

linux系统下标准GPIO按键驱动

前言: linux下platform平台驱动是为了方便隔离bsp与driver,利于移植.体现好代码的高内聚,低耦合.Linux设备驱动模型中,关心总线,设备和驱动三个实体.总线将设备和驱动绑定.在系统每注册一个设备的时候,都会寻找与之相匹配的驱动,相反的,每加载一个驱动的时候,也会寻找与之匹配的设备.匹配由总线完成.linux发明了一种虚拟的总线,称之为platform总线,相应的设备称之为platform_device,驱动为platform_driver. 基于这个模型,又根据面向对象的思

入门级的按键驱动——按键驱动笔记之poll机制-异步通知-同步互斥阻塞-定时器防抖

文章对应视频的第12课,第5.6.7.8节. 在这之前还有查询方式的驱动编写,中断方式的驱动编写,这篇文章中暂时没有这些类容.但这篇文章是以这些为基础写的,前面的内容有空补上. 按键驱动——按下按键,打印键值: 目录 概要 poll机制 异步通知 同步互斥阻塞 定时器防抖 概要: 查询方式: 12-3 缺点:占用CPU99%的资源.中断方式:12-4 缺点:调用read函数后如果没有按键按下,该函数永远不会结束,一直在等待按键按下. 优点:使用到了休眠机制,占用cpu资源极少.poll机制: 1

【转】s3c2440 按键驱动 — 字符设备

原文网址:http://www.xuebuyuan.com/632893.html 主机:VM - redhat 9.0 开发板:FL2440,linux-2.6.12 arm-linux-gcc:3.4.1 (1)原理图上的按键模块,可以看到相应的GPIO口,以及中断号. 由图可以得知GPF0等接高电平,当按键按下,则接低电平,所以将中断响应设置为下降沿触发. (2)驱动程序gzliu_2440_key.c,实现为一般的字符设备驱动,完整的源码如下,其中: // 定时器的使用参考:http:/

Linux设备驱动之button按键驱动学习与小结

button按键驱动,相对于前面的LED驱动来说.增加了中断服务程序以及等待队列等新知识点. 先上学习的驱动代码. 内核:linux3.0 板子:fl2440 /********************************************************************************* * Copyright: (C) 2011 Guo Wenxue<[email protected]> * All rights reserved. * * Filenam

Linux按键驱动程序设计详解---从简单到不简单

混杂设备驱动模型: 1. 混杂设备描述 在Linux系统中,存在一类字符设备,它们拥有相同的主设备号(10),单次设备号不同,我们称这类设备为混            杂设备(miscdevice).所有的混杂设备形成一个链表,对设备访问时内核根据次设备号查到相应的混杂设备. 混杂设备也是字符设备! linux中使用struct miscdevice来描述一个混杂设备. 2. 混杂驱动注册 Linux中使用misc_register函数来注册一个混杂设备驱动. int  misc_registe

MT7620 按键驱动(二)

一:为了消抖,笔者学习了Linux驱动之定时器API(参考 LDD定时器API (p198))   定时器相关结构: struct timer_list{ /*-省略一些字段-*/ struct list_head list; //双向链表头,用来将多个定时器连成一个双向链表 unsigned long expires;//定时有效时间 void (*function)(unsigned long);//定时器处理函数 unsigned long data://此成员传给处理函数的参数 }:  

第三十四天:按键驱动与蜂鸣器驱动以及MMU

编写按键驱动的过程和编写LED灯的驱动类似.区别在于按键是在底板上的.要从底板的电路图开始看.   使用key为关键字查找电路图: 可以得知的信息:按键松开时候XEINT26为高电平.按下时候为底电平.所以要判断按键是否被按下,就要检测XEINT26的状态. 使用XEINT26为关键字,在核心板上查看其定义.找到下图: XEINT26在核心板上链接到GPX3_2上.然后就是去datasheet中查找GPX3_2的说明了. 按键为检测,GPX3CON置0,GPX3DAT置1,表示按键被按下.代码如