矩陣鍵盤程序,作為麥知club小車項目的一部分,從IAR狀態(tài)機應用修改而來。
IAR7.4+STM32CUBEMX調(diào)試通過。
鍵盤行4,列3,每條線都有10K上拉電阻。改到4×4矩陣也很容易。
行線設置為 輸入,針腳為浮空; 列線設置為開漏輸出。
不支持長按和組合鍵,主要是我不會改。
在OS中使用20ms任務周期調(diào)用。
以下貼出代碼。
keypad.h
/*
*
*Name:keypad.h
*/
#ifndefKEYPAD_H
#defineKEYPAD_H
#include"stm32f1xx_hal.h"
#include"pinname.h"
#definePORT_KEYGPIOD
#defineCOLS(GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6)
//讀pin
//#defineIn(GPIO_Pin)(PORT_KEY->IDR&GPIO_Pin)
#defineIn(GPIO_Pin)HAL_GPIO_ReadPin(PORT_KEY,GPIO_Pin)
//寫1到Pin
//#defineHigh(GPIO_Pin)PORT_KEY->BSRR=GPIO_Pin
#defineHigh(GPIO_Pin)HAL_GPIO_WritePin(PORT_KEY,GPIO_Pin,GPIO_PIN_SET)
//寫0到Pin
//#defineLow(GPIO_Pin)PORT_KEY->BSRR=(uint32_t)GPIO_Pin<<16
#defineLow(GPIO_Pin)HAL_GPIO_WritePin(PORT_KEY,GPIO_Pin,GPIO_PIN_RESET)
/*
*0123
*4567
*891011
*12131415
*/
typedefenum{
Key_Up=0x02,
Key_Left=0x03,
Key_Right=0x04,
Key_Down=0x08,
Key_On=0x09,
Key_Mode=0x0a,
Key_None=0xFF
}KeyPressed;
staticconstintrow_count=4;
staticconstintcol_count=3;
uint16_tbus_out(void);
voidKeypad(void);
charAnyKey(void);
charSameKey(void);
charScanKey(void);
voidFindKey(void);
voidClearKey(void);
voidRead(void);
/**Startthekeypadinterruptroutines*/
voidStart(void);
/**Stopthekeypadinterruptroutines*/
voidStop(void);
voidCols_out(uint16_tv);
voidScan_Keyboard(void);
KeyPressedgetKey(void);
#endif//KEYPAD_H
keypad.c
/*
*
*Name:keypad.cpp
*
*/
#include"keypad.h"
//State:
charKeyState;
//Bitpatternaftereachscan:
charKeyCode;
//Outputvaluefromthevirtual74HC922:
KeyPressedKeyValue;
//KeyDownissetifkeyisdown:
charKeyDown;
//KeyNewisseteverytimeanewkeyisdown:
charKeyNew;
//映射表
charKeyTable[12][2];
//PinofRow
uint16_t_rows[]={KEYx0,KEYx1,KEYx2,KEYx3};
uint16_t_cols[]={KEYy0,KEYy1,KEYy2};
//構(gòu)造函數(shù)
voidKeypad(void)
{
Stop();
KeyState=0;//按鍵狀態(tài)初始0
}
//掃描鍵盤
voidScan_Keyboard(void){
switch(KeyState){
case0:{
if(AnyKey()){
charscankey=ScanKey();
if(scankey!=0xff)
KeyCode=scankey;
KeyState=1;
}
break;
}
case1:{
if(SameKey()){
FindKey();
KeyState=2;
}
else
KeyState=0;
break;
}
case2:{
if(SameKey()){
}
else
KeyState=3;
break;
}
case3:{
if(SameKey()){
KeyState=2;
}
else{
ClearKey();
KeyState=0;
}
break;
}
}
//funcend
}
//有鍵按下
charAnyKey(void){
//Start();//拉低
intr=-1;
for(r=0;r if(In(_rows[r])==0)//Inmacro break; } //Stop();//恢復 if(!(0<=r&&r return0; else return1; } //鍵按下,鍵值相同 charSameKey(void){ //charKeyCode_new=KeyCode; charKeyCode_new=ScanKey(); if(KeyCode==KeyCode_new) return1; else return0; } //掃描鍵 charScanKey(void){ /*行掃描*/ intr=-1; for(r=0;r if(In(_rows[r])==0)//Inmacro break; } /*若沒有找到有效行,返回*/ if(!(0<=r&&r return0xff; } /*列掃描,找出行上哪個被拉低*/ intc=-1; for(c=0;c //輪流輸出列線 Cols_out(~(1< if(In(_rows[r])==0)//Inmacro break; } /*給所有的列重新充電*/ Start(); /*若沒有找到有效列,返回*/ if(!(0<=c&&c return0xff; return r * col_count + c;