当前位置:首页 > 单片机 > 单片机
[导读]想要点亮点阵中的某一个LED灯。只要使得那个灯所在的行输出高电平,所在列输出低电平就好。

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

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

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

STM32与51单片机之间有什么差异呢?两者可以说是一场科技与性能的较量了。在科技飞速发展的今天,微控制器(MCU)已广泛应用于各类电子设备和系统中,发挥着举足轻重的作用。其中,STM32和51单片机作为两种常见的微控制...

关键字: STM32 51单片机 MCU

51单片机将是下述内容的主要介绍对象,通过这篇文章,小编希望大家可以对51单片机的相关情况以及信息有所认识和了解,详细内容如下。

关键字: 单片机 51单片机

在嵌入式系统开发中,单片机是不可或缺的重要组成部分。其中,STM32单片机和51单片机是两种常见的单片机芯片。本文将对比分析这两种单片机的区别,并探讨STM32单片机的优势。

关键字: stm32单片 51单片机

51单片机是指由美国INTEL公司生产的一系列单片机的总称,这一系列单片机包括了许多品种,如8031,8051,8751,8032,8052,8752等,其中8051是最早最典型的产品,该系列其它单片机都是在8051的基...

关键字: 51单片机 串行通信

51单片机是一种常见的微控制器,它具有串行通信接口(Serial Communication Interface,SCI)。通过串口通信接口,51单片机可以与其他设备或系统进行串行通信,实现数据传输和控制。

关键字: 51单片机 串口通信

Pic单片机和51单片机是两种应用广泛的微控制器,它们各自具有不同的特点和优势,选择哪种单片机取决于具体应用需求。下面将对Pic单片机和51单片机进行详细的介绍和对比。

关键字: PIC单片机 51单片机 单片机

随着电子信息技术的快速发展,串行通信在各种应用中得到了广泛的应用。其中,51单片机作为一种常见的嵌入式系统,具有低功耗、高性能、易于编程等特点,常用于各种自动化控制、数据采集等系统中。而PC机具有强大的数据处理能力和丰富...

关键字: 51单片机 PC机 串行通信

51 单片机内部有一个全双工串行接口。什么叫全双工串口呢?一般来说,只能接受或只能发送的称为单工串行;既可接收又可发送,但不能同时进行的称为半双工;能同时接收和发送的串行口称为全双工串行口。

关键字: 51单片机 串口通信 半双工

步进电机是一种无刷电机,可将电脉冲转换为机械旋转。顾名思义,它根据输入脉冲逐步旋转,是现代数字程序控制系统中的主要执行元件。

关键字: 51单片机 步进电机 无刷电机

1.ROM:只读存储器,单片机的只读存储区大多用于存储程序固又称程序存储器。

关键字: 51单片机 工作原理 电路
关闭
关闭