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;		
	}
}

改进建议:

  1. 加入延时函数

在Led_Display函数中,没有加入任何延时,导致每个数字的滚动速度过快,给人的感觉不够自然。可以使用延时函数或者定时器来控制每个数字的滚动速度,使得滚动更加自然。

  1. 优化接收程序

当前的接收程序使用了大量的if语句来判断接收到的数据,并进行相应的操作,这样的代码可读性不高,也不够简洁。可以使用switch语句来替换if语句,或者使用数组来存储对应的操作数。

  1. 函数命名规范化

Led_Dispaly函数的命名不符合命名规范,应该改为Led_Display。

  1. 常量使用const修饰

Table数组是一个常量数组,它的值在编译时就已经确定了,应该使用const关键字来修饰。

  1. 变量命名规范化

变量的命名应该具有一定的描述性,比如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
  • 使用了更具描述性的变量名,例如byteIndexrefreshCount等。
  • Led_Display函数中加入了delay函数,控制数字滚动速度,使滚动更加自然。

注意:

  • 以上代码仅供参考,需要根据实际情况进行修改。
  • 延时函数的延时时间可以根据需要进行调整。
  • 可以使用定时器来实现更精确的延时。
  • 代码中使用的串口通信方式可能需要根据实际情况进行调整。

原文地址: https://www.cveoy.top/t/topic/nJQX 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录