51单片机4x4矩阵键盘扫描+数码管显示(二)(修bug篇)
51单片机4x4矩阵键盘扫描+数码管显示(二)(修bug篇)
修正上一篇文章显示效果《51单片机4x4矩阵键盘扫描+数码管显示》闪烁,消隐处理,优化。

- 材料:
AT89C52、2位数码管、74HC595、
- Proteus仿真
在调试效果的时候,总想着在数码管位显示之间加延时来消除那种视觉上的闪烁,效果不理想,后面直接在数码管显示完后,直接让数码管做断电信号处理,也就是让P25和P26拉低,但是还是需要在位和位显示直接加一定的延时。
实例代码(先行后列扫描法)
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
| #include<reg52.h> #include "intrins.h"
sbit ST=P2^0;//定义74HC595移位寄存器 sbit SH=P2^2; sbit DS=P2^1;
sbit P25=P2^5;//数码管十位显示 sbit P26=P2^6;//数码管个位显示 typedef unsigned int u16; //对数据类型进行声明定义 typedef unsigned char u8; #define temp P1 //定义按键I/O口 u8 smgduan[]= {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};//共阳数码管段码 u8 duanZhi[]= {0,0};//数码管显示位数的数值数组 u8 gewei, shiwei; u8 num=0;
void SendTo595(u8 byteData); void keyscan2();
void display(u8 date); void delay(int s) { u16 i,j; for(i=0; i<s; i++) //延时函数 for(j=114; j>0; j--); } void main() {
while(1) { keyscan2(); } } /\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \*函数名 :SendTo595 \*功能 :串行发送8个比特(一个字节)的数据给595,再并行输出 \*参数 :byteData \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/ void SendTo595(u8 byteData) { char i=0; // P2=duanMa[n]; ST = 0; //ST //先拉低,为后面的上升沿做准备 for(i; i<8; i++) { // SH = 0;//先拉低, if(byteData&0x80)DS=1; else DS=0; // DS = (byteData&0x80)?1:0; byteData = byteData <<1; //该字节右移一位 SH = 1; \_nop\_(); \_nop\_(); SH = 0; //上升沿,让串行输入时钟变为高电平,并延时2个时钟周期 } /\*位移寄存器数据准备完毕,转移到存储寄存器\*/ ST =1;//上升沿,让存储寄存器时钟变为高电平,并延时2个时钟周期 \_nop\_(); \_nop\_(); // ST = 0; } void display(u8 date) { gewei = date%10; shiwei = date/10; duanZhi[0]=smgduan[shiwei]; duanZhi[1]=smgduan[gewei]; P25=0x01;//十位显示 P26=0x00; SendTo595(duanZhi[0]); //十位显示
delay(6); P25=0x00;//个位显示 P26=0x01; SendTo595(duanZhi[1]);//个位显示。 delay(53);
//消隐 //P2=0X00; P25=0x00; P26=0x00; }
void keyscan2() {
temp=0xf0; // if(temp!=0xf0) //检测是否有键按下 // { // delay(5); //延时消抖 if(temp!=0xf0) //再次检测是否有键按下 { temp=0xf0; //对应IO口拉高,以便检测 switch(temp) //先确定行 { case 0x70: num=1; break; //第一行 case 0xb0: num=5; break; //第二行 case 0xd0: num=9; break; //第三行 case 0xe0: num=13; break; //第四行 } temp=0x0f; //对应IO口拉高,以便检测 switch(temp) //再确定列 { case 0x07: num=num+0; break; //第一列 case 0x0b: num=num+1; break; //第二列 case 0x0d: num=num+2; break; //第三列 case 0x0e: num=num+3; break; //第四列 } display(num); //结合行列扫描的值得出按键对应的数值,并返回 } // } display(num); //结合行列扫描的值得出按键对应的数值,并返回 }
|
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!