【Proteus仿真】51单片机+矩阵按键扫描+数码管显示
【Proteus仿真】51单片机+矩阵按键扫描+数码管显示
📓程序一说明
🖋通过获取4*4的矩阵按键的键值,映射到字符0-F上,通过数码管显示出来。每获取到不同的按键值,将前面的按键值在数码管上进行移位显示,获取到的最新按键键值都在数码管的最右侧显示。
📝程序代码
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 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
| /\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \* 实 验 名 : 矩阵按键扫描+动态显示数码管实验 \* 使用的IO : 数码管使用P0,P2.2,P2.3,P2.4键盘使用P1 \* 实验效果 : 按矩阵键盘分别显示在数码管上面显示:0-F。 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/ #include <reg51.h>
#define GPIO\_DIG P0 #define GPIO\_KEY P1
sbit LSA=P2^2; sbit LSB=P2^3; sbit LSC=P2^4;
unsigned char code DIG_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, 0x77,0x7c,0x39,0x5e,0x79,0x71}; //0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码 unsigned char KeyValue; //用来存放读取到的键值 unsigned char KeyState; //记录按键的状态,0没有,1有 unsigned char DisplayData[8]; //用来存放要显示的8位数的值 void Delay10ms(); //延时10ms void KeyDown(); //检测按键函数 void DigDisplay(); //动态显示函数 /\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \* 函 数 名 : main \* 函数功能 : 主函数 \* 输 入 : 无 \* 输 出 : 无 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/ void main(void) { KeyState=0; while(1) { KeyDown(); if(KeyState==1) { DisplayData[7]=DisplayData[6]; DisplayData[6]=DisplayData[5]; DisplayData[5]=DisplayData[4]; DisplayData[4]=DisplayData[3]; DisplayData[3]=DisplayData[2]; DisplayData[2]=DisplayData[1]; DisplayData[1]=DisplayData[0]; DisplayData[0]=DIG_CODE[KeyValue]; KeyState=0; } DigDisplay(); } } /\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \* 函 数 名 : DigDisplay \* 函数功能 : 使用数码管显示 \* 输 入 : 无 \* 输 出 : 无 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/ void DigDisplay() { unsigned char i; unsigned int j; for(i=0;i<8;i++) { switch(i) //位选,选择点亮的数码管, { case(0): LSA=0;LSB=0;LSC=0; break;//显示第0位 case(1): LSA=1;LSB=0;LSC=0; break;//显示第1位 case(2): LSA=0;LSB=1;LSC=0; break;//显示第2位 case(3): LSA=1;LSB=1;LSC=0; break;//显示第3位 case(4): LSA=0;LSB=0;LSC=1; break;//显示第4位 case(5): LSA=1;LSB=0;LSC=1; break;//显示第5位 case(6): LSA=0;LSB=1;LSC=1; break;//显示第6位 case(7): LSA=1;LSB=1;LSC=1; break;//显示第7位 } GPIO_DIG = DisplayData[i];//发送段码 j=10; //扫描间隔时间设定 while(j--); GPIO_DIG=0x00;//消隐 } } /\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \* 函 数 名 : KeyDown \* 函数功能 : 检测有按键按下并读取键值 \* 输 入 : 无 \* 输 出 : 无 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/ void KeyDown(void) { unsigned int a=0; GPIO_KEY=0x0f; if(GPIO_KEY!=0x0f) { Delay10ms(); a++; a=0; if(GPIO_KEY!=0x0f) { KeyState=1;//有按键按下 //扫描列 GPIO_KEY=0X0F; // Delay10ms(); switch(GPIO_KEY) { case(0X07): KeyValue=0;break; case(0X0b): KeyValue=1;break; case(0X0d): KeyValue=2;break; case(0X0e): KeyValue=3;break; // default: KeyValue=17; //检测出错回复17意思是把数码管全灭掉。 } //扫描行 GPIO_KEY=0XF0; Delay10ms(); switch(GPIO_KEY) { case(0X70): KeyValue=KeyValue;break; case(0Xb0): KeyValue=KeyValue+4;break; case(0Xd0): KeyValue=KeyValue+8;break; case(0Xe0): KeyValue=KeyValue+12;break; // default: KeyValue=17; } while((a<500)&&(GPIO_KEY!=0xf0)) //按键松手检测 { Delay10ms(); a++; } a=0; } } } /\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \* 函 数 名 : Delay10ms \* 函数功能 : 延时函数,延时10ms \* 输 入 : 无 \* 输 出 : 无 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/ void Delay10ms(void) { unsigned char a,b,c; for(c=1;c>0;c--) for(b=38;b>0;b--) for(a=130;a>0;a--); }
|
📚仿真一资源和程序源码
1 2 3
| 链接:https://pan.baidu.com/s/1MxdzOBWGLoZQz\_57tAulgQ 提取码:7bbr
|
📓程序二说明
🖋通过获取4*4的矩阵按键的键值,映射到字符0-F上,通过数码管显示出来。获取到不同的按键值,将获取到的最新按键键值显示在数码管的最左侧。
📝程序二代码
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 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
| /\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \* 描述: \* \* 矩阵键盘数码管显示键值 \* \* 矩阵键盘定义: \* \* P1.1-P1.3为行线,P1.4-P1.7为列线 \* \* 矩阵键盘P1口 \* \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
#include <reg51.h>
#define uchar unsigned char //宏的定义变量类型 uchar 代替 unsigned char #define uint unsigned int //宏的定义变量类型 uint 代替 unsigned int
static uchar dis_buf = 0; //显示缓存 uchar temp; uchar key; //键顺序码
//用来存放读取到的键值 unsigned char KeyState; //记录按键的状态,0没有,1有 void delay(uchar x); //x\*0.14MS
// 此表为 LED 的字模 0 1 2 3 4 5 6 7 8 9 a b c d e f unsigned char code LED7Code[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71};
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \* \* \* 延时子程序 \* \* \* \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
void delay(uchar x) { uchar j; while((x--) != 0) //CPU执行x\*12次 { for(j = 0; j < 125; j++) { ; } } }
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \* \* \* 键扫描子程序 (4\*4 的矩阵) P1.4 P1.5 P1.6 P1.7为列 \* \* P1.1 P1.2 P1.3为行 \* \* \* \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
void keyscan(void) { unsigned int a=0; temp = 0; P1 = 0xF0; //高四位输入 列为高电平 行为低电平 delay(1); //延时 temp = P1; //读P1口 temp = temp & 0xF0; //屏蔽低四位 temp = ~((temp >> 4) | 0xF0); if(temp == 1) // p1.4 被拉低 key = 1; //第1个按键键值 else if(temp == 2) // p1.5 被拉低 key = 2; //第2个按键键值 else if(temp == 4) // p1.6 被拉低 key = 3; //第3个按键键值 else if(temp == 8) // p1.7 被拉低 key = 4; //第4个按键键值 else key = 16;
P1 = 0x0F; //低四位输入 行为高电平 列为低电平 delay(1); //延时 temp = P1; //读P1口 temp = temp & 0x0F; temp = ~(temp | 0xF0); if(temp == 1) //第一行 p1.0 被拉低 key = key + 0; else if(temp == 2) //第二行 p1.1 被拉低 key = key + 4; else if(temp == 4) //第三行 p1.2 被拉低 key = key + 8; else if(temp == 8) //第四行 p1.3 被拉低 key = key + 12; else key = 16;
while((a<120)&&(P1!=0xf0)) //按键松手检测 { delay(1); a++; } a=0;
dis_buf = key; //键值入显示缓存 dis_buf = dis_buf & 0x0f;//按键值范围:0-F,超出范围显示0
}
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \* \* \*判断键是否按下 \* \* \* \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
void keydown(void) { P1 = 0xF0; //将高4位全部置1 低四位全部置0 if(P1 != 0xF0) //判断按键是否按下 如果按钮按下 会拉低P1其中的一个端口 { KeyState = 1; //有按键按下 keyscan(); //调用按键扫描程序 } }
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \* \* \* 主程序 \* \* \* \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/ void main() { P0 = 0xFF; //置P0口 P1 = 0xFF; //置P1口 delay(10); //延时 KeyState = 0; P0 = LED7Code[dis_buf];//初始状态值 while(1) { keydown(); //调用按键判断检测程序 if(KeyState == 1) { P0 = LED7Code[dis_buf]; KeyState = 0; }
} }
|
📚仿真二资源和程序源码
1 2 3
| 链接:https://pan.baidu.com/s/1Nn2pTSDf2H1atLhHtdCYNA 提取码:8bhw
|
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!