KEY_unit

/*
*********************************************************************************************************
*
*   模块名称 : 按键驱动模块
*   文件名称 : bsp_key.h
*   版    本 : V1.0
*   说    明 : 头文件
*
*   Copyright (C), 2013-2014, 安富莱电子 www.armfly.com
*
*********************************************************************************************************
*/

#ifndef __BSP_KEY_H
#define __BSP_KEY_H

#define KEY_COUNT    10                     /* 按键个数, 8个独立建 + 2个组合键 */

/* 根据应用程序的功能重命名按键宏 */
#define KEY_DOWN_K1     KEY_1_DOWN
#define KEY_UP_K1       KEY_1_UP
#define KEY_LONG_K1     KEY_1_LONG

#define KEY_DOWN_K2     KEY_2_DOWN
#define KEY_UP_K2       KEY_2_UP
#define KEY_LONG_K2     KEY_2_LONG

#define KEY_DOWN_K3     KEY_3_DOWN
#define KEY_UP_K3       KEY_3_UP
#define KEY_LONG_K3     KEY_3_LONG

#define JOY_DOWN_U      KEY_4_DOWN      /* 上 */
#define JOY_UP_U        KEY_4_UP
#define JOY_LONG_U      KEY_4_LONG

#define JOY_DOWN_D      KEY_5_DOWN      /* 下 */
#define JOY_UP_D        KEY_5_UP
#define JOY_LONG_D      KEY_5_LONG

#define JOY_DOWN_L      KEY_6_DOWN      /* 左 */
#define JOY_UP_L        KEY_6_UP
#define JOY_LONG_L      KEY_6_LONG

#define JOY_DOWN_R      KEY_7_DOWN      /* 右 */
#define JOY_UP_R        KEY_7_UP
#define JOY_LONG_R      KEY_7_LONG

#define JOY_DOWN_OK     KEY_8_DOWN      /* ok */
#define JOY_UP_OK       KEY_8_UP
#define JOY_LONG_OK     KEY_8_LONG

#define SYS_DOWN_K1K2   KEY_9_DOWN      /* K1 K2 组合键 */
#define SYS_UP_K1K2     KEY_9_UP
#define SYS_LONG_K1K2   KEY_9_LONG

#define SYS_DOWN_K2K3   KEY_10_DOWN     /* K2 K3 组合键 */
#define SYS_UP_K2K3     KEY_10_UP
#define SYS_LONG_K2K3   KEY_10_LONG

/* 按键ID, 主要用于bsp_KeyState()函数的入口参数 */
typedef enum
{
    KID_K1 = 0,
    KID_K2,
    KID_K3,
    KID_JOY_U,
    KID_JOY_D,
    KID_JOY_L,
    KID_JOY_R,
    KID_JOY_OK
}KEY_ID_E;

/*
    按键滤波时间50ms, 单位10ms。
    只有连续检测到50ms状态不变才认为有效,包括弹起和按下两种事件
    即使按键电路不做硬件滤波,该滤波机制也可以保证可靠地检测到按键事件
*/
#define KEY_FILTER_TIME   5
#define KEY_LONG_TIME     100           /* 单位10ms, 持续1秒,认为长按事件 */

/*
    每个按键对应1个全局的结构体变量。
*/
typedef struct
{
    /* 下面是一个函数指针,指向判断按键手否按下的函数 */
    uint8_t (*IsKeyDownFunc)(void); /* 按键按下的判断函数,1表示按下 */

    uint8_t  Count;         /* 滤波器计数器 */
    uint16_t LongCount;     /* 长按计数器 */
    uint16_t LongTime;      /* 按键按下持续时间, 0表示不检测长按 */
    uint8_t  State;         /* 按键当前状态(按下还是弹起) */
    uint8_t  RepeatSpeed;   /* 连续按键周期 */
    uint8_t  RepeatCount;   /* 连续按键计数器 */
}KEY_T;

/*
    定义键值代码, 必须按如下次序定时每个键的按下、弹起和长按事件

    推荐使用enum, 不用#define,原因:
    (1) 便于新增键值,方便调整顺序,使代码看起来舒服点
    (2) 编译器可帮我们避免键值重复。
*/
typedef enum
{
    KEY_NONE = 0,           /* 0 表示按键事件 */

    KEY_1_DOWN,             /* 1键按下 */
    KEY_1_UP,               /* 1键弹起 */
    KEY_1_LONG,             /* 1键长按 */

    KEY_2_DOWN,             /* 2键按下 */
    KEY_2_UP,               /* 2键弹起 */
    KEY_2_LONG,             /* 2键长按 */

    KEY_3_DOWN,             /* 3键按下 */
    KEY_3_UP,               /* 3键弹起 */
    KEY_3_LONG,             /* 3键长按 */

    KEY_4_DOWN,             /* 4键按下 */
    KEY_4_UP,               /* 4键弹起 */
    KEY_4_LONG,             /* 4键长按 */

    KEY_5_DOWN,             /* 5键按下 */
    KEY_5_UP,               /* 5键弹起 */
    KEY_5_LONG,             /* 5键长按 */

    KEY_6_DOWN,             /* 6键按下 */
    KEY_6_UP,               /* 6键弹起 */
    KEY_6_LONG,             /* 6键长按 */

    KEY_7_DOWN,             /* 7键按下 */
    KEY_7_UP,               /* 7键弹起 */
    KEY_7_LONG,             /* 7键长按 */

    KEY_8_DOWN,             /* 8键按下 */
    KEY_8_UP,               /* 8键弹起 */
    KEY_8_LONG,             /* 8键长按 */

    /* 组合键 */
    KEY_9_DOWN,             /* 9键按下 */
    KEY_9_UP,               /* 9键弹起 */
    KEY_9_LONG,             /* 9键长按 */

    KEY_10_DOWN,            /* 10键按下 */
    KEY_10_UP,              /* 10键弹起 */
    KEY_10_LONG,            /* 10键长按 */
}KEY_ENUM;

/* 按键FIFO用到变量 */
#define KEY_FIFO_SIZE   10
typedef struct
{
    uint8_t Buf[KEY_FIFO_SIZE];     /* 键值缓冲区 */
    uint8_t Read;                   /* 缓冲区读指针1 */
    uint8_t Write;                  /* 缓冲区写指针 */
    uint8_t Read2;                  /* 缓冲区读指针2 */
}KEY_FIFO_T;

/* 供外部调用的函数声明 */
void bsp_InitKey(void);
void bsp_KeyScan(void);
void bsp_PutKey(uint8_t _KeyCode);
uint8_t bsp_GetKey(void);
uint8_t bsp_GetKey2(void);
uint8_t bsp_GetKeyState(KEY_ID_E _ucKeyID);
void bsp_SetKeyParam(uint8_t _ucKeyID, uint16_t _LongTime, uint8_t  _RepeatSpeed);
void bsp_ClearKey(void);

#endif

/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/
/*
*********************************************************************************************************
*
*   模块名称 : 独立按键驱动模块
*   文件名称 : bsp_key.c
*   版    本 : V1.0
*   说    明 : 扫描独立按键,具有软件滤波机制,具有按键FIFO。可以检测如下事件:
*               (1) 按键按下
*               (2) 按键弹起
*               (3) 长按键
*               (4) 长按时自动连发
*
*   修改记录 :
*       版本号  日期        作者     说明
*       V1.0    2013-02-01 armfly  正式发布
*       V1.1    2013-06-29 armfly  增加1个读指针,用于bsp_Idle() 函数读取系统控制组合键(截屏)
*                                  增加 K1 K2 组合键 和 K2 K3 组合键,用于系统控制
*       V1.2    2015-08-08 armfly  K1,K2,K3独立按键进行排他判断,修改  IsKeyDown1()等函数
*
*   Copyright (C), 2015-2016, 安富莱电子 www.armfly.com
*
*********************************************************************************************************
*/

#include "bsp.h"

/*
    该程序适用于安富莱STM32-V4开发板

    如果用于其它硬件,请修改GPIO定义和 IsKeyDown1 - IsKeyDown8 函数

    如果用户的按键个数小于8个,你可以将多余的按键全部定义为和第1个按键一样,并不影响程序功能
    #define KEY_COUNT    8    这个在 bsp_key.h 文件中定义
*/

/*
    安富莱STM32-V4 按键口线分配:
        K1 键      : PC13   (低电平表示按下)
        K2 键      : PA0    ( --- 高电平表示按下)
        K3 键      : PG8    (低电平表示按下)
        摇杆UP键   : PG15   (低电平表示按下)
        摇杆DOWN键 : PD3    (低电平表示按下)
        摇杆LEFT键 : PG14   (低电平表示按下)
        摇杆RIGHT键: PG13   (低电平表示按下)
        摇杆OK键   : PG7    (低电平表示按下)
*/

/* 按键口对应的RCC时钟 */
#define RCC_ALL_KEY     (RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOG)

#define GPIO_PORT_K1    GPIOC
#define GPIO_PIN_K1     GPIO_Pin_13

#define GPIO_PORT_K2    GPIOA
#define GPIO_PIN_K2     GPIO_Pin_0

#define GPIO_PORT_K3    GPIOG
#define GPIO_PIN_K3     GPIO_Pin_8

#define GPIO_PORT_K4    GPIOG
#define GPIO_PIN_K4     GPIO_Pin_15

#define GPIO_PORT_K5    GPIOD
#define GPIO_PIN_K5     GPIO_Pin_3

#define GPIO_PORT_K6    GPIOG
#define GPIO_PIN_K6     GPIO_Pin_14

#define GPIO_PORT_K7    GPIOG
#define GPIO_PIN_K7     GPIO_Pin_13

#define GPIO_PORT_K8    GPIOG
#define GPIO_PIN_K8     GPIO_Pin_7

static KEY_T s_tBtn[KEY_COUNT];
static KEY_FIFO_T s_tKey;       /* 按键FIFO变量,结构体 */

static void bsp_InitKeyVar(void);
static void bsp_InitKeyHard(void);
static void bsp_DetectKey(uint8_t i);

/*
*********************************************************************************************************
*   函 数 名: IsKeyDownX
*   功能说明: 判断按键是否按下
*   形    参: 无
*   返 回 值: 返回值1 表示按下,0表示未按下
*********************************************************************************************************
*/
/* 安富莱 STM32-V4 开发板 */
#if 1   /* 为了区分3个事件: K1单独按下, K2单独按下, K1和K2同时按下 */
static uint8_t IsKeyDown1(void)
{
    if ((GPIO_PORT_K1->IDR & GPIO_PIN_K1) == 0 && (GPIO_PORT_K2->IDR & GPIO_PIN_K2) == 0
        && (GPIO_PORT_K3->IDR & GPIO_PIN_K3) != 0)
        return 1;
    else 
        return 0;
}
static uint8_t IsKeyDown2(void)
{
    if ((GPIO_PORT_K1->IDR & GPIO_PIN_K1) != 0 && (GPIO_PORT_K2->IDR & GPIO_PIN_K2) != 0
        && (GPIO_PORT_K3->IDR & GPIO_PIN_K3) != 0)
        return 1;
    else 
        return 0;
}
static uint8_t IsKeyDown3(void)
{
    if ((GPIO_PORT_K1->IDR & GPIO_PIN_K1) != 0 && (GPIO_PORT_K2->IDR & GPIO_PIN_K2) == 0
        && (GPIO_PORT_K3->IDR & GPIO_PIN_K3) == 0)
        return 1;
    else 
        return 0;
}
static uint8_t IsKeyDown9(void) /* K1 K2组合键 */
{
    if ((GPIO_PORT_K1->IDR & GPIO_PIN_K1) == 0 && (GPIO_PORT_K2->IDR & GPIO_PIN_K2) != 0
        && (GPIO_PORT_K3->IDR & GPIO_PIN_K3) != 0)
        return 1;
    else 
        return 0;
}
static uint8_t IsKeyDown10(void)    /* K2 K3组合键 */
{
    if ((GPIO_PORT_K1->IDR & GPIO_PIN_K1) != 0 && (GPIO_PORT_K2->IDR & GPIO_PIN_K2) != 0
        && (GPIO_PORT_K3->IDR & GPIO_PIN_K3) == 0)
        return 1;
    else 
        return 0;
}
#else   
static uint8_t IsKeyDown1(void) {if ((GPIO_PORT_K1->IDR & GPIO_PIN_K1) == 0) return 1;else return 0;}
static uint8_t IsKeyDown2(void) {if ((GPIO_PORT_K2->IDR & GPIO_PIN_K2) != 0) return 1;else return 0;}
static uint8_t IsKeyDown3(void) {if ((GPIO_PORT_K3->IDR & GPIO_PIN_K3) == 0) return 1;else return 0;}

static uint8_t IsKeyDown9(void) {if (IsKeyDown1() && IsKeyDown2()) return 1;else return 0;}     /* K1 K2组合键 */
static uint8_t IsKeyDown10(void) {if (IsKeyDown2() && IsKeyDown3()) return 1;else return 0;}    /* K2 K3组合键 */
#endif

/* 5方向摇杆 */
static uint8_t IsKeyDown4(void) {if ((GPIO_PORT_K4->IDR & GPIO_PIN_K4) == 0) return 1;else return 0;}
static uint8_t IsKeyDown5(void) {if ((GPIO_PORT_K5->IDR & GPIO_PIN_K5) == 0) return 1;else return 0;}
static uint8_t IsKeyDown6(void) {if ((GPIO_PORT_K6->IDR & GPIO_PIN_K6) == 0) return 1;else return 0;}
static uint8_t IsKeyDown7(void) {if ((GPIO_PORT_K7->IDR & GPIO_PIN_K7) == 0) return 1;else return 0;}
static uint8_t IsKeyDown8(void) {if ((GPIO_PORT_K8->IDR & GPIO_PIN_K8) == 0) return 1;else return 0;}




/*
*********************************************************************************************************
*   函 数 名: bsp_InitKey
*   功能说明: 初始化按键. 该函数被 bsp_Init() 调用。
*   形    参:  无
*   返 回 值: 无
*********************************************************************************************************
*/
void bsp_InitKey(void)
{
    bsp_InitKeyVar();       /* 初始化按键变量 */
    bsp_InitKeyHard();      /* 初始化按键硬件 */
}

/*
*********************************************************************************************************
*   函 数 名: bsp_PutKey
*   功能说明: 将1个键值压入按键FIFO缓冲区。可用于模拟一个按键。
*   形    参:  _KeyCode : 按键代码
*   返 回 值: 无
*********************************************************************************************************
*/
void bsp_PutKey(uint8_t _KeyCode)
{
    s_tKey.Buf[s_tKey.Write] = _KeyCode;

    if (++s_tKey.Write  >= KEY_FIFO_SIZE)
    {
        s_tKey.Write = 0;
    }
}

/*
*********************************************************************************************************
*   函 数 名: bsp_GetKey
*   功能说明: 从按键FIFO缓冲区读取一个键值。
*   形    参:  无
*   返 回 值: 按键代码
*********************************************************************************************************
*/
uint8_t bsp_GetKey(void)
{
    uint8_t ret;

    if (s_tKey.Read == s_tKey.Write)
    {
        return KEY_NONE;
    }
    else
    {
        ret = s_tKey.Buf[s_tKey.Read];

        if (++s_tKey.Read >= KEY_FIFO_SIZE)
        {
            s_tKey.Read = 0;
        }
        return ret;
    }
}

/*
*********************************************************************************************************
*   函 数 名: bsp_GetKey2
*   功能说明: 从按键FIFO缓冲区读取一个键值。独立的读指针。
*   形    参:  无
*   返 回 值: 按键代码
*********************************************************************************************************
*/
uint8_t bsp_GetKey2(void)
{
    uint8_t ret;

    if (s_tKey.Read2 == s_tKey.Write)
    {
        return KEY_NONE;
    }
    else
    {
        ret = s_tKey.Buf[s_tKey.Read2];

        if (++s_tKey.Read2 >= KEY_FIFO_SIZE)
        {
            s_tKey.Read2 = 0;
        }
        return ret;
    }
}

/*
*********************************************************************************************************
*   函 数 名: bsp_GetKeyState
*   功能说明: 读取按键的状态
*   形    参:  _ucKeyID : 按键ID,从0开始
*   返 回 值: 1 表示按下, 0 表示未按下
*********************************************************************************************************
*/
uint8_t bsp_GetKeyState(KEY_ID_E _ucKeyID)
{
    return s_tBtn[_ucKeyID].State;
}

/*
*********************************************************************************************************
*   函 数 名: bsp_SetKeyParam
*   功能说明: 设置按键参数
*   形    参:_ucKeyID : 按键ID,从0开始
*           _LongTime : 长按事件时间
*            _RepeatSpeed : 连发速度
*   返 回 值: 无
*********************************************************************************************************
*/
void bsp_SetKeyParam(uint8_t _ucKeyID, uint16_t _LongTime, uint8_t  _RepeatSpeed)
{
    s_tBtn[_ucKeyID].LongTime = _LongTime;          /* 长按时间 0 表示不检测长按键事件 */
    s_tBtn[_ucKeyID].RepeatSpeed = _RepeatSpeed;            /* 按键连发的速度,0表示不支持连发 */
    s_tBtn[_ucKeyID].RepeatCount = 0;                       /* 连发计数器 */
}


/*
*********************************************************************************************************
*   函 数 名: bsp_ClearKey
*   功能说明: 清空按键FIFO缓冲区
*   形    参:无
*   返 回 值: 按键代码
*********************************************************************************************************
*/
void bsp_ClearKey(void)
{
    s_tKey.Read = s_tKey.Write;
}

/*
*********************************************************************************************************
*   函 数 名: bsp_InitKeyHard
*   功能说明: 配置按键对应的GPIO
*   形    参:  无
*   返 回 值: 无
*********************************************************************************************************
*/
static void bsp_InitKeyHard(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    /* 第1步:打开GPIO时钟 */
    RCC_APB2PeriphClockCmd(RCC_ALL_KEY, ENABLE);

    /* 第2步:配置所有的按键GPIO为浮动输入模式(实际上CPU复位后就是输入状态) */
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   /* 输入浮空模式 */

    GPIO_InitStructure.GPIO_Pin = GPIO_PIN_K1;
    GPIO_Init(GPIO_PORT_K1, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_PIN_K2;
    GPIO_Init(GPIO_PORT_K2, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_PIN_K3;
    GPIO_Init(GPIO_PORT_K3, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_PIN_K4;
    GPIO_Init(GPIO_PORT_K4, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_PIN_K5;
    GPIO_Init(GPIO_PORT_K5, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_PIN_K6;
    GPIO_Init(GPIO_PORT_K6, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_PIN_K7;
    GPIO_Init(GPIO_PORT_K7, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_PIN_K8;
    GPIO_Init(GPIO_PORT_K8, &GPIO_InitStructure);
}

/*
*********************************************************************************************************
*   函 数 名: bsp_InitKeyVar
*   功能说明: 初始化按键变量
*   形    参:  无
*   返 回 值: 无
*********************************************************************************************************
*/
static void bsp_InitKeyVar(void)
{
    uint8_t i;

    /* 对按键FIFO读写指针清零 */
    s_tKey.Read = 0;
    s_tKey.Write = 0;
    s_tKey.Read2 = 0;

    /* 给每个按键结构体成员变量赋一组缺省值 */
    for (i = 0; i < KEY_COUNT; i++)
    {
        s_tBtn[i].LongTime = KEY_LONG_TIME;         /* 长按时间 0 表示不检测长按键事件 */
        s_tBtn[i].Count = KEY_FILTER_TIME / 2;      /* 计数器设置为滤波时间的一半 */
        s_tBtn[i].State = 0;                            /* 按键缺省状态,0为未按下 */
        //s_tBtn[i].KeyCodeDown = 3 * i + 1;                /* 按键按下的键值代码 */
        //s_tBtn[i].KeyCodeUp   = 3 * i + 2;                /* 按键弹起的键值代码 */
        //s_tBtn[i].KeyCodeLong = 3 * i + 3;                /* 按键被持续按下的键值代码 */
        s_tBtn[i].RepeatSpeed = 0;                      /* 按键连发的速度,0表示不支持连发 */
        s_tBtn[i].RepeatCount = 0;                      /* 连发计数器 */
    }

    /* 如果需要单独更改某个按键的参数,可以在此单独重新赋值 */
    /* 比如,我们希望按键1按下超过1秒后,自动重发相同键值 */
    s_tBtn[KID_JOY_U].LongTime = 100;
    s_tBtn[KID_JOY_U].RepeatSpeed = 5;  /* 每隔50ms自动发送键值 */

    s_tBtn[KID_JOY_D].LongTime = 100;
    s_tBtn[KID_JOY_D].RepeatSpeed = 5;  /* 每隔50ms自动发送键值 */

    s_tBtn[KID_JOY_L].LongTime = 100;
    s_tBtn[KID_JOY_L].RepeatSpeed = 5;  /* 每隔50ms自动发送键值 */

    s_tBtn[KID_JOY_R].LongTime = 100;
    s_tBtn[KID_JOY_R].RepeatSpeed = 5;  /* 每隔50ms自动发送键值 */

    /* 判断按键按下的函数 */
    s_tBtn[0].IsKeyDownFunc = IsKeyDown1;
    s_tBtn[1].IsKeyDownFunc = IsKeyDown2;
    s_tBtn[2].IsKeyDownFunc = IsKeyDown3;
    s_tBtn[3].IsKeyDownFunc = IsKeyDown4;
    s_tBtn[4].IsKeyDownFunc = IsKeyDown5;
    s_tBtn[5].IsKeyDownFunc = IsKeyDown6;
    s_tBtn[6].IsKeyDownFunc = IsKeyDown7;
    s_tBtn[7].IsKeyDownFunc = IsKeyDown8;

    /* 组合键 */
    s_tBtn[8].IsKeyDownFunc = IsKeyDown9;
    s_tBtn[9].IsKeyDownFunc = IsKeyDown10;
}

/*
*********************************************************************************************************
*   函 数 名: bsp_DetectKey
*   功能说明: 检测一个按键。非阻塞状态,必须被周期性的调用。
*   形    参:  按键结构变量指针
*   返 回 值: 无
*********************************************************************************************************
*/
static void bsp_DetectKey(uint8_t i)
{
    KEY_T *pBtn;

    /*
        如果没有初始化按键函数,则报错
        if (s_tBtn[i].IsKeyDownFunc == 0)
        {
            printf("Fault : DetectButton(), s_tBtn[i].IsKeyDownFunc undefine");
        }
    */

    pBtn = &s_tBtn[i];
    if (pBtn->IsKeyDownFunc())
    {
        if (pBtn->Count < KEY_FILTER_TIME)
        {
            pBtn->Count = KEY_FILTER_TIME;
        }
        else if(pBtn->Count < 2 * KEY_FILTER_TIME)
        {
            pBtn->Count++;
        }
        else
        {
            if (pBtn->State == 0)
            {
                pBtn->State = 1;

                /* 发送按钮按下的消息 */
                bsp_PutKey((uint8_t)(3 * i + 1));
            }

            if (pBtn->LongTime > 0)
            {
                if (pBtn->LongCount < pBtn->LongTime)
                {
                    /* 发送按钮持续按下的消息 */
                    if (++pBtn->LongCount == pBtn->LongTime)
                    {
                        /* 键值放入按键FIFO */
                        bsp_PutKey((uint8_t)(3 * i + 3));
                    }
                }
                else
                {
                    if (pBtn->RepeatSpeed > 0)
                    {
                        if (++pBtn->RepeatCount >= pBtn->RepeatSpeed)
                        {
                            pBtn->RepeatCount = 0;
                            /* 常按键后,每隔10ms发送1个按键 */
                            bsp_PutKey((uint8_t)(3 * i + 1));
                        }
                    }
                }
            }
        }
    }
    else
    {
        if(pBtn->Count > KEY_FILTER_TIME)
        {
            pBtn->Count = KEY_FILTER_TIME;
        }
        else if(pBtn->Count != 0)
        {
            pBtn->Count--;
        }
        else
        {
            if (pBtn->State == 1)
            {
                pBtn->State = 0;

                /* 发送按钮弹起的消息 */
                bsp_PutKey((uint8_t)(3 * i + 2));
            }
        }

        pBtn->LongCount = 0;
        pBtn->RepeatCount = 0;
    }
}

/*
*********************************************************************************************************
*   函 数 名: bsp_KeyScan
*   功能说明: 扫描所有按键。非阻塞,被systick中断周期性的调用
*   形    参:  无
*   返 回 值: 无
*********************************************************************************************************
*/
void bsp_KeyScan(void)
{
    uint8_t i;

    for (i = 0; i < KEY_COUNT; i++)
    {
        bsp_DetectKey(i);
    }
}

/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值