开发板买来半个月,有空就会玩儿玩儿,不过我玩儿的都还是比较初级的东西,所以感觉也没什么可写的,今天就把搞定数码管动态显示的东西记一下吧。
常见的数码管(7-segment display)封装形式有一位数字的,也有多位数字的。在只有一位数字的数码管上显示一个数字(或者在多位封装的数码管上显示若干个一样的数字)叫做静态显示,静态显示不是说显示的数字不可变,而是意味着在显示这个数字期间,数码管的状态不变,是静态的。数码管的动态显示用于多位数码管,拿 4 位数码管来举例,4 位数码管的所有段(segment)引脚是公用的,然后由 4 个位选引脚来决定哪个数字位有效。比如说我们想显示在这个 4 位数码管上显示 0123,那么实际上要做的事情其实是:
- 用位选选中 4 位数码管中的第一个数字位
- 给数码管送 0 这个数字的字模
- 关闭数码管的显示
- 用位选选中 4 位数码管中的第二个数字位
- 给数码管送 1 这个数字的字模
- ……以此类推……
从上面过程可以看出来,就算我们想显示的是一串恒定的数字 0123,但对于 4 位数码管来说,这个过程是一个动态的逐位显示的过程,所以叫动态显示。
环境准备
以下描述都以我手上的普中 HC6800 为准:
- 用跳线帽连接 J15 和 J16
- 用排线连接 JP10(P0)和 J12
- J21 接 VCC
原理
这里我们用 74HC138 这个译码器(Decoder)来实现 2 个 4 位数码管的位选:

74HC138 的真值表如下:

74HC138 有 3 个输入(接 P2.2、P2.3、P2.4),8 个输出,从真值表上可以看出,74HC138 的作用就相当于把一个 3 位二进制数的输入转换成某个输出脚上的低电平。2 个 4 位数码管,做位选刚好够用:)
HC6800 用的 2 个 4 位数码管是共阴极数码管,用 74HC573 锁存器(Latch)来驱动:

74HC573 有 8 个输入,8 个输出:

由于 J21 接了 VCC(LE 高电平),-OE 接了 GND,所以 74HC573 工作在 transparent mode,Dn 如果是低电平,对应的 Qn 也是低电平;如果 Dn 是高电平,对应的 Qn 也是高电平。74HC573 的作用应该是提供点亮数码管所需的电流(这里暂时存疑)。J12 和 JP10 连接以后,P0 就是 74HC573 的输入。
代码
SSD.h
- #ifndef __SEVEN_SEGMENT_DISPLAY__20101030__
- #define __SEVEN_SEGMENT_DISPLAY__20101030__
-
- unsigned char
- GetSSDCode(
- unsigned char n,
- bit bWithDP, // Decimal Point
- bit bCC ); // Common Cathode(-) or Common Anode(+)
-
- unsigned char
- GetEmptySSDCode( bit bCC ); // Common Cathode(-) or Common Anode(+)
-
- #endif // __SEVEN_SEGMENT_DISPLAY__20101030__
SSD.c
- unsigned char code SSDCodes[] =
- {
- 0x3F, // 0 = ABCDEF
- 0x06, // 1 = BC
- 0x5B, // 2 = ABGED
- 0x4F, // 3 = ABCDG
- 0x66, // 4 = BCFG
- 0x6D, // 5 = ACDFG
- 0x7D, // 6 = ACDEFG
- 0x07, // 7 = ABC
- 0x7F, // 8 = ABCDEFG
- 0x6F, // 9 = ABCDFG
- 0x77, // A = ABCEFG
- 0x7C, // b = CDEFG
- 0x39, // C = ADEF
- 0x5E, // d = BCDEG
- 0x79, // E = ADEFG
- 0x71, // F = AEFG
- };
-
- unsigned char
- GetSSDCode(
- unsigned char n,
- bit bWithDP, // Decimal Point
- bit bCC ) // Common Cathode(-) or Common Anode(+)
- {
- unsigned char SSDCode;
- if( n >= 0 && n < sizeof( SSDCodes ) / sizeof( SSDCodes[0] ) )
- SSDCode = SSDCodes[n];
-
- if( bWithDP )
- SSDCode |= 0x80;
-
- return( bCC ? SSDCode : ~SSDCode );
- }
-
- unsigned char
- GetEmptySSDCode( bit bCC ) // Common Cathode(-) or Common Anode(+)
- {
- return( bCC ? 0 : 0xFF );
- }
main.c
- #include <reg52.h>
- #include "SSD.h"
-
- sbit DecoderA = P2^2;
- sbit DecoderB = P2^3;
- sbit DecoderC = P2^4;
-
- void Display( unsigned char pos, unsigned char n )
- {
- switch( pos )
- {
- case 0: DecoderC = 0; DecoderB = 0; DecoderA = 0; break;
- case 1: DecoderC = 0; DecoderB = 0; DecoderA = 1; break;
- case 2: DecoderC = 0; DecoderB = 1; DecoderA = 0; break;
- case 3: DecoderC = 0; DecoderB = 1; DecoderA = 1; break;
- case 4: DecoderC = 1; DecoderB = 0; DecoderA = 0; break;
- case 5: DecoderC = 1; DecoderB = 0; DecoderA = 1; break;
- case 6: DecoderC = 1; DecoderB = 1; DecoderA = 0; break;
- case 7: DecoderC = 1; DecoderB = 1; DecoderA = 1; break;
- }
- P0 = GetSSDCode( n, 0, 1 );
- }
-
- void main()
- {
- unsigned char i = 0;
- do
- {
- for( i = 0; i < 8; ++i )
- {
- Display( i, i );
- P0 = GetEmptySSDCode( 1 );
- }
- }
- while( 1 );
- }
程序烧进 89C52 以后会看到 2 个 4 位数码管上显示 0 到 7 这 8 个数字。