作者声明 :我将代码详细的解释到此处,全部代码经过板测,希望对你有帮助
1.以下代码需要着重注意的是:seg[]表,和buff[]表,中的元素数量与对应关系,以便需要再 seg[] 表中添加数据时,能够正确修改buff[]缓冲表中的值。
2.因为比赛是5个小时,这里的代码就没有考虑封装函数(当seg[]表段码数变化时自动将熄灭码同 步到buff[]表中),为了精简代码,可能第一次理解时有些麻烦
#include <DEVELOP.H>
//宏定义译码器选通,该代码见其它文章
#define E(loc) (P2 = (P2 & 0x1F) | ((loc & 0x07) << 5))
xdata char buff[] = {36,36,36,36,36,36,36,36};
xdata char seg[] = {
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,
0x88,0x83,0xC6,0xA1,0x86,0x8E,
0xC0&0x7f,0xF9&0x7f,0xA4&0x7f,0xB0&0x7f,0x99&0x7f,
0x92&0x7f,0x82&0x7f,0xF8&0x7f,0x80&0x7f,0x90&0x7f,
0x88&0x7f,0x83&0x7f,0xC6&0x7f,0xA1&0x7f,0x86&0x7f,0x8E&0x7f,
0xBF,0x8c,0x89,0xc7,0xff
};
//@ 数码管中断更新函数
void Display_Updata(){
static char i = 0;
E(7); P0 = 0xff;
E(6); P0 = 0x01<<i;
E(7); P0 = seg[buff[i]];
i++;
if(i==8)i = 0;
}
//@ 数码管位显设置函数
void D(char loc,num,point){
buff[loc] = num + (point?16:0);
}
以下是对上述代码的每一段的详细解释:
头文件与存储声明
#include <DEVELOP.H> // 开发板专用头文件(定义硬件寄存器地址和常用宏)
xdata char buff[] = {36,36,36,36,36,36,36,36}; // 显示缓冲区(8位初始值为36,对应全灭)
xdata char seg[] = { // 数码管段码表(共37个元素)
/* 基础段码(0-15)*/
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90, // 0-9
0x88,0x83,0xC6,0xA1,0x86,0x8E, // A-F
/* 带小数点段码(16-31,基础段码 & 0x7F)*/
0xC0&0x7f,0xF9&0x7f,...,0x8E&0x7f, // 0.-F.
/* 特殊字符(32-36)*/
0xBF,0x8c,0x89,0xc7,0xff // "-", "P", "H", "L", 全灭
};
存储说明
-
xdata:表示数据存储在外部RAM(扩展内存),适用于51单片机内存扩展场景。
-
buff数组:8字节缓冲区,每个元素对应数码管一位的显示内容(索引值为
seg[]
下标)。 -
seg数组:
-
0-15:标准0-F十六进制段码(共阴极)。
-
16-31:带小数点的0-F段码(通过
&0x7F
操作点亮小数点)。 -
32-36:特殊字符段码(如横杠、字母等)。
-
数码管更新函数 Display_Updata()
void Display_Updata(){
static char i = 0; // 静态变量,记录当前刷新位(0-7循环)
E(7); P0 = 0xff; // 关闭段选(防鬼影)
E(6); P0 = 0x01<<i; // 位选:选中第i位数码管
E(7); P0 = seg[buff[i]];// 段选:输出缓冲区对应的段码
i = (i+1) % 8; // 循环切换至下一位
}
关键操作流程
-
关闭段选:通过
P0=0xff
熄灭当前显示,避免切换位选时产生残影。 -
位选信号:
0x01<<i
生成位选码(如i=0时选中第1位)。 -
段码输出:从
buff[]
读取索引,查表seg[]
获取实际段码。 -
循环刷新:8位数码管依次刷新,利用视觉暂留实现“同时显示”。
显示设置函数 D(char loc, num, point)
void D(char loc, num, point){
buff[loc] = num + (point ? 16 : 0); // 设置指定位置的数字及小数点
}
参数说明
-
loc:数码管位置(0-7对应第1-8位)。
-
num:显示的数字(0-15对应seg[0-15]或seg[16-31])。
-
point:小数点控制(非0时启用,通过+16跳转至带小数点段码区)。
示例
-
D(2, 5, 1)
:在第3位显示“5.”,实际访问seg[5+16=21]
。
硬件控制细节
-
E(n):宏函数,控制锁存器使能(通常对应开发板的74HC573芯片)。
-
E(6)
:位选锁存器,控制数码管位置。 -
E(7)
:段选锁存器,控制显示内容。
-
-
P0端口:用于数据传输,先送位选码再送段选码。
注意事项
-
seg索引越界:
num
需在0-15范围内,否则访问非法段码。 -
小数点逻辑:段码最高位控制小数点(共阴极时,
0x7F
操作可能为点亮)。 -
初始状态:
buff[]
初始值为36,对应seg[36]=0xff
(全灭),需通过D()
设置显示内容。