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(* ̄▽ ̄*)ブ
下一步优化代码++++++++++++++++++++++++++++++++++++++++++