一、LED點陣發光原理
8*8單色單片機結構圖如下:
從電路圖中很簡單的就可以看出來,想要點亮點陣中的某一個LED燈。只要使得那個燈所在的行輸出高電平,所在列輸出低電平就好。
二、點陣掃描實驗
1 /*********************************************** 2 實驗名稱: 點陣掃描 3 實驗說明: 掃描每個LED燈,檢查點陣是否完好 4 實驗時間: 2014/12/24 5 ***********************************************/ 6 #include <reg51.h> 7 #include <intrins.h> 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的小點陣組成起來的。其結構圖如下:
1 | 2 |
3 | 4 |
這里只是簡單示意一下。。。其中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 <reg51.h> 6 #include <array.h> 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 <reg51.h> 2 #include <array.h> 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; 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 //上升沿時將移位寄存器數據移到鎖存器中用於顯示,平時保持低電平,數據不變 111 R_CLK = 0; 112 R_CLK = 1; 113 R_CLK = 0; 114 }
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 // 我 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};
漢字輸出顯示其實跟數字沒什么差別,這里不做累贅講述了。
五、用指針方式顯示漢字
1 #include <reg51.h> 2 #include <array.h> 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++)//一共六個字 24 { 25 for(c=i;c>0;c--)//延時 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 //點陣顯示數組 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};
這里需要注意的一點就是數組指針的用法。明白那個之后整個程序就很容易了。
六、漢字縱向移屏
1 #include <REG51.H> 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 //--定義一個指針數組指向每個漢字--// 19 uchar *p[] = {tab8, tab1, tab2, tab3, tab4, tab5, tab6, tab7}; 20 while(1) 21 { 22 23 for(ms = 20; ms > 0; ms--) //移動定格時間設置 24 { 25 for(k = 0; k < 16; k++) 26 { 27 //因為字模軟件取的數組是高電平有效,所以列要取反 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頭文件如下:
//點陣顯示數組 //用於行掃描 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};
主函數中的*(p[0] + 2*(k+j) + 1)就是P[0][2(k+j)+1],*(p[0] + 2*(k+j))就是P[0][2(k+j)],就是P數組的第0行。
我們先來看看怎么縱向顯示漢字。縱向移動就可以理解為一開始是有一個無限大的點陣是讓你放你想要的內容的。加入你一開始放好了。但是一開始只顯示一個漢字,然后隔一段時間,整個向上移一行,再顯示一張圖像。以此循環,直到整個全部顯示完。
就是通過這個原理,實現縱向移動的。
至於j的值怎么判斷,我是這么理解的:
“我叫做大熙熙”一共六個字,然后加上最前面和最后的全滅,一共是8*32位。
所以整個數組最大為P[0][255](根據所指向的位置分析,P[0][32]就是P[1][0])。
所以這里j取7*16時,數組最大為P[0][255],最后一位沒讀,但是數組本身存的值為0,取反之后就是1,列為高電平的話就算不讀也是滅的。
相反,但是如果取8*16的話,數組最大為P[0][287],多出來的幾位因為數組沒初始化過,所以不知道相對應的地址會是什么值。所以可能會造成有點地方亮,影響最終效果。
總而言之,最后的判斷值越接近實際數組大小越好。
個人意見,解析也不是很專業,不過希望能看懂。。哈哈。。
結語:對於縱向移動的話采用的是行掃描法,然后顯示信息放在列中。橫向移動的話就采用列掃描法,顯示信息放在行中。
這里具體的就不呈現了,因為都差不多啦。