之前参加电子比赛时,有用过stm32做主控制器。分享一下当时我用stm32做键盘扫描的程序,项目比较简单,望大神不鄙视。 具体思想是,通过设置systick的做一个计时器,可以设置MCU后台对键盘扫描的时间间隔。systick配置如下: SysTick_CounterCmd(SysTick_Counter_Disable); SysTick_ITConfig(DISABLE); SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); NVIC_SystemHandlerPriorityConfig(SystemHandler_SysTick, 3, 0); SysTick_SetReload(720000); SysTick_ITConfig(ENABLE); SysTick_CounterCmd(SysTick_Counter_Enable); 程序设置为10ms中断,在systick中断里进行键盘扫描 按键代码如下: /******************************************************************************** *文件名: keypad.c *功能 : 键盘扫描及键值处理 *作者 : Aemlia *日期 : 2012/3/18 *********************************************************************************/ #include "common.h" u16 KeyStore=0; u16 keyvalue=0xff; //初始化按键值 static u8 keyBackCheck=1; /******************************************************************************** *函数名 : keyscan() *功能 : 扫描键盘,判断是否有键按下 *输入 : 无 *输出 : 无 *返回 : 1或0 ********************************************************************************/ u8 keyscan (void) { u16 keystate; GPIOA->ODR=0x00; keystate=GPIOC->IDR&0xf0; if(keystate!=0xf0) return 1; else return 0; } /******************************************************************************* *函数名: keyvaluecheck *功能 : 判断键值 *输入 : 无 *输出 : 无 *返回 : KEYVALUE *******************************************************************************/ u16 keyvaluecheck(void) { u16 KEYVALUE=0xff; GPIOA->ODR=0xfe; //第一行 if(0==GET_GPIOC_P4) { KEYVALUE=0x00; } else if(0==GET_GPIOC_P5) { KEYVALUE=0x01; } else if(0==GET_GPIOC_P6) { KEYVALUE=0x02;} else if(0==GET_GPIOC_P7) { KEYVALUE=0x03; } GPIOA->ODR=0xfd; //第二行 if(0==GET_GPIOC_P4) KEYVALUE=0x04; else if(0==GET_GPIOC_P5) KEYVALUE=0x05; else if(0==GET_GPIOC_P6) KEYVALUE=0x06; else if(0==GET_GPIOC_P7) KEYVALUE=0x07; GPIOA->ODR=0xfb; //第三行 if(0==GET_GPIOC_P4) KEYVALUE=0x08; else if(0==GET_GPIOC_P5) KEYVALUE=0x09; else if(0==GET_GPIOC_P6) KEYVALUE=0x0a; else if(0==GET_GPIOC_P7) KEYVALUE=0x0b; GPIOA->ODR=0xf7; //第四行 if(0==GET_GPIOC_P4) KEYVALUE=0x0c; else if(0==GET_GPIOC_P5) KEYVALUE=0x0d; else if(0==GET_GPIOC_P6) KEYVALUE=0x0e; else if(0==GET_GPIOC_P7) KEYVALUE=0x0f; return KEYVALUE; } /******************************************************************************** *函数名 : keycheck() *功能 : 判断键值 *输入 : 无 *输出 : 无 *返回 : keyvalue *说明 :状态机按键 *********************************************************************************/ void keycheck(void) { static enum STATE c_state=state0; switch (c_state) { case state0 : //判断是否有键按下 if(keyscan ()) {c_state=state1;break; } else {c_state=state0;break; } case state1 : //消抖 if(keyscan ()) {c_state=state2;break; } else {c_state=state0;break; } case state2 : //扫描键值 if(keyscan()) { keyvalue=keyvaluecheck(); c_state=state3; break; } else c_state=state0; case state3 : //等待按键释放 if(keyscan()) c_state=state3; else c_state=state0; break; default : c_state=state0; break; } return ; } /******************************************************************************* *函数名: keyprocess() *功能 : 键值处理 *输入 : keyvalue *输出 : 无 *说明 : 无 *******************************************************************************/ void keyprocess(u16* KEYVALUE) { switch (*KEYVALUE) { case 0x00 : KeyOK(); break; case 0x01 : KeyUp(); break; case 0x02 : KeyDown(); break; case 0x03 : KeyBack(); break; case 0x04 : chosenum(0); break; case 0x05 : chosenum(1); break; case 0x06 : chosenum(2); break; case 0x07 : chosenum(3); break; case 0x08 : chosenum(4); break; case 0x09 : chosenum(5); break; case 0x0a : chosenum(6); break; case 0x0b : chosenum('k'); break; case 0x0c : chosenum(7); break; case 0x0d : chosenum(8); break; case 0x0e : chosenum(9); break; case 0x0f : if(g_u8inputAEnable) chosenum('.'); else chosenum('M'); break; } *KEYVALUE=0xff; } /**************************************************************************** * 名称:KeyUp() * 功能:按键选择上一项 * 入口参数:无 * 出口参数:无 * 说明: ****************************************************************************/ void KeyUp(void) { } /**************************************************************************** * 名称:KeyDown() * 功能:按键选择下一项 * 入口参数:无 * 出口参数:无 * 说明:用 ****************************************************************************/ void KeyDown(void) { } /**************************************************************************** * 名称:Key_OK() * 功能:按键选择确定 * 入口参数:无 * 出口参数:无 * 说明: ****************************************************************************/ void KeyOK(void) { } /**************************************************************************** * 名称:KeyBackRoot() * 功能:按键选择返回 * 入口参数:无 * 出口参数:无 * 说明: ****************************************************************************/ void KeyBackRoot(void) { } /**************************************************************************** * 名称:KeyBack() * 功能:按键选择返回 * 入口参数:无 * 出口参数:无 * 说明: ****************************************************************************/ void KeyBack(void) { } /**************************************************************************** * 名称:RoutineProcess() * 功能:例行程序 * 入口参数:无 * 出口参数:无 * 说明:无 ****************************************************************************/ void RoutineProcess(void) { keycheck(); } 中断里运行RoutineProcess()函数,进行键盘扫描,主程序则运行keyprocess()函数,进行按键值处理。 由于水平有限,代码可能有不完善之处,希望大神给予指正。 |
RE:【MCU实战经验】+利用stm32的systick进行键盘扫描
回复:【MCU实战经验】+利用stm32的systick进行键盘扫描
回复:【MCU实战经验】+利用stm32的systick进行键盘扫描
用systick与通用定时器有什么区别呢?看不出优势在哪,请指教
抱歉,才看到。其实systick和通用的定时器的在计数方面功能是一样的,我在这里用systick,是因为systic配置起来相对简单,再者,systick一般用于os的定时,所以这里我也借鉴了这个。
初学stm32,说的有不对的地方,望指正。