公历阳历转阴历农历C51程序键盘数码管成功剖析.docx
《公历阳历转阴历农历C51程序键盘数码管成功剖析.docx》由会员分享,可在线阅读,更多相关《公历阳历转阴历农历C51程序键盘数码管成功剖析.docx(24页珍藏版)》请在冰点文库上搜索。
![公历阳历转阴历农历C51程序键盘数码管成功剖析.docx](https://file1.bingdoc.com/fileroot1/2023-5/21/bc0add66-ccb4-419a-b030-645cb0b6e545/bc0add66-ccb4-419a-b030-645cb0b6e5451.gif)
公历阳历转阴历农历C51程序键盘数码管成功剖析
/*******************************************************************************
*实验名:
动态显示数码管实验
*使用的IO:
数码管使用P0,P2.2,P2.3,P2.4
*实验效果:
数码管显示76543210。
*注意:
*******************************************************************************/
#include
#include
#defineGPIO_DIGP0//数码管显示
#defineGPIO_KEYP1//键盘
sbitLSA=P2^2;
sbitLSB=P2^3;
sbitLSC=P2^4;
sbitK3=P3^2;//外部中断
unsignedcharcodeDataTab[404]={
//日期差//上大小月//下大小月//闰月月份及大小
0x46,0x43,0x21,0x00,//1999
0x35,0x15,0x51,0x00,//2000
0x23,0x11,0x52,0x41,
0x42,0x12,0x65,0x00,
0x31,0x11,0x32,0x00,
0x21,0x42,0x52,0x21,
0x39,0x52,0x25,0x00,//2005
0x28,0x25,0x04,0x71,
0x48,0x66,0x42,0x00,
0x37,0x33,0x22,0x00,
0x25,0x15,0x24,0x51,
0x44,0x25,0x52,0x00,//2010
0x33,0x22,0x65,0x00,
0x22,0x21,0x25,0x41,
0x40,0x24,0x52,0x00,
0x30,0x52,0x42,0x91,
0x49,0x55,0x05,0x00,//2015
0x38,0x26,0x44,0x00,
0x27,0x53,0x50,0x60,
0x46,0x53,0x24,0x00,
0x35,0x25,0x54,0x00,
0x24,0x41,0x52,0x41,//2020
0x42,0x45,0x25,0x00,
0x31,0x24,0x52,0x00,
0x21,0x51,0x12,0x21,
0x40,0x55,0x11,0x00,
0x28,0x32,0x21,0x61,//2025
0x47,0x26,0x61,0x00,
0x36,0x13,0x31,0x00,
0x25,0x05,0x31,0x51,
0x43,0x12,0x54,0x00,
0x33,0x51,0x25,0x00,//2030
0x22,0x42,0x25,0x31,
0x41,0x32,0x22,0x00,
0x30,0x55,0x02,0x71,
0x49,0x55,0x22,0x00,
0x38,0x26,0x62,0x00,//2035
0x27,0x13,0x64,0x60,
0x45,0x13,0x32,0x00,
0x34,0x12,0x55,0x00,
0x23,0x10,0x53,0x51,
0x42,0x22,0x45,0x00,//2040
0x31,0x52,0x22,0x00,
0x21,0x52,0x44,0x21,
0x40,0x55,0x44,0x00,
0x29,0x26,0x50,0x71,
0x47,0x26,0x64,0x00,//2045
0x36,0x25,0x32,0x00,
0x25,0x23,0x32,0x50,
0x44,0x44,0x55,0x00,
0x32,0x24,0x45,0x00,
0x22,0x55,0x11,0x30,//2050
0x41,0x33,0x10,0x00,
0x31,0x55,0x40,0x81,
0x49,0x55,0x50,0x00,
0x38,0x46,0x64,0x00,
0x27,0x45,0x65,0x60,//2055
0x45,0x05,0x32,0x00,
0x34,0x45,0x15,0x00,
0x23,0x26,0x23,0x40,
0x42,0x25,0x21,0x00,
0x32,0x33,0x21,0x00,//2060
0x20,0x43,0x21,0x31,
0x39,0x15,0x51,0x00,
0x28,0x12,0x52,0x71,
0x47,0x12,0x65,0x00,
0x35,0x11,0x32,0x00,//2065
0x25,0x50,0x52,0x51,
0x44,0x52,0x25,0x00,
0x33,0x26,0x22,0x00,
0x22,0x52,0x42,0x41,
0x41,0x53,0x22,0x00,//2070
0x30,0x25,0x44,0x81,
0x49,0x25,0x52,0x00,
0x37,0x22,0x65,0x00,
0x26,0x22,0x25,0x61,
0x45,0x24,0x52,0x00,//2075
0x35,0x52,0x45,0x00,
0x23,0x25,0x05,0x41,
0x42,0x26,0x44,0x00,
0x32,0x53,0x24,0x00,
0x21,0x23,0x30,0x31,//2080
0x39,0x45,0x54,0x00,
0x28,0x43,0x14,0x71,
0x47,0x45,0x25,0x00,
0x36,0x24,0x52,0x00,
0x25,0x55,0x12,0x50,//2085
0x44,0x55,0x11,0x00,
0x33,0x26,0x50,0x00,
0x23,0x52,0x61,0x41,
0x40,0x13,0x31,0x00,
0x29,0x05,0x51,0x81,//2090
0x48,0x12,0x55,0x00,
0x37,0x11,0x25,0x00,
0x26,0x45,0x25,0x60,
0x45,0x52,0x22,0x00,
0x35,0x55,0x21,0x00,//2095
0x24,0x25,0x42,0x41,
0x42,0x26,0x62,0x00,
0x31,0x13,0x52,0x00,
0x20,0x03,0x32,0x21//2099
};
unsignedcharcodeDIG_CODE[17]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码
unsignedcharcodeso_m_d[12]={31,28,31,30,31,30,31,31,30,31,30,31};
//公历该月的天数
unsignedcharDisplayData[8];
//用来存放要显示的8位数的值
unsignedcharTempData[8];
unsignedcharTurnData[4];
//转换用于取出数据表的四个数据
unsignedcharKeyValue;
//用来存放读取到的键值
unsignedcharKV;
charyear_soH;
charyear_so;//公历年月日
charmonth_so;
charday_so;
intSumDar_so;//char型位数不够,出现瓶颈
charyear_lu;//农历年月日
charmonth_lu;
charday_lu;
intSumDar_lu;
intn,H;
voidDigDisplay();//动态显示函数
voidDelay10ms();//延时10ms
voidKeyDown();//检测按键函数
voidKeyShow();//检测键值并显示
voidTurn();//阳历转换阴历
//intLMP(intLP);
intmonth12_lu(intmonth_a,unsignedcharmonth_b,unsignedcharmonth_c);
/*******************************************************************************
*函数名:
main
*函数功能:
主函数
*输入:
无
*输出:
无
*******************************************************************************/
voidmain()
{
year_lu=0;//农历年月日
month_lu=0;
day_lu=0;
KeyShow();
//设置INT0
IT0=1;//跳变沿出发方式(下降沿)
EX0=1;//打开INT0的中断允许。
EA=1;//打开总中断
while
(1)
{
DigDisplay();//显示
if(KV==1)//进中断
{
Turn();//转换程序
}
}
}
/*******************************************************************************
*函数名:
KeyShow
*函数功能:
检测有按键按下并显示键值
*输入:
无
*输出:
无
*******************************************************************************/
voidKeyShow()
{
unsignedchari=0;
intj=0;
intq,u=0;
SumDar_so=0;
LSA=0;//给一个数码管提供位选
LSB=0;
LSC=0;
while(i<=7)
{
GPIO_KEY=0x0f;
if(GPIO_KEY!
=0x0f)//读取按键是否按下
{
Delay10ms();//延时10ms进行消抖
if(GPIO_KEY!
=0x0f)//再次检测键盘是否按下
{
KeyDown();//读取键值
if(KeyValue<=9)//键值有效
{
TempData[i]=KeyValue;//将按键输入的8位数存在寄存器中
DisplayData[i]=DIG_CODE[KeyValue];//将查到的值送到显示数据寄存器
i++;
DigDisplay();//显示
}
}
}
DigDisplay();//显示
}
DigDisplay();//显示
year_soH=(int)(TempData[0]);//从寄存器中读取公历年份
year_soH=year_soH*10+(int)(TempData[1]);
year_so=(int)(TempData[2]);//从寄存器中读取公历年份
year_so=year_so*10+(int)(TempData[3]);
month_so=(int)(TempData[4]);
month_so=month_so*10+(int)(TempData[5]);//读取公历月
day_so=(int)(TempData[6]);
day_so=day_so*10+(int)(TempData[7]);//读取公历月
j=month_so-1;
for(q=0;q{
u=so_m_d[q];
SumDar_so=SumDar_so+u;
}
SumDar_so=SumDar_so+day_so;
H=SumDar_so;
if(j>1)//J>1需要考虑公历闰年
{
if(year_so%4==0)
SumDar_so=SumDar_so+1;
}
}
/*******************************************************************************
*函数名:
Turn
*函数功能:
阳历转阴历
*输入:
无
*输出:
无
*******************************************************************************/
voidTurn()
{
unsignedcharTemp;
unsignedcharL_Temp;
unsignedchary;
unsignedcharsy;
unsignedcharxy;
unsignedcharL_y;
unsignedcharL_sy;
unsignedcharL_xy;
unsignedcharry;
unsignedcharZ;
unsignedcharF;
unsignedcharZ_y;
unsignedcharF_y;
unsignedcharZ_r;
unsignedcharF_r;
intj,k,m,p,T;
intl1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12,LastMonth;
p=year_soH*100+year_so;//年份20**年
Temp=(p-2000+1)*4;//公历年份*4再去查表,存入转化暂存器
y=DataTab[Temp];//上半年的数据
Temp++;
sy=DataTab[Temp];
Temp++;//下半年的数据
xy=DataTab[Temp];
Temp++;//闰月的月份和大小
ry=DataTab[Temp];
//BCD码转十进制,求出差值
n=10*(int)((y&0xf0)>>4)+(int)(y&0x0f);//天数差值
SumDar_lu=SumDar_so-n;//农历总天数
k=(int)((ry&0xf0)>>4);//闰月月份
m=30-(int)(ry&0x0f);//闰月的天数
l1=month12_lu(1,sy,xy);//农历1月多少天
l2=month12_lu(2,sy,xy);//农历1月多少天
l3=month12_lu(3,sy,xy);//农历1月多少天
l4=month12_lu(4,sy,xy);//农历1月多少天
l5=month12_lu(5,sy,xy);//农历1月多少天
l6=month12_lu(6,sy,xy);//农历1月多少天
l7=month12_lu(7,sy,xy);//农历1月多少天
l8=month12_lu(8,sy,xy);//农历1月多少天
l9=month12_lu(9,sy,xy);//农历1月多少天
l10=month12_lu(10,sy,xy);//农历1月多少天
l11=month12_lu(11,sy,xy);//农历1月多少天
l12=month12_lu(12,sy,xy);//农历1月多少天
T=SumDar_so;
if(T{
L_Temp=(p-2000)*4;//去年公历年份*4再去查表,存入转化暂存器
L_y=DataTab[L_Temp];//上半年的数据
L_Temp++;
L_sy=DataTab[L_Temp];
L_Temp++;//下半年的数据
L_xy=DataTab[L_Temp];
if((n-T)>31)
{
month_lu=11;//跨年到去年的11月
LastMonth=month12_lu(12,L_sy,L_xy);
day_lu=n-SumDar_so-LastMonth;
LastMonth=month12_lu(1,L_sy,L_xy);
day_lu=LastMonth-day_lu;
day_lu=day_lu+1;
}2
if(((n)>0)&&((n-T)<=31))
{
month_lu=12;//跨年到去年的12月
LastMonth=month12_lu(12,L_sy,L_xy);
day_lu=LastMonth-(n-T);
}
}
else//没有跨年
{
if((SumDar_lu-l1)>0)
{
if((SumDar_lu-l2-l1)>0)
{
if((SumDar_lu-l3-l2-l1)>0)
{
if((SumDar_lu-l4-l3-l2-l1)>0)
{
if((SumDar_lu-l5-l4-l3-l2-l1)>0)
{
if((SumDar_lu-l6-l5-l4-l3-l2-l1)>0)
{
if((SumDar_lu-l7-l6-l5-l4-l3-l2-l1)>0)
{
if((SumDar_lu-l8-l7-l6-l5-l4-l3-l2-l1)>0)
{
if((SumDar_lu-l9-l8-l7-l6-l5-l4-l3-l2-l1)>0)
{
if((SumDar_lu-l10-l9-l8-l7-l6-l5-l4-l3-l2-l1)>0)
{
if((SumDar_lu-l11-l10-l9-l8-l7-l6-l5-l4-l3-l2-l1)>0)
{
month_lu=12;
day_lu=SumDar_lu-l11-l10-l9-l8-l7-l6-l5-l4-l3-l2-l1;
}
else
{
month_lu=11;
day_lu=SumDar_lu-l10-l9-l8-l7-l6-l5-l4-l3-l2-l1;
}
}
else
{
month_lu=10;
day_lu=SumDar_lu-l9-l8-l7-l6-l5-l4-l3-l2-l1;
}
}
else
{
month_lu=9;
day_lu=SumDar_lu-l8-l7-l6-l5-l4-l3-l2-l1;
}
}
else
{
month_lu=8;
day_lu=SumDar_lu-l7-l6-l5-l4-l3-l2-l1;
}
}
else
{
month_lu=7;
day_lu=SumDar_lu-l6-l5-l4-l3-l2-l1;
}
}
else
{
month_lu=6;
day_lu=SumDar_lu-l5-l4-l3-l2-l1;
}
}
else
{
month_lu=5;
day_lu=SumDar_lu-