#include "Func.h" /////////////////////////////////////////////////////////////////////////////////////// // // 键盘扫描初始化 // // B.5 B.6 B.7 B.8 //C.6 Rudder TL Rudder TR Elevator TU Elevator TD //C.7 NC Ent R+ L- //C.8 Throttle TU Throttle TD Aileron TR Aileron TL //C.9 NC DN- UP+ Ext //TL: Trim Left TR: Trim Right //TU: Trim Up TD: Trim down void KeyInit(void) { /* Enable AFIO */ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN); /* Remap GPIO_Remap_SWJ_JTAGDisable */ AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON; /* Enable GPIOB & GPIOE */ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN); // PortB 5 6 7 8 开漏输出 gpio_set_mode(KEY_COL_PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO5 | GPIO6 | GPIO7 | GPIO8); gpio_set(KEY_COL_PORT, GPIO5 | GPIO6| GPIO7 | GPIO8); // PortC 6 7 8 9 上拉输入 gpio_set_mode(KEY_ROW_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO6 | GPIO7 | GPIO8 | GPIO9); gpio_set(KEY_ROW_PORT, GPIO6 | GPIO7 | GPIO8 | GPIO9); //PortC 10 11上拉输入 HOLD FMOD gpio_set_mode(KEY_SW_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO10 | GPIO11); gpio_set(KEY_SW_PORT, GPIO10 | GPIO11); KeyFlush(); KeyStat=KeyScanOnce();//为开机检测按键取得按键状态 } /////////////////////////////////////////////////////////////////////////////////////// // // 键盘扫描一次 // u16 KeyScanOnce(void) { u16 result=KEY_MASK; u32 col; gpio_set(KEY_COL_PORT, KEY_COL_PORT_MASK); for(col = 1<<5; col <= 1<<8; col<<=1) { gpio_clear(KEY_COL_PORT, col); result<<=4; result|= 0x0f&(gpio_port_read(KEY_ROW_PORT)>>6); gpio_set(KEY_COL_PORT, col); } return result; } /////////////////////////////////////////////////////////////////////////////////////// // // 键盘扫描中断服务程序(sys_tick_handler里1ms调用1次) // volatile u16 KeyStat,KeyDown,KeyHold,KeyBuf; volatile u16 KeyPressCnt; volatile u16 SwStat,SwBuf; void KeyScanHandler(void) { static u32 KeyScanDivider; u16 k; u16 s,sw; //按键扫描分频,25ms扫描一次 if(SysTimerClk-KeyScanDivider<25) return; KeyScanDivider=SysTimerClk; //读取开关 s=gpio_port_read(KEY_SW_PORT); sw=0; if(s&(1L<<10)) sw|=SW_FMOD; if(s&(1L<<11)) sw|=SW_HOLD; if(sw==SwBuf) SwStat=sw; else SwBuf=sw; k=KeyScanOnce(); //键盘消抖 if(k==KeyBuf) { KeyStat=k; k&=KEY_MASK; if(k!=KEY_MASK) { if(KeyPressCnt==0) { if(TxSys.KeyBeep) BeepShort(1000+TxSys.KeyTone*30,30+TxSys.KeyBeep*6,20); LightStartTmr=SysTimerCnt;//背光关闭计数器重置 KeyDown&=KeyStat; } else { //连按处理 if(KeyPressCnt>=KEY_CONT_TRIG) { u16 kd=KeyDown; //连按的赋值要用&,以免将还未处理的"禁连按键"消去 KeyHold&=KeyBuf; KeyDown&=KeyBuf |KEY_EXT|KEY_ENT;//***不允许连按的键在此处处理 KeyPressCnt=KEY_CONT_TRIG-KEY_CONT_FREQ; //按键有变化,发声 if(KeyDown!=kd) { if(TxSys.KeyBeep) BeepShort(1000+TxSys.KeyTone*30,30+TxSys.KeyBeep*6,20); LightStartTmr=SysTimerCnt;//背光关闭计数器重置 } } } KeyPressCnt++; } else { KeyHold|=KeyBuf; //按键一松开,KEYHOLD就要为0 KeyPressCnt=0; } } else { KeyBuf=k; } } /////////////////////////////////////////////////////////////////////////////////////// // // 按键检测 // u8 KeyTstDown(u16 mask) { if((KeyDown&mask)==0) { KeyDown |= mask; return 1; } return 0; } void KeyClearDown(u16 mask) { KeyDown |= mask; } u8 KeyTstStat(u16 mask) { return !(KeyStat&mask); } u8 KeyTstHold(u16 mask) { if((KeyHold&mask)==0) { KeyHold |= mask; return 1; } return 0; } void KeyFlush(void) { KeyDown=KeyStat=KeyHold=KeyBuf=KEY_MASK; KeyPressCnt=0; } void KeyStopCnt(void) { KeyPressCnt=1; }