0
点赞
收藏
分享

微信扫一扫

STC89C52RC第三练

STC89C52RC单片机

STC89C52RC第三练_数码管


练习目标

5个数码管,以1秒为频率,按照MM-DD的格式显示2023年01月01日至12月31日每个日期,往复循环。

个人认为主要困难点:

每个日期显示频率是1秒,如果按照1秒刷新5个数码管,则只有最后一个亮。因此数码管的刷新频率与日期递增频率必须是两个不同值。

代码如下:

#include <REGX52.H>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char

void Delay(uint);
void ShowAllDay();
void ShowLcd(uint,uint);
uint monthG,monthS,dayG,dayS;
//第几个数码管亮时,P0取值分别是
uint code lcdIndexAll[6] = {0XFE,0XFD,0XFB,0XF7,0XEF,0XDF};
//数码管显示0-9时,P0取值分别是
uint code lcdValueAll[10] = {0x3F,0x06,0x5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F};

void main()
{
	uint monthVal,dayVal,frequency;
	monthVal = 1;
	dayVal = 1;
	frequency = 1000;			//用来控制monthVal 和 dayVal 更新的频率
	while(1)
	{
		//日期 和 月份 4个数码管赋值过程
		if(frequency == 1000)
		{
			if(monthVal > 12)
				monthVal = 1;

			if(monthVal > 9)
			{
				monthS = lcdValueAll[1];
				monthG = lcdValueAll[monthVal - 10];
			}
			else
			{
				monthS = lcdValueAll[0];	//数码管显示0
				monthG = lcdValueAll[monthVal];
			}

			switch(monthVal)
			{
				case 1:
				case 3:
				case 5:
				case 7:
				case 8:
				case 10:
				case 12:
					//31天
					if(dayVal > 31)
						dayVal = 1;
					
					if(dayVal > 29)
					{
						dayS = lcdValueAll[3];
						dayG = lcdValueAll[dayVal - 30];
					}
					else if(dayVal > 19)
					{
						dayS = lcdValueAll[2];
						dayG = lcdValueAll[dayVal - 20];
					}
					else if(dayVal > 9)
					{
						dayS = lcdValueAll[1];
						dayG = lcdValueAll[dayVal - 10];
					}
					else
					{
						dayS = lcdValueAll[0];
						dayG = lcdValueAll[dayVal];
					}
					break;
				case 4:
				case 6:
				case 9:
				case 11:
					//30天
					if(dayVal > 30)
						dayVal = 1;
					
					if(dayVal > 29)
					{
						dayS = lcdValueAll[3];
						dayG = lcdValueAll[dayVal - 30];
					}
					else if(dayVal > 19)
					{
						dayS = lcdValueAll[2];
						dayG = lcdValueAll[dayVal - 20];
					}
					else if(dayVal > 9)
					{
						dayS = lcdValueAll[1];
						dayG = lcdValueAll[dayVal - 10];
					}
					else
					{
						dayS = lcdValueAll[0];
						dayG = lcdValueAll[dayVal];
					}
					break;
				default:
					//2月份  2023年28天
					if(dayVal > 28)
						dayVal = 1;

					if(dayVal > 19)
					{
						dayS = lcdValueAll[2];
						dayG = lcdValueAll[dayVal - 20];
					}
					else if(dayVal > 9)
					{
						dayS = lcdValueAll[1];
						dayG = lcdValueAll[dayVal - 10];
					}
					else
					{
						dayS = lcdValueAll[0];
						dayG = lcdValueAll[dayVal];
					}
			}
		}

		ShowAllDay();									//数码管显示函数
		
		frequency = frequency - 5;		//ShowAllDay函数调用了5次ShowLcd,每执行1次延时1毫秒
		if(frequency == 0)
			frequency = 1000;
		
		//日期和月份递增处理过程
		if(frequency == 1000)
		{
			dayVal++;
			if(dayVal == 29)						//因为先执行的dayVal++ 因此if中dayVal比临界值28、30、31大1
			{
				if(monthVal == 2)
				{
					monthVal++;
					dayVal = 1;
				}
			}
			else if(dayVal == 31)
			{
				switch(monthVal)
				{
					case 4:
					case 6:
					case 9:
					case 11:
						monthVal++;
						dayVal = 1;						//每次月份变更后,日期必须从1开始;否则会出现月份连续变化的情况
						break;
				}
			}
			else if(dayVal == 32)
			{
				switch(monthVal)
				{
					case 1:
					case 3:
					case 5:
					case 7:
					case 8:
					case 10:
					case 12:
						monthVal++;
						dayVal = 1;
						break;
				}
			}
		}
		
	}
}

void ShowAllDay()
{
	ShowLcd(lcdIndexAll[0],monthS);										
	ShowLcd(lcdIndexAll[1],monthG);
	ShowLcd(lcdIndexAll[2],0x40);		//月份-日期 分割符
	ShowLcd(lcdIndexAll[3],dayS);
	ShowLcd(lcdIndexAll[4],dayG);
}

void ShowLcd(uint lcdLocal ,uint lcdContent)
{
	P2_7 = 1;
	P0 = lcdLocal;
	P2_7 = 0;
	P0 = 0xFF;
	P2_6 = 1;
	P0 = lcdContent;
	P2_6 = 0;
	Delay(1);				//很重要,不能省略
}

void Delay(uint dTime)
{
	uchar data i, j;
	while(dTime--)
	{
		_nop_();
		i = 2;
		j = 199;
		do
		{
			while (--j);
		} while (--i);
	}
}

代码很屎,看到的大佬请见谅🤭

如那位大佬又兴趣欢迎给出优化建议o(* ̄▽ ̄*)ブ

下一步优化代码++++++++++++++++++++++++++++++++++++++++++




举报

相关推荐

0 条评论