什么是数码管?
数码管非常常见,就是8字形管,形状很红路灯的倒计时一样,不过红绿灯是用多个LED模拟数码管,
从上图可以看到一个数码管有8段组成,abcdefg七段组成数字,dp是小数点,而七段数码管就 是少了dp小数点;数码管的abcdefg分别对应P0的低7位,dp对应第8位;由于我们的是共阴极的,所以只要在对应的段上加上高电平就可以点亮这个数码管。
我们的代码实现如下:
#include<reg52.h>
typedef unsigned char u8;
typedef unsigned int u16;
#define TUBE P0 //定义宏变量
sbit S1=P2^2; //这三位是片选,我们的板子上有8个数码管,通过片选可以让任意一个有效;
sbit S2=P2^3;
sbit S3=P2^4;
u8 code digit_table[]={//定义每一个数字对应的数码管值
0x3f/*0*/, 0x06/*1*/, 0x5b/*2*/, 0x4f/*3*/,
0x66/*4*/, 0x6d/*5*/, 0x7d/*6*/, 0x07/*7*/,
0x7f/*8*/, 0x6f/*9*/, 0x77/*A*/, 0x7c/*b*/,
0x39/*C*/, 0x5e/*d*/, 0x79/*E*/, 0x71/*F*/,
0x00
};
void select_tube(u8 n)
{
S1=n%2;
S2=n/2%2;
S3=n/4%2;
}
void delay_ms(u16 n)
{
u8 i;
while(n--)
{
i = 111;
while(i--);
}
}
void main()
{
u8 j;
while(1)
{
for(j=0; j < 16; j++)
{
select_tube(0);
TUBE=digit_table[j];
delay_ms(300);
}
}
}
这个程序的效果就是让第一个数码管循环显示0-F。
u8 code digit_table[]={//定义每一个数字对应的数码管值
0x3f/*0*/, 0x06/*1*/, 0x5b/*2*/, 0x4f/*3*/,
0x66/*4*/, 0x6d/*5*/, 0x7d/*6*/, 0x07/*7*/,
0x7f/*8*/, 0x6f/*9*/, 0x77/*A*/, 0x7c/*b*/,
0x39/*C*/, 0x5e/*d*/, 0x79/*E*/, 0x71/*F*/,
0x00
};
大家有没有发现这里有个code关键字,我也是第一次遇到,C语音中没有这个关键字,这个关键字是用来告诉编译器数组digit_table放在代码段,而不是放在默认的数据段;
放在代码段可以减小程序的体积,但是会放在代码段的变量是不能修改的,必须是只读的;
我还遇到一个疑问,正常来说如果放在代码段,code应该会增大,而data应该会减小;反过来如果放在数据段,data应该变大,而code应该变小,但结果却是放在代码段,data和code都变小了,如下:
没有使用code编译时:
Program Size: data=26.0 xdata=0 code=230
使用code编译时:
Program Size: data=9.0 xdata=0 code=99
这是一个值得研究的问题!