【Proteus仿真】51单片机+4X4矩阵按键扫描+数码管0-F显示
51单片机+4X4矩阵按键扫描+数码管0-F显示
- 🎞📽📺🎬Proteus仿真实验一效果:

- 🎞📽📺🎬Proteus仿真实验二效果:

- 📓工程项目一架构

📚工程项目一功能说明
📝按键4x4共16个按键,通过按下对应的按键,分别显示0-9,a-f,字符。
✨采用的的共阴数码管,代码实现部分:
1 2 3 4 5 6 7 8
| //共阴数码管段码表 unsigned char code seg[]={0x3f/\*0\*/,0x06/\*1\*/,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77/\*A\*/,0x7C,0x39,0x5E,0x79,0x71/\*F\*/}; void display(unsigned char Num) { P2=seg[Num]; }
|
- 🔰4x4矩阵部分

🌼按键扫描功能算法实现方法一:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| uint16\_t key\_scan(void) { uint16\_t key_val=0; uint16\_t temp=0; /\*\*\*\*\*\*\*\*\*\*\*\*\*扫描第1行\*\*\*\*\*\*\*\*\*\*\*\*\*\*/ P1 = 0X00; P1 = 0XF7; if((P1&0XF0)!=0XF0) { delay\_ms();//消抖 if((P1 & 0XF0)!=0XF0) { temp=(P1&0XF7); switch(temp) { case 0xE7: key_val=1; break; case 0xD7: key_val=2; break; case 0xB7: key_val=3; break; case 0x77: key_val=4; break; default: key_val=0; break; } } } /\*\*\*\*\*\*\*\*\*\*\*\*\*扫描第2行\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/ P1=0X00; P1=0XFB; if((P1&0XF0)!=0XF0) { delay\_ms(); if((P1 & 0XF0)!=0XF0) { temp=(P1&0XFB); switch(temp) { case 0xEB: key_val=5; break;
case 0xDB: key_val=6; break;
case 0xBB: key_val=7; break;
case 0x7B: key_val=8; break;
default: key_val=0; break; } } }
/\*\*\*\*\*\*\*\*\*\*\*\*\*扫描第3行\*\*\*\*\*\*\*\*\*\*\*\*/ P1=0X00; P1=0XFD; if((P1&0XF0)!=0XF0) { delay\_ms(); if((P1 & 0XF0)!=0XF0) { temp=(P1&0XFD); switch(temp) { case 0xED: key_val=9; break; case 0xDD: key_val=10; break; case 0xBD: key_val=11; break; case 0x7D: key_val=12; break; default: key_val=0; break; } } } /\*\*\*\*\*\*\*\*\*\*\*\*\*Scan 4st Line\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/ P1=0X00; P1=0XFE; if((P1&0XF0)!=0XF0) { delay\_ms(); if((P1 & 0XF0)!=0XF0) { temp=(P1&0XFE); switch(temp) { case 0xEE: key_val=13; break; case 0xDE: key_val=14; break; case 0xBE: key_val=15; break; case 0x7E: key_val=16; break; default: key_val=0; break; } } } return key_val; }
|
🌼按键扫描功能算法实现方法二:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| uint16\_t key\_scan(void) { uint16\_t key_val=0; u8 KeyNO =0x10; //行码、列码及扫描得到的关码 u8 row,colm; P1 = 0xf0; delay\_ms(); if(P1 !=0xf0) { delay\_ms(); if(P1 !=0xf0) { row = P1; P1 = 0x0f; delay\_ms(); colm = P1; KeyNO = row + colm; switch(KeyNO) { case 0xf0: key_val = 0;break; case 0xe7: key_val = 1;break;//?1110 0111? case 0xd7: key_val = 2;break;//?1101 0111? case 0xb7: key_val = 3;break;//?1011 0111? case 0x77: key_val = 4;break;// 0111 0111 case 0xeb: key_val = 5;break;//?1110 1011? case 0xDB: key_val = 6;break;// 1101 1011 case 0xbb: key_val = 7;break;//?1011 1011? case 0x7b: key_val = 8;break;//?0111 1011? case 0xed: key_val = 9;break;//?1110 1101? case 0xdd: key_val = 10;break;//?1101 1101? case 0xbd: key_val = 11;break;//?1011 1101? case 0x7d: key_val = 12;break;//?0111 1101? case 0xee: key_val = 13;break;//?1110 1110? case 0xde: key_val = 14;break;//?1101 1110? case 0xbe: key_val = 15;break;//?1011 1110? case 0x7e: key_val = 16;break;//?0111 1110? `` default: key_val = 0; } } } return key_val; }
|
🌻按键扫描功能算法实现方法三:
这种是纵向排列的,与前面的两种数字标号不一样。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| sbit L1=P1^3; //定义键盘的4列线 sbit L2=P1^2; sbit L3=P1^1; sbit L4=P1^0; uint16\_t key\_scan(void) { uint16\_t key_val=0; uint8\_t i=0; P1=0xef; //行扫描初值,P1.4=0,P1.5~P1.7=1 for(i=0;i<=3;i++) //按行扫描,一共4行 { if(L1==0) key_val=i\*4+1; //判断第一列是否有键按下 if(L2==0) key_val=i\*4+2; //判断第二列是否有键按下 if(L3==0) key_val=i\*4+3; //判断第三列是否有键按下 if(L4==0) key_val=i\*4+4; //判断第四列是否有键按下 delay\_ms(); //延时 temp=P1; //读入P1口状态 temp=temp|0x0f;//使P1.3~P1.0为输入 temp=temp<<1; //P1.7~P1.4左移1位,准备下一行扫描 temp=temp|0x0f; //移位后,置P1.3~P1.0为1,保证其仍为输入 P1=temp; //行扫描值送P1口,为下一行扫描做准备 } return key_val; }
|
📖工程项目一主程序代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #include "key\_scan.h" #include "SEG.h"
void main() { static uint16\_t Key_Value=0; display(0); while(1) { Key_Value = key\_scan(); if((Key_Value !=0) && (Key_Value != 16)) display(Key_Value); else if(Key_Value == 16) display(0); } }
|
⛳工程项目一源码和仿真资源
🍁基于Proteus8.12版本仿真
1 2 3
| 链接:https://pan.baidu.com/s/16\_9CiAQmoV61NMHtoqb45Q 提取码:bjk8
|
📖工程项目二
✨采用共阳数码管作为显示,外部按键扫描引入了74LS148来扩展中断,只有在按键被按下的时候才会触发按键扫描。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
| #include <reg52.h>
#define uchar unsigned char #define uint unsigned int
sbit BEEP = P3 ^ 0;
uchar code DSY_CODE[] = { 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e, 0xff };//共阳段码:0 - F
uchar Pre_KeyNO = 16, KeyNO = 16; static bit Button_State = 0;
void DelayMS(uint ms) { uchar t; while(ms--) { for(t = 0; t < 120; t++); } }
void Keys\_Scan() { uchar Tmp; EX0 = 0; P1 = 0x0f; // DelayMS(1); Tmp = P1 ^ 0x0f; switch(Tmp) { case 1: KeyNO = 0; break; case 2: KeyNO = 1; break; case 4: KeyNO = 2; break; case 8: KeyNO = 3; break; default: KeyNO = 16; } P1 = 0xf0; DelayMS(1); Tmp = P1 >> 4 ^ 0x0f; switch(Tmp) { case 1: KeyNO += 0; break; case 2: KeyNO += 4; break; case 4: KeyNO += 8; break; case 8: KeyNO += 12; } Button_State = 0; EX0 = 1; }
void Beep() { uchar i; for(i = 0; i < 120; i++) { DelayMS(1); BEEP = ~BEEP; } BEEP = 1; }
void T0\_Init() //定时器0初始化 { TMOD = 0x01; TH0 = 0x3c; TL0 = 0xb0; EA = 1; //开总中断 ET0 = 1; TR0 = 1; } void main() { P0 = 0xff;//数码管什么都不显示 // T0\_Init();//定时器0初始化 IE = 0x81;//使能EA EX0 IT0 = 1;//一定要选择:边沿触发 while(1) { P1 = 0xf0; if(Button_State){ Keys\_Scan();}
if(Pre_KeyNO != KeyNO) { P0 = DSY_CODE[KeyNO]; Beep(); Pre_KeyNO = KeyNO; } // DelayMS(100); } }
void timer0\_Init() interrupt 1 //定时器0中断函数 {
TL0 = (65536 - 1000) % 256; //1ms预装载值 TH0 = (65536 - 1000) / 256;
} void EX\_INT0() interrupt 0 { Button_State = 1; }
|
📚工程项目二资源
1 2 3
| 链接:https://pan.baidu.com/s/1fdpZx6OftxkZfTqu7uo2iA 提取码:in8t
|
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!