51單片機(jī)----16*16LED點(diǎn)陣
一、LED點(diǎn)陣發(fā)光原理
8*8單色單片機(jī)結(jié)構(gòu)圖如下:
從電路圖中很簡(jiǎn)單的就可以看出來(lái),想要點(diǎn)亮點(diǎn)陣中的某一個(gè)LED燈。只要使得那個(gè)燈所在的行輸出高電平,所在列輸出低電平就好。
二、點(diǎn)陣掃描實(shí)驗(yàn)
1 /***********************************************
2 實(shí)驗(yàn)名稱(chēng): 點(diǎn)陣掃描
3 實(shí)驗(yàn)說(shuō)明: 掃描每個(gè)LED燈,檢查點(diǎn)陣是否完好
4 實(shí)驗(yàn)時(shí)間: 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;//鎖存器時(shí)鐘
14 sbit S_CLK = P3^6;//移位寄存器時(shí)鐘
15
16 //data3:右邊半塊列數(shù)據(jù);data2:左邊半塊列數(shù)據(jù)
17 //data1:下邊半塊行數(shù)據(jù);data0:上邊半塊行數(shù)據(jù)
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++); //延時(shí)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++); //延時(shí)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++); //延時(shí)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); //循環(huán)左移
57 for(j=0;j<20000;j++); //延時(shí)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++); //延時(shí)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 //先移入的會(huì)被后面移入的數(shù)據(jù)推移到后面的595中,所以需要先移入data3
91 for(i=0;i<8;i++)
92 {
93 //先移入高位再移入低位,移位寄存器移入的第一位就是輸出的最高位
94 MOSIO = data3 >> 7;
95 data3 <<= 1;
96 S_CLK = 0;//給一個(gè)上升沿,移位
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 //上升沿時(shí)將移位寄存器數(shù)據(jù)移到鎖存器中用于顯示,平時(shí)保持低電平,數(shù)據(jù)不變
122 R_CLK = 0;
123 R_CLK = 1;
124 R_CLK = 0;
125
126 }
這里我用到的是16*16的點(diǎn)陣。其實(shí)也就是4個(gè)8*8的小點(diǎn)陣組成起來(lái)的。其結(jié)構(gòu)圖如下:
12
34
這里只是簡(jiǎn)單示意一下。。。其中4個(gè)小塊都是與一個(gè)相對(duì)應(yīng)的74HC595相連。每個(gè)74HC595又是級(jí)聯(lián)的,入口只有一個(gè),我們需要輸入相對(duì)應(yīng)的行,列電平情況來(lái)控制LED燈的亮滅。
根據(jù)74HC595的結(jié)構(gòu)可以知道,輸入的數(shù)據(jù)是8位8位的輸入的。最開(kāi)始輸入的8位數(shù)據(jù)會(huì)被后面的輸入數(shù)據(jù)推移到第四個(gè)74HC595中。
所以實(shí)際輸入時(shí),是先輸入2和4的列數(shù)據(jù),再輸入1和3的列數(shù)據(jù),然后再是3和4的行數(shù)據(jù),最后才是1和2的行數(shù)據(jù)。
三、16*16點(diǎn)陣倒計(jì)時(shí)
1 /***********************************************************************
2 實(shí)驗(yàn)名稱(chēng): 16*16點(diǎn)陣數(shù)字倒計(jì)時(shí)
3 實(shí)驗(yàn)時(shí)間: 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 //顯示數(shù)字10
26 for(c=i;c>0;c--)//延時(shí)
27 for(j=0;j<16;j++)
28 {
29 //字模取出來(lái)的數(shù)據(jù)是跟實(shí)際實(shí)際所需數(shù)據(jù)相反的,所以要取反。
30 //函數(shù)對(duì)應(yīng)的參數(shù)分別表示列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 //顯示數(shù)字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 //顯示數(shù)字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 //顯示數(shù)字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 //顯示數(shù)字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 //顯示數(shù)字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 //顯示數(shù)字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 //顯示數(shù)字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 //顯示數(shù)字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 //顯示數(shù)字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 //顯示數(shù)字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 //先移入的會(huì)被后面移入的數(shù)據(jù)推移到后面的595中,所以需要先移入data3
129 for(i=0;i<8;i++)
130 {
131 //先移入高位再移入低位,移位寄存器移入的第一位就是輸出的最高位
132 MOSIO = data3 >> 7;
133 data3 <<= 1;
134 S_CLK = 0;//給一個(gè)上升沿,移位
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 //上升沿時(shí)將移位寄存器數(shù)據(jù)移到鎖存器中用于顯示,平時(shí)保持低電平,數(shù)據(jù)不變
160 R_CLK = 0;
161 R_CLK = 1;
162 R_CLK = 0;
163 }
array.h頭文件如下:
1 //點(diǎn)陣顯示數(shù)組
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數(shù)字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 //數(shù)字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 //數(shù)字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 //數(shù)字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 //數(shù)字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 //數(shù)字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 //數(shù)字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 //數(shù)字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 //數(shù)字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 //數(shù)字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 //數(shù)字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 //數(shù)字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};
頭文件的數(shù)據(jù)是通過(guò)字模軟件得出的。字模軟件的工作原理就是對(duì)于一個(gè)點(diǎn)陣,你想要什么樣的圖像,然后就在相應(yīng)位置數(shù)據(jù)為1。然后再通過(guò)從左到右,從上到下的順序,組成一個(gè)個(gè)8位數(shù)據(jù)。
這些8位數(shù)據(jù)就是頭文件的內(nèi)容。
由此我們就可以知道,通過(guò)字模取出來(lái)的數(shù)據(jù),而我們實(shí)際運(yùn)用過(guò)程中對(duì)于列來(lái)說(shuō)是相反的。
因?yàn)槲覀兿胍c(diǎn)亮對(duì)應(yīng)的LED燈是將它所在行輸出高電平,所在列輸出低電平。所以取出來(lái)的字模數(shù)據(jù)作為列的值的話是相反的。所以這里用了取反。
四、顯示漢字
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--)//延時(shí)
23 for(j=0;j<16;j++)
24 {
25 //字模取出來(lái)的數(shù)據(jù)是跟實(shí)際實(shí)際所需數(shù)據(jù)相反的,所以要取反。
26 //函數(shù)對(duì)應(yīng)的參數(shù)分別表示列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 //先移入的會(huì)被后面移入的數(shù)據(jù)推移到后面的595中,所以需要先移入data3
80 for(i=0;i<8;i++)
81 {
82 //先移入高位再移入低位,移位寄存器移入的第一位就是輸出的最高位
83 MOSIO = data3 >> 7;
84 data3 <<= 1;
85 S_CLK = 0;//給一個(gè)上升沿,移位
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;
98 data1 <<= 1;
99 S_CLK = 0;
100 S_CLK = 1;
101 }
102 for(i=0;i<8;i++)
103 {
104 MOSIO = data0 >> 7;
105 data0 <<= 1;
106 S_CLK = 0;
107 S_CLK = 1;
108 }
109
110 //上升沿時(shí)將移位寄存器數(shù)據(jù)移到鎖存器中用于顯示,平時(shí)保持低電平,數(shù)據(jù)不變
111 R_CLK = 0;
112 R_CLK = 1;
113 R_CLK = 0;
114 }
array.h頭文件如下:
1 //點(diǎn)陣顯示數(shù)組
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 // 我
6 unsigned char code tab1[] ={96,2,28,10,16,18,16,2,254,63,16,2,16,18,112,18,24,10,22,10,16,36,16,42,16,49,156,32,0,0,0,0};
7 // 叫
8 unsigned char code tab2[] ={0,16,0,16,158,16,146,16,146,16,146,16,146,24,146,22,146,17,158,16,18,16,0,16,0,16,0,16,0,0,0,0};
9 // 做
10 unsigned char code tab3[] ={80,2,80,2,72,2,232,62,76,17,74,18,232,18,168,18,168,10,168,10,168,4,232,10,40,17,136,32,0,0,0,0};
11 // 大
12 unsigned char code tab4[] ={128,0,128,0,128,0,128,0,254,63,128,0,64,1,64,1,64,1,32,2,32,2,16,4,8,8,6,48,0,0,0,0};
13 // 熙
14 unsigned char code tab5[] ={252,62,36,34,36,34,244,34,148,62,148,2,244,2,36,34,36,34,252,60,0,0,36,17,68,34,66,34,0,0,0,0};
15 // 熙
16 unsigned char code tab6[] ={252,62,36,34,36,34,244,34,148,62,148,2,244,2,36,34,36,34,252,60,0,0,36,17,68,34,66,34,0,0,0,0};
漢字輸出顯示其實(shí)跟數(shù)字沒(méi)什么差別,這里不做累贅講述了。
五、用指針?lè)绞斤@示漢字
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 uchar *p[] = {tab1, tab2, tab3, tab4, tab5, tab6};
16
17 uint i,j,c,k;
18 i = 100;
19
20 while(1)
21 {
22 //分別顯示“我叫做大熙熙”
23 for(k=0;k<6;k++)//一共六個(gè)字
24 {
25 for(c=i;c>0;c--)//延時(shí)
26 {
27 for(j=0;j<16;j++)
28 {
29 //p[k]+2*j+1就是p[k][2*j+1], p[k]+2*j就是p[k][2*j]
30 HC595Pro(~(*(p[k]+2*j+1)),~(*(p[k]+2*j)),tab0[2*j],tab0[2*j+1]);
31 }
32 HC595Pro(0xFF,0xFF,0x00,0x00);//清屏
33 }
34 }
35 }
36 }
37
38 void HC595Pro(uchar data3,uchar data2,uchar data1,uchar data0)
39 {
40 uchar i;
41 for(i=0;i<8;i++)
42 {
43 MOSIO = data3 >> 7;
44 data3 <<= 1;
45 S_CLK = 0;
46 S_CLK = 1;
47 }
48 for(i=0;i<8;i++)
49 {
50 MOSIO = data2 >> 7;
51 data2 <<= 1;
52 S_CLK = 0;
53 S_CLK = 1;
54 }
55 for(i=0;i<8;i++)
56 {
57 MOSIO = data1 >> 7;
58 data1 <<= 1;
59 S_CLK = 0;
60 S_CLK = 1;
61 }
62 for(i=0;i<8;i++)
63 {
64 MOSIO = data0 >> 7;
65 data0 <<= 1;
66 S_CLK = 0;
67 S_CLK = 1;
68 }
69
70 R_CLK = 0;
71 R_CLK = 1;
72 R_CLK = 0;
73 }
array.h頭文件如下:
1 //點(diǎn)陣顯示數(shù)組
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 // 我
6 unsigned char code tab1[] ={96,2,28,10,16,18,16,2,254,63,16,2,16,18,112,18,24,10,22,10,16,36,16,42,16,49,156,32,0,0,0,0};
7 // 叫
8 unsigned char code tab2[] ={0,16,0,16,158,16,146,16,146,16,146,16,146,24,146,22,146,17,158,16,18,16,0,16,0,16,0,16,0,0,0,0};
9 // 做
10 unsigned char code tab3[] ={80,2,80,2,72,2,232,62,76,17,74,18,232,18,168,18,168,10,168,10,168,4,232,10,40,17,136,32,0,0,0,0};
11 // 大
12 unsigned char code tab4[] ={128,0,128,0,128,0,128,0,254,63,128,0,64,1,64,1,64,1,32,2,32,2,16,4,8,8,6,48,0,0,0,0};
13 // 熙
14 unsigned char code tab5[] ={252,62,36,34,36,34,244,34,148,62,148,2,244,2,36,34,36,34,252,60,0,0,36,17,68,34,66,34,0,0,0,0};
15 // 熙
16 unsigned char code tab6[] ={252,62,36,34,36,34,244,34,148,62,148,2,244,2,36,34,36,34,252,60,0,0,36,17,68,34,66,34,0,0,0,0};
這里需要注意的一點(diǎn)就是數(shù)組指針的用法。明白那個(gè)之后整個(gè)程序就很容易了。
六、漢字縱向移屏
1 #include
2 #include "array.h"
3
4 #define uchar unsigned char
5 #define uint unsigned int
6
7 //--定義SPI要使用的 IO--//
8 sbit MOSIO = P3^4;
9 sbit R_CLK = P3^5;
10 sbit S_CLK = P3^6;
11
12 void HC595Pro(uchar data3,uchar data2,uchar data1,uchar data0);
13
14 void main(void)
15 {
16 int k, j, ms;
17
18 //--定義一個(gè)指針數(shù)組指向每個(gè)漢字--//
19 uchar *p[] = {tab8, tab1, tab2, tab3, tab4, tab5, tab6, tab7};
20 while(1)
21 {
22
23 for(ms = 20; ms > 0; ms--) //移動(dòng)定格時(shí)間設(shè)置
24 {
25 for(k = 0; k < 16; k++)
26 {
27 //因?yàn)樽帜\浖〉臄?shù)組是高電平有效,所以列要取反
28 HC595Pro(~(*(p[0] + 2*(k+j) + 1)),~(*(p[0] + 2*(k+j) )),tab0[2*k],tab0[2*k + 1]);
29 }
30
31 HC595Pro(0xFF,0xFF,0x00,0x00);//清屏
32 }
33 j++;
34 if(j == (7*16) )
35 {
36 j = 0;
37 }
38
39 }
40 }
41
42
43 void HC595Pro(uchar data3,uchar data2,uchar data1,uchar data0)
44 {
45 uchar i;
46 for(i=0;i<8;i++)
47 {
48 MOSIO = data3 >> 7;
49 data3 <<= 1;
50 S_CLK = 0;
51 S_CLK = 1;
52 }
53 for(i=0;i<8;i++)
54 {
55 MOSIO = data2 >> 7;
56 data2 <<= 1;
57 S_CLK = 0;
58 S_CLK = 1;
59 }
60 for(i=0;i<8;i++)
61 {
62 MOSIO = data1 >> 7;
63 data1 <<= 1;
64 S_CLK = 0;
65 S_CLK = 1;
66 }
67 for(i=0;i<8;i++)
68 {
69 MOSIO = data0 >> 7;
70 data0 <<= 1;
71 S_CLK = 0;
72 S_CLK = 1;
73 }
74
75 R_CLK = 0;
76 R_CLK = 1;
77 R_CLK = 0;
78 }
array.h頭文件如下:
//點(diǎn)陣顯示數(shù)組
//用于行掃描
unsigned char code tab0[] = {0x00, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80,
0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80, 0x00};
//全滅
unsigned char code tab8[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
// 我
unsigned char code tab1[] ={96,2,28,10,16,18,16,2,254,63,16,2,16,18,112,18,24,10,22,10,16,36,16,42,16,49,156,32,0,0,0,0};
// 叫
unsigned char code tab2[] ={0,16,0,16,158,16,146,16,146,16,146,16,146,24,146,22,146,17,158,16,18,16,0,16,0,16,0,16,0,0,0,0};
// 做
unsigned char code tab3[] ={80,2,80,2,72,2,232,62,76,17,74,18,232,18,168,18,168,10,168,10,168,4,232,10,40,17,136,32,0,0,0,0};
// 大
unsigned char code tab4[] ={128,0,128,0,128,0,128,0,254,63,128,0,64,1,64,1,64,1,32,2,32,2,16,4,8,8,6,48,0,0,0,0};
// 熙
unsigned char code tab5[] ={252,62,36,34,36,34,244,34,148,62,148,2,244,2,36,34,36,34,252,60,0,0,36,17,68,34,66,34,0,0,0,0};
// 熙
unsigned char code tab6[] ={252,62,36,34,36,34,244,34,148,62,148,2,244,2,36,34,36,34,252,60,0,0,36,17,68,34,66,34,0,0,0,0};
//全滅
unsigned char code tab7[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
主函數(shù)中的*(p[0] + 2*(k+j) + 1)就是P[0][2(k+j)+1],*(p[0] + 2*(k+j))就是P[0][2(k+j)],就是P數(shù)組的第0行。
我們先來(lái)看看怎么縱向顯示漢字。縱向移動(dòng)就可以理解為一開(kāi)始是有一個(gè)無(wú)限大的點(diǎn)陣是讓你放你想要的內(nèi)容的。加入你一開(kāi)始放好了。但是一開(kāi)始只顯示一個(gè)漢字,然后隔一段時(shí)間,整個(gè)向上移一行,再顯示一張圖像。以此循環(huán),直到整個(gè)全部顯示完。
就是通過(guò)這個(gè)原理,實(shí)現(xiàn)縱向移動(dòng)的。
至于j的值怎么判斷,我是這么理解的:
“我叫做大熙熙”一共六個(gè)字,然后加上最前面和最后的全滅,一共是8*32位。
所以整個(gè)數(shù)組最大為P[0][255](根據(jù)所指向的位置分析,P[0][32]就是P[1][0])。
所以這里j取7*16時(shí),數(shù)組最大為P[0][255],最后一位沒(méi)讀,但是數(shù)組本身存的值為0,取反之后就是1,列為高電平的話就算不讀也是滅的。
相反,但是如果取8*16的話,數(shù)組最大為P[0][287],多出來(lái)的幾位因?yàn)閿?shù)組沒(méi)初始化過(guò),所以不知道相對(duì)應(yīng)的地址會(huì)是什么值。所以可能會(huì)造成有點(diǎn)地方亮,影響最終效果。
總而言之,最后的判斷值越接近實(shí)際數(shù)組大小越好。