单片机的按键处理程序

2019-04-15 17:44发布

#ifndef _KEY_H_ #define _KEY_H_ #include "stm32f10x_conf.h" #include "delay.h" #include "hardware_inc.h" #include "includes.h" #include "stdbool.h" typedef struct { u8 trg; //触发标志位 u8 cont; //计数标志位 }KEY_STATUS; typedef struct { _Bool left_trg; //左按键触发标志位 u8 ltmr; //左按键定时器 u8 lcnt_trg; //左按键模拟队列 _Bool right_trg; //右按键触发标志位 u8 rtmr; //右按键定时器 u8 rcnt_trg; //右按键模拟队列 }KEY_TRG; void Key_Init(void); u8 Key_Scan(KEY_STATUS * key); void Get_Key_Status(KEY_TRG* key_trg); #endif #include "key.h" /*! * fn: Key_Init * rief: 按键接口初始化 * param: [in] void * eturn: void * date: 2016/11/10 */ void Key_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB,ENABLE); //Configure pin as input GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOB,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA,&GPIO_InitStructure); } /*! * fn: lKey_Scan * rief: 扫描左按键的状态,低电平代表按键被按下 * param: [in] KEY_STATUS * key 按键结构体 * --trg 按键触发标志位 1 代表按键被触发 0 代表按键没被触发 * --cont 按键弹起标志位 1 代表按键没弹起 1 代表按键已弹起 * eturn: u8 无意义返回值 * date: 2016/11/14 */ u8 lKey_Scan(KEY_STATUS * key) { u8 Read_Data = 0; if(!GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)) Read_Data = 0x01; else Read_Data = 0x00; key->trg = Read_Data & (Read_Data ^ key->cont); key->cont = Read_Data; return 0; } /*! * fn: rKey_Scan * rief: 扫描右按键的状态,低电平代表按键被按下 * param: [in] KEY_STATUS * key 按键结构体 * --trg 按键触发标志位 1 代表按键被触发 0 代表按键没被触发 * --cont 按键弹起标志位 1 代表按键没弹起 1 代表按键已弹起 * eturn: u8 无意义返回值 * date: 2016/11/14 */ u8 rKey_Scan(KEY_STATUS * key) { u8 Read_Data = 0; if(!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)) Read_Data = 0x01; else Read_Data = 0x00; key->trg = Read_Data & (Read_Data ^ key->cont); key->cont = Read_Data; return 0; } /*! * fn: Get_Key_Status * rief: 获取按键状态函数 * param: [in] KEY_TRG * key_trg 按键标志位 * -- _Bool left_trg 左按键触发标志位 * -- u8 ltmr 左按键定时器 * -- u8 lcnt_trg 左模拟队列 * -- _Bool right_trg 右按键触发标志位 * -- u8 rtmr 右按键定时器 * -- u8 rcnt_trg 右模拟队列 * eturn: void * date: 2016/11/14 */ void Get_Key_Status(KEY_TRG* key_trg) { KEY_STATUS lkey_status; KEY_STATUS rkey_status; lKey_Scan(&lkey_status); rKey_Scan(&rkey_status); if(lkey_status.trg) //左键触发标志位如果被置位 { if(key_trg->lcnt_trg != 0x55)//0x55代表自写值,出现自写值则不在连续保存 key_trg->lcnt_trg |= 1 << key_trg->ltmr; //移位操作是确保连续触发八次 key_trg->ltmr++; if(key_trg->lcnt_trg == 0xFF)//连续触发八次才能确定按键被按下 { key_trg->lcnt_trg = 0x55;//自写值保证按键一直没有弹起的情况下只采集一次值 key_trg->left_trg = !key_trg->left_trg; } } else if(lkey_status.cont == 0)//按键被弹起 { key_trg->ltmr = 0; key_trg->lcnt_trg = 0x00; } if(rkey_status.trg) { if(key_trg->rcnt_trg != 0x55) key_trg->rcnt_trg |= 1 << key_trg->rtmr; key_trg->rtmr++; if(key_trg->rcnt_trg == 0xFF) { key_trg->rcnt_trg = 0x55; key_trg->right_trg = !key_trg->right_trg; } } else if(rkey_status.cont == 0) { key_trg->rtmr = 0; key_trg->rcnt_trg = 0x00; } }