差不多是在一个星期以前吧,在实验室做实验的时候,用的函数发生器貌似比较“古老”了,咳咳,学校舍不得换新的,然后我启动的时候发现它有一个数码管检测的过程,就是一段一段的测试并进行显示,这样就能很方便检测哪段数码管显示有问题了。当时觉得这个检测还蛮有趣的,就想着自己把这个程序写出来,也不是有什么难度,算是聊以慰藉吧。
测试显示:先a段亮,然后是b段,再是c,d,e,f,...,直到小数点被点亮,再是显示0,1,2,直到F,之后显示0并接连闪烁3次然后全部灭。这就是整个过程。
首先我们写存储段码的数组,数字什么的段码书上都有,只有分段显示的没有,共阴管的段以a为最低位,dp为最高位,所以分别为0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,分别点亮a~dp段。
然后是延时控制的问题,这里用了两个定时器(感觉有点浪费资源啊),T0用作a,b,...dp,0,1,..F的点亮,而T1主要实现最后的三次闪烁控制。T0里面在显示完最后一个字母后,就关闭T0,接着打开T1,T1里面闪烁就用一个只有两个元素的数组[0x3f, 0x00],元素1显0,元素2灭,就这么循环控制,三次闪烁完毕,关闭T1。
T1里面用的两个计时的变量,一个控制闪烁间隔,一个控制多久时间后灭灯、关定时器。
#include <reg51.h>
#define uchar unsigned char
sbit oe = P1^3;
sbit du = P1^4;
sbit we = P1^5;
uchar flag_t1 = 0, count = 0; //定时器1的两个计时变量
uchar code table[]=
{0x01, 0x02, 0x04, 0x08, 0x10, //共阴段码
0x20, 0x40, 0x80, 0x3f, 0x06,
0x5b, 0x4f, 0x66, 0x6d, 0x7d,
0x07, 0x7f, 0x6f, 0x77, 0x7c,
0x39, 0x5e, 0x79, 0x71, 0x00};
uchar code flash[]={0x3f, 0x00}; //0,灭
uchar flag = 0, i = 0;
void main()
{
oe = 0; //开数码管总使能
du = 0;
we = 0;
TMOD = 0X11; //模式设置
TH0 = (65535 - 50000) / 256; //T0定时初值
TL0 = (65535 - 50000) % 256;
TH1 = (65535 - 50000) / 256;
TL1 = (65535 - 50000) % 256;
ET0 = 1; //允许T0中断
TR0 = 1; //打开T0
ET1 = 1;
//TR = 1;
EA = 1; //允许所有中断
while(1);
}
void t0(void) interrupt 1
{
TH0 = (65535 - 50000) / 256;
TL0 = (65535 - 50000) % 256;
flag++; //计时变量
if(flag == 6)
{
flag = 0;
P0 = 0; //送位选值
we = 1;
we = 0;
//P0 = 0x7f | 0x80;
P0 = table[i++]; //送段码
du = 1;
du = 0;
if(i>24) //判断是否显示完
{
//table[2] = 0x00;
//i = i - 1;
TR0 = 0; //关T0
TR1 = 1; //开T1
i = 0; //i初始为0
}
}
}
void t1(void) interrupt 3
{
TH1 = (65535 - 50000) / 256;
TL1 = (65535 - 50000) % 256;
flag_t1++; //T1计时变量1
count++; //T1计时变量2
if(flag_t1 == 6)
{
flag_t1 = 0;
P0 = 0;
we = 1;
we = 0;
//P0 = 0x7f | 0x80;
P0 = flash[i++];
du = 1;
du = 0;
if(i>1) //闪烁
{
//table[2] = 0x00;
//i = i - 1;
i = 0;
}
}
if(count == 42) //时间到了关T1,数码管全灭
{
TR1 = 0;
P0 = 0x00;
du = 1;
du = 0;
}
}
附程序文件