51单片机 3个IO口 + TM1638+24个独立按键扫描(非自锁按键)+驱动8位共阳数码管显示+Proteus仿真

51单片机 3个IO口 + TM1638+24个独立按键扫描(非自锁按键)+驱动8位共阳数码管显示+Proteus仿真


在上一版的基础上进行优化,原来是需要物理自锁按键来显示按键值的,在代码上做了优化,实现点动物理按键即可实现自锁,其实是本质上是利用了TM1638数据锁存的特性实现的,代码上的简单处理就可以了,所以只是小小的一点改动。

在这里插入图片描述

主程序代码

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
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
3线IO口控制8位共阳数码管
共阳数码管数据转换
tab[]数组对应共阴断码表,0x3f → 0;0x40 → ‘-’;0x00 → 什么都不显示
\*/

#include<delay.h>
#include<TM1638.h>

unsigned char data DisBuffer[8]={0,0,0,0,0,0,0,0}; /\*显示缓存区\*/ //各个数码管显示的值
unsigned char code tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x40,0x00};//17
/\*数据转换函数\*/
void LedDisplay(unsigned char data0,unsigned char data1,unsigned char data2,unsigned char data3,
unsigned char data4,unsigned char data5,unsigned char data6,unsigned char data7);


void main(void)
{
unsigned char KEY;
LedDisplay(16,16,17,17,9,5,2,7);//数码管显示“-- 9527”
delay\_ms(500);
LedDisplay(17,17,17,17,17,17,17,17);//数码管什么都不显示,相当于清空显示
while(1)
{
KEY = Read\_key();
if(KEY)LedDisplay(16,16,16,KEY/10,KEY%10,16,16,16);
delay\_ms(160); //消除仿真时的闪屏,以及防止在仿真过程数码管黑屏现象
}
}
//共阳数据转换
void LedDisplay(unsigned char ddata0,unsigned char ddata1,unsigned char ddata2,unsigned char ddata3,
unsigned char ddata4,unsigned char ddata5,unsigned char ddata6,unsigned char ddata7)
{
unsigned char writedata0,writedata1,writedata2,writedata3,writedata4,writedata5,writedata6,writedata7;
unsigned char data0,data1,data2,data3,data4,data5,data6,data7;
data0=ddata0;
data1=ddata1;
data2=ddata2;
data3=ddata3;
data4=ddata4;
data5=ddata5;
data6=ddata6;
data7=ddata7;

writedata0=(tab[data0]&0x01)+((tab[data1]&0x01)<<1)+((tab[data2]&0x01)<<2)+((tab[data3]&0x01)<<3)+((tab[data4]&0x01)<<4)
+((tab[data5]&0x01)<<5)+((tab[data6]&0x01)<<6)+((tab[data7]&0x01)<<7);

writedata1=((tab[data0]&0x02)>>1)+((tab[data1]&0x02))+((tab[data2]&0x02)<<1)+((tab[data3]&0x02)<<2)+((tab[data4]&0x02)<<3)
+((tab[data5]&0x02)<<4)+((tab[data6]&0x02)<<5)+((tab[data7]&0x02)<<6);

writedata2=((tab[data0]&0x04)>>2)+((tab[data1]&0x04)>>1)+((tab[data2]&0x04))+((tab[data3]&0x04)<<1)+((tab[data4]&0x04)<<2)
+((tab[data5]&0x04)<<3)+((tab[data6]&0x04)<<4)+((tab[data7]&0x04)<<5);

writedata3=((tab[data0]&0x08)>>3)+((tab[data1]&0x08)>>2)+((tab[data2]&0x08)>>1)+((tab[data3]&0x08))+((tab[data4]&0x08)<<1)
+((tab[data5]&0x08)<<2)+((tab[data6]&0x08)<<3)+((tab[data7]&0x08)<<4);

writedata4=((tab[data0]&0x10)>>4)+((tab[data1]&0x10)>>3)+((tab[data2]&0x10)>>2)+((tab[data3]&0x10)>>1)+((tab[data4]&0x10))
+((tab[data5]&0x10)<<1)+((tab[data6]&0x10)<<2)+((tab[data7]&0x10)<<3);

writedata5=((tab[data0]&0x20)>>5)+((tab[data1]&0x20)>>4)+((tab[data2]&0x20)>>3)+((tab[data3]&0x20)>>2)+((tab[data4]&0x20)>>1)
+((tab[data5]&0x20))+((tab[data6]&0x20)<<1)+((tab[data7]&0x20)<<2);

writedata6=((tab[data0]&0x40)>>6)+((tab[data1]&0x40)>>5)+((tab[data2]&0x40)>>4)+((tab[data3]&0x40)>>3)+((tab[data4]&0x40)>>2)
+((tab[data5]&0x40)>>1)+((tab[data6]&0x40))+((tab[data7]&0x40)<<1);

writedata7=((tab[data0]&0x80)>>7)+((tab[data1]&0x80)>>6)+((tab[data2]&0x80)>>5)+((tab[data3]&0x80)>>4)+((tab[data4]&0x80)>>3)
+((tab[data5]&0x80)>>2)+((tab[data6]&0x80)>>1)+((tab[data7]&0x80));

Write\_COM(0x8a);//亮度
Write\_COM(0x40); //写 数据命令
STB=0;
TM1638\_Write(0xc0); //写地址命令

TM1638\_Write(writedata0);
TM1638\_Write(0x80);
TM1638\_Write(writedata1);
TM1638\_Write(0x00);
TM1638\_Write(writedata2);
TM1638\_Write(0x00);
TM1638\_Write(writedata3);
TM1638\_Write(0x00);
TM1638\_Write(writedata4);
TM1638\_Write(0x00);
TM1638\_Write(writedata5);
TM1638\_Write(0x00);
TM1638\_Write(writedata6);
TM1638\_Write(0x00);
TM1638\_Write(writedata7);
TM1638\_Write(0x00);

STB=1;


}

程序源码和仿真资源

1
2
3
链接:https://pan.baidu.com/s/1isqa2w-Go6c5mERl86HoLw 
提取码:l5qp