stm32 4*4矩阵键盘
2015-12-23 11:30
621 查看
stm32f030开发板。
使用HAL库。
状态机做debounce消抖。
col列,Pin配置为PP推挽输出模式;
row行,Pin配置为Input模式,启用内部上拉电阻。
代码如下:
.h文件
.c文件
使用HAL库。
状态机做debounce消抖。
col列,Pin配置为PP推挽输出模式;
row行,Pin配置为Input模式,启用内部上拉电阻。
代码如下:
.h文件
/* * * Name: keypad.h * Faq: www.mazclub.com */ #ifndef KEYPAD_H #define KEYPAD_H #include "stm32f0xx_hal.h" //#include "pinname.h" #define COLS (GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6) #define PORT_COL GPIOB #define KEYy0 GPIO_PIN_6 #define KEYy1 GPIO_PIN_5 #define KEYy2 GPIO_PIN_4 #define KEYy3 GPIO_PIN_3 #define PORT_ROW GPIOA #define KEYx0 GPIO_PIN_12 #define KEYx1 GPIO_PIN_11 #define KEYx2 GPIO_PIN_10 #define KEYx3 GPIO_PIN_9 // 读pin //#define In(GPIO_Pin) (PORT_KEY->IDR & GPIO_Pin) #define In(GPIO_Pin) HAL_GPIO_ReadPin(PORT_ROW, GPIO_Pin) // 写1到Pin //#define High(GPIO_Pin) PORT_KEY->BSRR = GPIO_Pin #define High(GPIO_Pin) HAL_GPIO_WritePin(PORT_COL, GPIO_Pin, GPIO_PIN_SET) // 写0到Pin //#define Low(GPIO_Pin) PORT_KEY->BSRR = (uint32_t)GPIO_Pin << 16 #define Low(GPIO_Pin) HAL_GPIO_WritePin(PORT_COL, GPIO_Pin, GPIO_PIN_RESET) /* * 0 1 2 3 * 4 5 6 7 * 8 9 10 11 * 12 13 14 15 */ typedef enum { Key_Up = 0x02, Key_Left = 0x03, Key_Right = 0x04, Key_Down = 0x08, Key_Power = 0x09, Key_Mode = 0x0a, Key_None = 0xFF } KeyPressed; static const int row_count = 4; static const int col_count = 4; uint16_t bus_out(void); void Keypad(void); char AnyKey(void); char SameKey(void); char ScanKey(void); void FindKey(void); void ClearKey(void); void Read(void); /** Start the keypad interrupt routines */ void Start(void); /** Stop the keypad interrupt routines */ void Stop(void); void Cols_out(uint16_t v); void Scan_Keyboard(void); KeyPressed getKey(void); #endif // KEYPAD_H
.c文件
/* * * Name: keypad.cpp * Faq: www.mazclub.com * */ #include "keypad.h" // State: char KeyState; // Bit pattern after each scan: char KeyCode; // Output value from the virtual 74HC922: KeyPressed KeyValue; // KeyDown is set if key is down: char KeyDown; // KeyNew is set every time a new key is down: char KeyNew; // 映射表 char KeyTable[12][2]; // Pin of Row uint16_t _rows[] = {KEYx0, KEYx1, KEYx2, KEYx3}; uint16_t _cols[] = {KEYy0, KEYy1, KEYy2, KEYy3}; //构造函数 void Keypad(void) { Stop(); KeyState = 0; // 按键状态初始 0 } //扫描键盘 void Scan_Keyboard(void){ switch (KeyState) { case 0: { if (AnyKey()) { char scankey = ScanKey(); if (scankey != 0xff) KeyCode = scankey; KeyState = 1; } break; } case 1: { if (SameKey()) { FindKey(); KeyState = 2; } else KeyState = 0; break; } case 2: { if (SameKey()) { } else KeyState = 3; break; } case 3: { if (SameKey()) { KeyState = 2; } else { ClearKey(); KeyState = 0; } break; } } // func end } // 有键按下 char AnyKey(void) { //Start(); //拉低 int r = -1; for (r = 0; r < row_count; r++) { if (In(_rows[r]) == 0) // In macro break; } //Stop(); //恢复 if (!(0 <= r && r < row_count)) return 0; else return 1; } // 键按下, 键值相同 char SameKey(void) { // char KeyCode_new = KeyCode; char KeyCode_new = ScanKey(); if (KeyCode == KeyCode_new) return 1; else return 0; } // 扫描键 char ScanKey(void) { /* 行扫描 */ int r = -1; for (r = 0; r < row_count; r++) { if (In(_rows[r]) == 0) // In macro break; } /* 若没有找到有效行,返回 */ if (!(0 <= r && r < row_count)) { return 0xff; } /* 列扫描,找出行上哪个被拉低 */ int c = -1; for (c = 0; c < col_count; c++) { // 轮流输出列线 Cols_out(~(1 << c)); if (In(_rows[r]) == 0) // In macro break; } /* 给所有的列重新充电 */ Start(); /* 若没有找到有效列,返回 */ if (!(0 <= c && c < col_count)) return 0xff; return r * col_count + c; } // FindKey compares KeyCode to values in KeyTable. // If match, KeyValue, KeyDown and KeyNew are updated. void FindKey(void) { KeyValue = (KeyPressed)KeyCode; KeyDown = 1; KeyNew = 1; } void ClearKey(void) { KeyDown = 0; } KeyPressed getKey(void) { if(KeyNew) { KeyNew = 0; return KeyValue; } else return Key_None; } void Start(void) { /* 列输出0, 拉低行 */ PORT_COL->BRR = COLS; } void Stop(void) { /* 列输出1,使行不被拉低 */ PORT_COL->BSRR = COLS; } // cols bus output void Cols_out(uint16_t v) { if ((v & 0x01) > 0) //0b001 High(_cols[0]); else Low(_cols[0]); if ((v & 0x02) > 0) //0b010 High(_cols[1]); else Low(_cols[1]); if ((v & 0x04) > 0) //0b100 High(_cols[2]); else Low(_cols[2]); if ((v & 0x08) > 0) //0b100 High(_cols[3]); else Low(_cols[3]); }
相关文章推荐
- eclipse里访问tomcat首页出现404错误解决方法
- OAUTH appkey appsecret token sign签名等
- Drools 规则语法
- sys.sysprocesses视图的使用小结
- Runtime基本知识记录
- 1026. 程序运行时间(15)
- Connection Error: Io 异常: Connection refused(DESCRIPTION=(TMP=)(VSNNUM=186647040)(ERR=12505)(ERROR_ST
- UICollectionView的下拉刷新无法滑动
- ElasticSearch学习6_从[FIELDDATA]Data too large错误看FieldData配置
- 正确认识H.264与MPEG-4技术产品
- Xcode如何添加字体库--
- 交互体验杂记
- [转]用NPOI操作EXCEL--数据有效性
- 【转载】“思维导图”制作注意问题
- centos 6 更新 libcurl
- 100. Same Tree
- 如何把Win7系统桌面上的内容保存在非系统盘
- 天声人語 20151223 戦後70年のひもじさ
- Win10开发:ListView实现分组和索引
- 在线加密解密很好的一个网站