[51单片机学习笔记FOUR]----16*16LED点阵

发布者:码字先生最新更新时间:2017-01-05 来源: eefocus关键字:51单片机  16*16LED  点阵 手机看文章 扫描二维码
随时随地手机看文章

一、LED点阵发光原理

8*8单色单片机结构图如下:

从电路图中很简单的就可以看出来,想要点亮点阵中的某一个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的小点阵组成起来的。其结构图如下:

12
34

这里只是简单示意一下。。。其中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;

 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

 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++)//一共六个字

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

 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],多出来的几位因为数组没初始化过,所以不知道相对应的地址会是什么值。所以可能会造成有点地方亮,影响最终效果。


总而言之,最后的判断值越接近实际数组大小越好。


关键字:51单片机  16*16LED  点阵 引用地址:[51单片机学习笔记FOUR]----16*16LED点阵

上一篇:[51单片机学习笔记THREE]----继电器
下一篇:51单片机寄存器组的设置

推荐阅读最新更新时间:2024-03-16 15:28

51单片机-按键&蜂鸣器&数码管
在上一讲的代码中我们可以不用写“sbit GND = P2^3;”,像宋老师那样直接在开头“P2 = 0xF7;”仅让P2.3输出0其他输出1即可,这样P2.7就有被拉低的条件了。 1.趁热打铁 沿袭上一讲的功能,我们新学的按键知识需要结合所学过的无源蜂鸣器硬件一起捣鼓玩玩。同上一讲的代码功能一样,这次用的是无源蜂鸣器,按键按下时,蜂鸣器就响,松开不按时就不响。 2.分析 我们先缕缕思路,显然无源蜂鸣器要想鸣叫,就不能像“LED2=KEY4;”这样赋值的方式。我们已经知道,在P2.3输出低电平的情况下,K4按下的时候程序中KEY4就等于0,松开不按时KEY4等于1。 这里可以在主函数中的死循环里用“if(KEY4==0
[单片机]
有关51单片机有关晶振的问题总结(干货)
在初学51单片机的时候,总是伴随很多有关于晶振的问题,其实晶振就是如同人的心脏,是血液的脉搏,把单片机的晶振问题搞明白了,51单片机的其他问题迎刃而解…… 有关51单片机有关晶振的问题一并总结出来,希望对学51的童鞋来说能有帮助。 一、为什么51单片机爱用11.0592MHZ晶振? 其一:因为它能够准确地划分成时钟频率,与UART(通用异步接收器/发送器)量常见的波特率相关。特别是较高的波特率(19600,19200),不管多么古怪的值,这些晶振都是准确,常被使用的。 其二:用11.0592晶振的原因是51单片机的定时器导致的。用51单片机的定时器做波特率发生器时,如果用11.0592Mhz的晶振,根据公式算下来需要定时器
[单片机]
详解80C51单片机的四种I/O口
在80C51单片机中有4个双向的8位I/O口P0~P3,在无片外存储器的系统中,这4个I/O口的每一位都可以作为准双向通用I/O使用。 在具有片外存储器的系统中,P0口作为地址线的低8位以及双向数据总线,P2口作为高8位的地址线。这4个I/O口除了可以按字节寻址外,还可以按位寻址。 P0口 下图给出了P0口的逻辑结构,它由一个锁存器,两个三态输入缓冲器,一个多路复用开关,一个与门,一个非门以及控制电路和驱动电路组成。 “锁存器,是数字电路中的一种具有记忆功能的逻辑元件。锁存,就是把信号暂存以维持某种电平状态,在数字电路中则可以记录二进制数字信号 0 和 1 。 只有在有锁存信号时输入的状态被保存到输出,直到下一个锁
[单片机]
详解80C<font color='red'>51单片机</font>的四种I/O口
基于单片机的LED点阵显示控制的设计
摘要:LED点阵显示屏具有运行可靠、安全、节能、成本低、使用方便等特点。本文讨论了基于单片机的LED点阵显示控制系统设计所用的各种方法,制作出一个以单片机作为控制单元的点阵显示屏。设计采用动态扫描的显示方法,选取74LS154和74LS595芯片分别构成行、列驱动电路,单片机通过行、列驱动电路,可对点阵显示模块单元进行行列信号控制,达到控制点阵显示屏正常显示汉字、图片信息的设计要求。 关键词:点阵LED;单片机;显示控制;芯片 由于单片机技术的不断发展以及高亮度LED发光管的出现,使得大屏幕高亮度LED电子广告屏成为可能。与传统的霓虹灯广告相比,LED电子广告屏在显示效果以及可修改性上都有着无法比拟的优势,而且单片机的日益
[工业控制]
基于单片机的LED<font color='red'>点阵</font>显示控制的设计
基于51单片机的大屏幕LED显示屏高速控制方案
引言   LED显示屏的基本工作原理是动态扫描。显示控制的过程是先从数据存储器读得字模数据,再通过单片机的串行口或并行口将数据写给LED点阵片,然后再行扫描。   动态扫描方案和静态显示方案相比节省驱动元件,但要求刷新频率高于50 Hz,以避免显示的图像或文字出现闪烁。由于刷新频率的限制,一片单片机能控制显示元件的片数是较少的。   现在大屏幕LED显示屏的应用已越来越广泛。为了对成百、上千片的LED点阵片实现有序的、快速的显示控制,人们动了许多脑筋,双CPU、双RAM的方案,FPGA的方案等都获得了成功的应用;但是这些方案的显示控制过程还是先读后写。   本方案另开思路:用一条读指令,将读和写合在一步完成,可大大地提高显
[单片机]
基于<font color='red'>51单片机</font>的大屏幕LED显示屏高速控制方案
奥地利微电子推出 144 通道点阵 LED 驱动器
奥地利微电子公司(SWX 股票代码:AMS)推出最先进、最小尺寸(同样 PCB空间的通道数)的LED点阵驱动器AS1119。AS1119可驱动144颗LED,占板面积仅为9 mm²。它不仅减少了外部元件数和连接器引脚数,同时占用的PCB层数更少。可为终端用户带来延长80%的电池寿命、丰富的色彩效果和更流畅的动画播放。AS1119适用于移动电话、个人电子产品和玩具中的点阵显示。 AS1119的设计领先业界,可驱动最多的LED,每颗LED都有一个8位调光控制。AS1119不需要任何外部电阻,且其8位模拟电流控制可对每个矩阵进行微调,以补偿不同颜色的亮度差异,也可以调整RGB LED的白平衡。AS1119为小规模动画集成了
[电源管理]
奥地利微电子推出 144 通道<font color='red'>点阵</font> LED 驱动器
8*8的点阵驱动程序
此程序为8*8的点阵驱动程序,用点阵的关键在于明白其每一个发光二极管亮的原理,本人往往将其看做二维坐标系来处理更为简单,可以说只要熟练应用数组并明白其原理就可以按自己的要求驱动了!! #include reg51.h #define unchar unsigned char #define uint unsigned int unchar code se ={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; unchar code nero ={ {0x00,0x00,0x3e,0x41,0x41,0x41,0x3e,0x00}, //0 {0x00,0x00,0x00,0x00,0x21,0x
[单片机]
基于C8051单片机超声波测距电平触发编写
#include c8051f020.h #include intrins.h #define uchar unsigned char #define uint unsigned int void SYSCLK_Init (void); void PORT_Init (void); void StartModule() ; void display(unsigned char bai,unsigned char shi,unsigned char ge); void delay(unsigned int z); void timerinit(); void delay(unsigned int z); void Timer_Co
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved