历史上的今天
今天是:2024年10月12日(星期六)
2019年10月12日 | 51单片机----16*16LED点阵
2019-10-12 来源:eefocus
一、LED点阵发光原理
想要点亮点阵中的某一个LED灯。只要使得那个灯所在的行输出高电平,所在列输出低电平就好。
二、点阵扫描实验
1 /***********************************************
2 实验名称: 点阵扫描
3 实验说明: 扫描每个LED灯,检查点阵是否完好
4 实验时间: 2014/12/24
5 ***********************************************/
6 #include
7 #include
8
9 #define uchar unsigned char
10 #define uint unsigned int
11
12 sbit MOSIO = P3^4;//输入口
13 sbit R_CLK = P3^5;//锁存器时钟
14 sbit S_CLK = P3^6;//移位寄存器时钟
15
16 //data3:右边半块列数据;data2:左边半块列数据
17 //data1:下边半块行数据;data0:上边半块行数据
18 void HC595Pro(uchar data3,uchar data2,uchar data1,uchar data0);
19
20 void main()
21 {
22 uint i,j;
23 uchar d;
24
25 while(1)
26 {
27 //全亮
28 HC595Pro(0x00,0x00,0xFF,0xFF);
29 for(i=0;i<40000;i++); //延时40ms
30
31 /*行扫描*/
32 //上半块行扫描
33 d = 0x01;
34 for(i=0;i<8;i++)
35 {
36 HC595Pro(0x00,0x00,0x00,d);
37 d <<= 1;
38 for(j=0;j<20000;j++); //延时20ms
39 }
40 //下半块行扫描
41 d = 0x01;
42 for(i=0;i<8;i++)
43 {
44 HC595Pro(0x00,0x00,d,0x00);
45 d <<= 1;
46 for(j=0;j<20000;j++); //延时20ms
47 }
48
49 /*列扫描*/
50 //左半快列扫描
51 d = 0xFE;
52 for(i=0;i<8;i++)
53 {
54 HC595Pro(0xFF,d,0xFF,0xFF);
55 //如果还想用跟行扫描一样的形式,看main()最下面注释行
56 d = _crol_(d,1); //循环左移
57 for(j=0;j<20000;j++); //延时20ms
58 }
59 //右半块列扫描
60 d = 0xFE;
61 for(i=0;i<8;i++)
62 {
63 HC595Pro(d,0xFF,0xFF,0xFF);
64 d = _crol_(d,1);
65 for(j=0;j<20000;j++); //延时20ms
66 }
67 /******************************************************
68 b1 = 0x01;
69 for(i = 0; i<8; i++)
70 {
71 HC595Pro(0xFF, ~b1, 0xFF, 0xFF);
72 b1 <<= 1;
73 for(j=0; j<20000; j++);
74 }
75
76 b1 = 0x01;
77 for(i = 0; i<8; i++)
78 {
79 HC595Pro(~b1, 0xFF, 0xFF, 0xFF);
80 b1 <<= 1;
81 for(j=0; j<20000; j++);
82 }
83 ******************************************************/
84 }
85 }
86
87 void HC595Pro(uchar data3,uchar data2,uchar data1,uchar data0)
88 {
89 uchar i;
90 //先移入的会被后面移入的数据推移到后面的595中,所以需要先移入data3
91 for(i=0;i<8;i++)
92 {
93 //先移入高位再移入低位,移位寄存器移入的第一位就是输出的最高位
94 MOSIO = data3 >> 7;
95 data3 <<= 1;
96 S_CLK = 0;//给一个上升沿,移位
97 S_CLK = 1;
98 }
99 for(i=0;i<8;i++)
100 {
101 MOSIO = data2 >> 7;
102 data2 <<= 1;
103 S_CLK = 0;
104 S_CLK = 1;
105 }
106 for(i=0;i<8;i++)
107 {
108 MOSIO = data1 >> 7;
109 data1 <<= 1;
110 S_CLK = 0;
111 S_CLK = 1;
112 }
113 for(i=0;i<8;i++)
114 {
115 MOSIO = data0 >> 7;
116 data0 <<= 1;
117 S_CLK = 0;
118 S_CLK = 1;
119 }
120
121 //上升沿时将移位寄存器数据移到锁存器中用于显示,平时保持低电平,数据不变
122 R_CLK = 0;
123 R_CLK = 1;
124 R_CLK = 0;
125
126 }
这里我用到的是16*16的点阵。其实也就是4个8*8的小点阵组成起来的。
其中4个小块都是与一个相对应的74HC595相连。每个74HC595又是级联的,入口只有一个,我们需要输入相对应的行,列电平情况来控制LED灯的亮灭。
根据74HC595的结构可以知道,输入的数据是8位8位的输入的。最开始输入的8位数据会被后面的输入数据推移到第四个74HC595中。
所以实际输入时,是先输入2和4的列数据,再输入1和3的列数据,然后再是3和4的行数据,最后才是1和2的行数据。
三、16*16点阵倒计时
1 /***********************************************************************
2 实验名称: 16*16点阵数字倒计时
3 实验时间: 2014/12/26
4 ***********************************************************************/
5 #include
6 #include
7
8 #define uchar unsigned char
9 #define uint unsigned int
10
11 sbit MOSIO = P3^4;
12 sbit R_CLK = P3^5;
13 sbit S_CLK = P3^6;
14
15 void HC595Pro(uchar data3,uchar data2,uchar data1,uchar data0);
16
17 void main()
18 {
19 uint i,c;
20 uchar j;
21 i = 100;
22
23 while(1)
24 {
25 //显示数字10
26 for(c=i;c>0;c--)//延时
27 for(j=0;j<16;j++)
28 {
29 //字模取出来的数据是跟实际实际所需数据相反的,所以要取反。
30 //函数对应的参数分别表示列2,列1,行2,行1
31 HC595Pro(~tab1[2*j+1],~tab1[2*j],tab0[2*j],tab0[2*j+1]);
32 }
33 HC595Pro(0xFF,0xFF,0x00,0x00);//清屏
34
35 //显示数字09
36 for(c=i;c>0;c--)
37 for(j=0;j<16;j++)
38 {
39 HC595Pro(~tab2[2*j+1],~tab2[2*j],tab0[2*j],tab0[2*j+1]);
40 }
41 HC595Pro(0xFF,0xFF,0x00,0x00);//清屏
42
43 //显示数字08
44 for(c=i;c>0;c--)
45 for(j=0;j<16;j++)
46 {
47 HC595Pro(~tab3[2*j+1],~tab3[2*j],tab0[2*j],tab0[2*j+1]);
48 }
49 HC595Pro(0xFF,0xFF,0x00,0x00);//清屏
50
51 //显示数字07
52 for(c=i;c>0;c--)
53 for(j=0;j<16;j++)
54 {
55 HC595Pro(~tab4[2*j+1],~tab4[2*j],tab0[2*j],tab0[2*j+1]);
56 }
57 HC595Pro(0xFF,0xFF,0x00,0x00);//清屏
58
59 //显示数字06
60 for(c=i;c>0;c--)
61 for(j=0;j<16;j++)
62 {
63 HC595Pro(~tab5[2*j+1],~tab5[2*j],tab0[2*j],tab0[2*j+1]);
64 }
65 HC595Pro(0xFF,0xFF,0x00,0x00);//清屏
66
67 //显示数字05
68 for(c=i;c>0;c--)
69 for(j=0;j<16;j++)
70 {
71 HC595Pro(~tab6[2*j+1],~tab6[2*j],tab0[2*j],tab0[2*j+1]);
72 }
73 HC595Pro(0xFF,0xFF,0x00,0x00);//清屏
74
75 //显示数字04
76 for(c=i;c>0;c--)
77 for(j=0;j<16;j++)
78 {
79 HC595Pro(~tab7[2*j+1],~tab7[2*j],tab0[2*j],tab0[2*j+1]);
80 }
81 HC595Pro(0xFF,0xFF,0x00,0x00);//清屏
82
83 //显示数字03
84 for(c=i;c>0;c--)
85 for(j=0;j<16;j++)
86 {
87 HC595Pro(~tab8[2*j+1],~tab8[2*j],tab0[2*j],tab0[2*j+1]);
88 }
89 HC595Pro(0xFF,0xFF,0x00,0x00);//清屏
90
91 //显示数字02
92 for(c=i;c>0;c--)
93 for(j=0;j<16;j++)
94 {
95 HC595Pro(~tab9[2*j+1],~tab9[2*j],tab0[2*j],tab0[2*j+1]);
96 }
97 HC595Pro(0xFF,0xFF,0x00,0x00);//清屏
98
99 //显示数字01
100 for(c=i;c>0;c--)
101 for(j=0;j<16;j++)
102 {
103 HC595Pro(~tab10[2*j+1],~tab10[2*j],tab0[2*j],tab0[2*j+1]);
104 }
105 HC595Pro(0xFF,0xFF,0x00,0x00);//清屏
106
107 //显示数字00
108 for(c=i;c>0;c--)
109 for(j=0;j<16;j++)
110 {
111 HC595Pro(~tab11[2*j+1],~tab11[2*j],tab0[2*j],tab0[2*j+1]);
112 }
113 HC595Pro(0xFF,0xFF,0x00,0x00);//清屏
114
115 //显示字母GO
116 for(c=i;c>0;c--)
117 for(j=0;j<16;j++)
118 {
119 HC595Pro(~tab12[2*j+1],~tab12[2*j],tab0[2*j],tab0[2*j+1]);
120 }
121 HC595Pro(0xFF,0xFF,0x00,0x00);//清屏
122 }
123 }
124
125 void HC595Pro(uchar data3,uchar data2,uchar data1,uchar data0)
126 {
127 uchar i;
128 //先移入的会被后面移入的数据推移到后面的595中,所以需要先移入data3
129 for(i=0;i<8;i++)
130 {
131 //先移入高位再移入低位,移位寄存器移入的第一位就是输出的最高位
132 MOSIO = data3 >> 7;
133 data3 <<= 1;
134 S_CLK = 0;//给一个上升沿,移位
135 S_CLK = 1;
136 }
137 for(i=0;i<8;i++)
138 {
139 MOSIO = data2 >> 7;
140 data2 <<= 1;
141 S_CLK = 0;
142 S_CLK = 1;
143 }
144 for(i=0;i<8;i++)
145 {
146 MOSIO = data1 >> 7;
147 data1 <<= 1;
148 S_CLK = 0;
149 S_CLK = 1;
150 }
151 for(i=0;i<8;i++)
152 {
153 MOSIO = data0 >> 7;
154 data0 <<= 1;
155 S_CLK = 0;
156 S_CLK = 1;
157 }
158
159 //上升沿时将移位寄存器数据移到锁存器中用于显示,平时保持低电平,数据不变
160 R_CLK = 0;
161 R_CLK = 1;
162 R_CLK = 0;
163 }
array.h头文件如下:
1 //点阵显示数组
2 //用于行扫描
3 unsigned char code tab0[] = {0x00, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80,
4 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80, 0x00};
5 //1数字10的字模
6 unsigned char code tab1[] = {0, 0, 0, 0, 0, 0, 8, 24, 14, 36, 8, 66, 8, 66, 8, 66,
7 8, 66, 8, 66, 8, 66, 8, 36, 62, 24, 0, 0, 0, 0, 0, 0};
8 //数字09的字模
9 unsigned char code tab2[] = {0, 0, 0, 0, 0, 0, 24, 24, 36, 36, 66, 66, 66, 66, 66,
10 66, 66, 100, 66, 88, 66, 64, 66, 64, 36, 36, 24, 28, 0, 0, 0, 0} ;
11 //数字08的字模
12 unsigned char code tab3[] = {0, 0, 0, 0, 0, 0, 24, 60, 36, 66, 66, 66, 66, 66, 66, 36,
13 66, 24, 66, 36, 66, 66, 66, 66, 36, 66, 24, 60, 0, 0, 0, 0};
14 //数字07的字模
15 unsigned char code tab4[] = {0, 0, 0, 0, 0, 0, 24, 126, 36, 34, 66, 34, 66, 16, 66, 16,
16 66, 8, 66, 8, 66, 8, 66, 8, 36, 8, 24, 8, 0, 0, 0, 0};
17 //数字06的字模
18 unsigned char code tab5[] = {0, 0, 0, 0, 0, 0, 24, 56, 36, 36, 66, 2, 66, 2, 66, 26, 66,
19 38, 66, 66, 66, 66, 66, 66, 36, 36, 24, 24, 0, 0, 0, 0};
20 //数字05的字模
21 unsigned char code tab6[] = {0, 0, 0, 0, 0, 0, 24, 126, 36, 2, 66, 2, 66, 2, 66, 26, 66,
22 38, 66, 64, 66, 64, 66, 66, 36, 34, 24, 28, 0, 0, 0, 0};
23 //数字04的字模
24 unsigned char code tab7[] = {0, 0, 0, 0, 0, 0, 24, 32, 36, 48, 66, 40, 66, 36, 66, 36, 66,
25 34, 66, 34, 66, 126, 66, 32, 36, 32, 24, 120, 0, 0, 0, 0};
26 //数字03的字模
27 unsigned char code tab8[] = {0, 0, 0, 0, 0, 0, 24, 60, 36, 66, 66, 66, 66, 32, 66, 24, 66,
28 32, 66, 64, 66, 64, 66, 66, 36, 34, 24, 28, 0, 0, 0, 0};
29 //数字02的字模
30 unsigned char code tab9[] = {0, 0, 0, 0, 0, 0, 24, 60, 36, 66, 66, 66, 66, 66, 66, 32, 66,
31 32, 66, 16, 66, 8, 66, 4, 36, 66, 24, 126, 0, 0, 0, 0};
32 //数字01的字模
33 unsigned char code tab10[] = {0, 0, 0, 0, 0, 0, 24, 8, 36, 14, 66, 8, 66, 8, 66, 8, 66, 8, 66,
34 8, 66, 8, 66, 8, 36, 8, 24, 62, 0, 0, 0, 0};
35 //数字00的字模
36 unsigned char code tab11[] = {0, 0, 0, 0, 0, 0, 24, 24, 36, 36, 66, 66, 66, 66, 66, 66, 66, 66,
37 66, 66, 66, 66, 66, 66, 36, 36, 24, 24, 0, 0, 0, 0};
38 //数字GO的字模
39 unsigned char code tab12[] = {0, 0, 0, 0, 0, 0, 60, 28, 34, 34, 34, 65, 1, 65, 1, 65, 1, 65, 113,
40 65, 33, 65, 34, 65, 34, 34, 28, 28, 0, 0, 0, 0};
头文件的数据是通过字模软件得出的。字模软件的工作原理就是对于一个点阵,你想要什么样的图像,然后就在相应位置数据为1。然后再通过从左到右,从上到下的顺序,组成一个个8位数据。
这些8位数据就是头文件的内容。
由此我们就可以知道,通过字模取出来的数据,而我们实际运用过程中对于列来说是相反的。
因为我们想要点亮对应的LED灯是将它所在行输出高电平,所在列输出低电平。所以取出来的字模数据作为列的值的话是相反的。所以这里用了取反。
四、显示汉字
1 #include
2 #include
3
4 #define uchar unsigned char
5 #define uint unsigned int
6
7 sbit MOSIO = P3^4;
8 sbit R_CLK = P3^5;
9 sbit S_CLK = P3^6;
10
11 void HC595Pro(uchar data3,uchar data2,uchar data1,uchar data0);
12
13 void main()
14 {
15 uint i,c;
16 uchar j;
17 i = 100;
18
19 while(1)
20 {
21 //显示“我”
22 for(c=i;c>0;c--)//延时
23 for(j=0;j<16;j++)
24 {
25 //字模取出来的数据是跟实际实际所需数据相反的,所以要取反。
26 //函数对应的参数分别表示列2,列1,行2,行1
27 HC595Pro(~tab1[2*j+1],~tab1[2*j],tab0[2*j],tab0[2*j+1]);
28 }
29 HC595Pro(0xFF,0xFF,0x00,0x00);//清屏
30
31 //显示“叫”
32 for(c=i;c>0;c--)
33 for(j=0;j<16;j++)
34 {
35 HC595Pro(~tab2[2*j+1],~tab2[2*j],tab0[2*j],tab0[2*j+1]);
36 }
37 HC595Pro(0xFF,0xFF,0x00,0x00);//清屏
38
39 //显示“做”
40 for(c=i;c>0;c--)
41 for(j=0;j<16;j++)
42 {
43 HC595Pro(~tab3[2*j+1],~tab3[2*j],tab0[2*j],tab0[2*j+1]);
44 }
45 HC595Pro(0xFF,0xFF,0x00,0x00);//清屏
46
47 //显示“大”
48 for(c=i;c>0;c--)
49 for(j=0;j<16;j++)
50 {
51 HC595Pro(~tab4[2*j+1],~tab4[2*j],tab0[2*j],tab0[2*j+1]);
52 }
53 HC595Pro(0xFF,0xFF,0x00,0x00);//清屏
54
55 //显示“熙”
56 for(c=i;c>0;c--)
57 for(j=0;j<16;j++)
58 {
59 HC595Pro(~tab5[2*j+1],~tab5[2*j],tab0[2*j],tab0[2*j+1]);
60 }
61 for(c=i;c>0;c--)
62 {
63 HC595Pro(0xFF,0xFF,0x00,0x00);//清屏
64 }
65
66 //显示“熙”
67 for(c=i;c>0;c--)
68 for(j=0;j<16;j++)
69 {
70 HC595Pro(~tab6[2*j+1],~tab6[2*j],tab0[2*j],tab0[2*j+1]);
71 }
72 HC595Pro(0xFF,0xFF,0x00,0x00);//清屏
73 }
74 }
75
76 void HC595Pro(uchar data3,uchar data2,uchar data1,uchar data0)
77 {
78 uchar i;
79 //先移入的会被后面移入的数据推移到后面的595中,所以需要先移入data3
80 for(i=0;i<8;i++)
81 {
82 //先移入高位再移入低位,移位寄存器移入的第一位就是输出的最高位
83 MOSIO = data3 >> 7;
84 data3 <<= 1;
85 S_CLK = 0;//给一个上升沿,移位
86 S_CLK = 1;
87 }
88 for(i=0;i<8;i++)
89 {
90 MOSIO = data2 >> 7;
91 data2 <<= 1;
92 S_CLK = 0;
93 S_CLK = 1;
94 }
95 for(i=0;i<8;i++)
96 {
97 MOSIO = data1 >> 7;
史海拾趣
|
有感于一个老工程师的十大忠告,贴一个小故事 有二个和尚住在隔壁;所谓隔壁是:隔壁那座山。他们分别在相邻的二座山上的庙里。 这二座山之间有一条溪。于是这二个和尚,每天都会在同一时间下山去溪边挑水。久 ...… 查看全部问答> |




