蓝桥杯单片机 (简洁高效数码管)

 作者声明 :我将代码详细的解释到此处,全部代码经过板测,希望对你有帮助

 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;          // 循环切换至下一位
}
关键操作流程
  1. 关闭段选:通过P0=0xff熄灭当前显示,避免切换位选时产生残影。

  2. 位选信号0x01<<i生成位选码(如i=0时选中第1位)。

  3. 段码输出:从buff[]读取索引,查表seg[]获取实际段码。

  4. 循环刷新: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端口:用于数据传输,先送位选码再送段选码。


注意事项

  1. seg索引越界num需在0-15范围内,否则访问非法段码。

  2. 小数点逻辑:段码最高位控制小数点(共阴极时,0x7F操作可能为点亮)。

  3. 初始状态buff[]初始值为36,对应seg[36]=0xff(全灭),需通过D()设置显示内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值