8x8 LED点阵屏仿真电梯数字滚动显示优化代码
8x8 LED点阵屏仿真电梯数字滚动显示优化代码
以下是对原代码的优化建议,并提供改进后的代码。
原代码:
//8*8led点阵屏仿真电梯数字滚动显示
//processing作为上位机模拟楼层
//点击processing上相对应的楼层,点阵屏上的数字产生相应的滚动
//接收程序
#include <reg51.h>//包含头文件reg51.h
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar code Table[]= //0~9的取模
{
0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,//0
0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,//1
0x00,0x7E,0x02,0x02,0x7E,0x40,0x40,0x7E,//2
0x00,0x7E,0x02,0x02,0x7E,0x02,0x02,0x7E,//3
0x00,0x48,0x48,0x48,0x7E,0x08,0x08,0x08,//4
0x00,0x7E,0x40,0x40,0x7E,0x02,0x02,0x7E,//5
0x00,0x7C,0x40,0x40,0x7C,0x44,0x44,0x7C,//6
0x00,0x7C,0x04,0x04,0x04,0x04,0x04,0x04,//7
0x00,0x7C,0x44,0x44,0x7C,0x44,0x44,0x7C,//8
0x00,0x7E,0x42,0x42,0x7E,0x02,0x02,0x7E,//9
};
uint r= 0;
char offset = 0;
uchar Current_Level = 1,Dest_Level=1,x=0,t =0;
void main()
{
unsigned char val=0;
Current_Level = 1;//从1开始显示
TMOD=0x20; //TMOD=0010 0000B,定时器1工作方式为方式2
SCON=0x50;
PCON=0x00;//PCON中的SMOD=0
TH1=0xFD;
TL1=0xFD;//波特率为9600b/s
TR1=1;//启动T1,波特率发生器工作
while(1)
{
while(RI==0);//查询是否接受到单片机甲的数据
RI=0;//接受完毕一个字符,清零接受中断标志位
//接受缓冲器的字符,即单片机甲的开关状态
val=SBUF;
P1=val;
if (val==0x09)Dest_Level =Table[9];//目的的操作数为~
if (val==0x08)Dest_Level =Table[8];
if (val==0x07)Dest_Level =Table[7];
if (val==0x06)Dest_Level =Table[6];
if (val==0x05)Dest_Level =Table[5];
if (val==0x04)Dest_Level =Table[4];
if (val==0x03)Dest_Level =Table[3];
if (val==0x02)Dest_Level =Table[2];
if (val==0x01)Dest_Level =Table[1];
}
}
void Led_Dispaly()
{
uchar i;
i = Current_Level *8 + r + offset;
P0 = ~Table[i];
//上升显示
if (Current_Level < Dest_Level )
{
if ( ++r ==8)
{//每个数字有八字节
r =0;
if( ++x ==4)
{//每完成x次刷新后后偏
x = 0;
if(++offset ==8)
{
offset = 0;
Current_Level++;
}
}
}
}
//下降显示
else if(Current_Level > Dest_Level )
{
if ( ++r ==8)
{//每个数字有八个字节
r =0;
if( ++x ==4)
{//完成x次刷新后前偏
x = 0;
if(--offset == -8)
{
offset = 0;
Current_Level--;
}
}
}
}
//停止滚动,保持稳定的刷新显示
else
{
if ( ++r ==8) r =0;
}
}
改进建议:
- 加入延时函数
在Led_Display函数中,没有加入任何延时,导致每个数字的滚动速度过快,给人的感觉不够自然。可以使用延时函数或者定时器来控制每个数字的滚动速度,使得滚动更加自然。
- 优化接收程序
当前的接收程序使用了大量的if语句来判断接收到的数据,并进行相应的操作,这样的代码可读性不高,也不够简洁。可以使用switch语句来替换if语句,或者使用数组来存储对应的操作数。
- 函数命名规范化
Led_Dispaly函数的命名不符合命名规范,应该改为Led_Display。
- 常量使用const修饰
Table数组是一个常量数组,它的值在编译时就已经确定了,应该使用const关键字来修饰。
- 变量命名规范化
变量的命名应该具有一定的描述性,比如x变量可以改为refreshCount,r变量可以改为byteIndex。
改进后的代码:
// 8x8 LED点阵屏仿真电梯数字滚动显示
// processing作为上位机模拟楼层
// 点击processing上相对应的楼层,点阵屏上的数字产生相应的滚动
// 接收程序
#include <reg51.h> //包含头文件reg51.h
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
const uchar code Table[] = // 0~9的取模
{
0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, // 0
0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, // 1
0x00, 0x7E, 0x02, 0x02, 0x7E, 0x40, 0x40, 0x7E, // 2
0x00, 0x7E, 0x02, 0x02, 0x7E, 0x02, 0x02, 0x7E, // 3
0x00, 0x48, 0x48, 0x48, 0x7E, 0x08, 0x08, 0x08, // 4
0x00, 0x7E, 0x40, 0x40, 0x7E, 0x02, 0x02, 0x7E, // 5
0x00, 0x7C, 0x40, 0x40, 0x7C, 0x44, 0x44, 0x7C, // 6
0x00, 0x7C, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, // 7
0x00, 0x7C, 0x44, 0x44, 0x7C, 0x44, 0x44, 0x7C, // 8
0x00, 0x7E, 0x42, 0x42, 0x7E, 0x02, 0x02, 0x7E, // 9
};
uint byteIndex = 0;
char offset = 0;
uchar currentLevel = 1, destLevel = 1, refreshCount = 0, t = 0;
void delay(unsigned int ms)
{
unsigned int i, j;
for (i = 0; i < ms; i++)
{
for (j = 0; j < 120; j++);
}
}
void main()
{
unsigned char val = 0;
currentLevel = 1; // 从1开始显示
TMOD = 0x20; // TMOD=0010 0000B, 定时器1工作方式为方式2
SCON = 0x50;
PCON = 0x00; // PCON中的SMOD=0
TH1 = 0xFD;
TL1 = 0xFD; // 波特率为9600b/s
TR1 = 1; // 启动T1, 波特率发生器工作
while (1)
{
while (RI == 0); // 查询是否接受到单片机甲的数据
RI = 0; // 接受完毕一个字符,清零接受中断标志位
// 接受缓冲器的字符,即单片机甲的开关状态
val = SBUF;
P1 = val;
switch (val)
{
case 0x09: destLevel = Table[9]; break; // 目的的操作数为~
case 0x08: destLevel = Table[8]; break;
case 0x07: destLevel = Table[7]; break;
case 0x06: destLevel = Table[6]; break;
case 0x05: destLevel = Table[5]; break;
case 0x04: destLevel = Table[4]; break;
case 0x03: destLevel = Table[3]; break;
case 0x02: destLevel = Table[2]; break;
case 0x01: destLevel = Table[1]; break;
}
}
}
void Led_Display()
{
uchar i = currentLevel * 8 + byteIndex + offset;
P0 = ~Table[i];
// 上升显示
if (currentLevel < destLevel)
{
if (++byteIndex == 8)
{
// 每个数字有八个字节
byteIndex = 0;
if (++refreshCount == 4)
{
// 每完成x次刷新后后偏
refreshCount = 0;
if (++offset == 8)
{
offset = 0;
currentLevel++;
}
}
}
}
// 下降显示
else if (currentLevel > destLevel)
{
if (++byteIndex == 8)
{
// 每个数字有八个字节
byteIndex = 0;
if (++refreshCount == 4)
{
// 完成x次刷新后前偏
refreshCount = 0;
if (--offset == -8)
{
offset = 0;
currentLevel--;
}
}
}
}
// 停止滚动,保持稳定的刷新显示
else
{
if (++byteIndex == 8) byteIndex = 0;
}
delay(50); // 加入延时
}
说明:
- 使用了
switch语句来替代多个if语句,提高代码的可读性和简洁性。 - 使用了
const关键字来修饰常量数组Table。 - 使用了更具描述性的变量名,例如
byteIndex、refreshCount等。 - 在
Led_Display函数中加入了delay函数,控制数字滚动速度,使滚动更加自然。
注意:
- 以上代码仅供参考,需要根据实际情况进行修改。
- 延时函数的延时时间可以根据需要进行调整。
- 可以使用定时器来实现更精确的延时。
- 代码中使用的串口通信方式可能需要根据实际情况进行调整。
原文地址: https://www.cveoy.top/t/topic/nJQX 著作权归作者所有。请勿转载和采集!