使用简单的循环实现按键消抖。
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int#define KeyPort P1
#define INIT_DISPLAY 0x8C // 初始显示状态// 数码管段码定义(0~15)
uchar code SegCode[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90,0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E};
// 列扫描码定义
uchar code ColCode[] = {0xFE, 0xFD, 0xFB, 0xF7};// 延时函数
void delay(uchar m) {uchar j;while (m--) {for (j = 120; j > 0; j--);}
}// 键盘扫描函数
uchar keyscan() {uchar temp, row, col, i;KeyPort = 0xF0; // 设置行高电平,列低电平delay(10); temp = KeyPort & 0xF0;if (temp != 0xF0) { // 检测到按键按下delay(10); // 消抖temp = KeyPort & 0xF0;if (temp != 0xF0) { // 再次确认按键按下// 确定行号switch (temp) {case 0x70: row = 3; break; // 第一行case 0xB0: row = 2; break; // 第二行case 0xD0: row = 1; break; // 第三行case 0xE0: row = 0; break; // 第四行default: return 16; // 错误情况}// 确定列号for (i = 0; i < 4; i++) {KeyPort = 0xF0 | ColCode[i] & 0x0F; // 确保高 4 位为 1,低 4 位为列扫描码temp = KeyPort & 0xF0;if (temp != 0xF0) { // 检测到按键col = i;break;}} return (row * 4 + col); // 返回按键编号 } }return 16; // 无按键按下
}
void main(void) {uchar keyNum;P2 = INIT_DISPLAY; // 初始状态while (1) {keyNum = keyscan();if (keyNum < 16) {P2 = SegCode[keyNum]; // 显示按键编号对应的数码管段码} else {P2 = INIT_DISPLAY; // 无按键按下时恢复初始状态}}}