|
/*
* Desc:DS12C887 6位数码管显示
*
*/
#include <AT89X51.h>
#define SEG_DAT P0
#define SEG_BIT P2
#define DS_DAT P0
#define DS_SEC 0x00
#define DS_MIN 0x02
#define DS_HOR 0x04
#define DS_WEK 0x06
#define DS_DAY 0x07
#define DS_MON 0x08
#define DS_YER 0x09
#define DS_R_A 0x0A
#define DS_R_B 0x0B
#define DS_R_C 0x0C
#define DS_R_D 0x0D
#define DS_Y_S 0x0E //年千百位
#define CNT_M 30 //控制闪烁速度,为偶数
#define BCD_DEC(X) (((X & 0xF0) >> 4) * 10 + (X & 0x0F))
#define DEC_BCD(X) (((X / 10) << 4) | (X % 10))
sbit DS_DS = P3^0;
sbit DS_RW = P3^1;
sbit DS_AS = P3^2;
sbit DS_CS = P3^3;
sbit KEY1 = P1^0;
sbit KEY2 = P1^1;
sbit KEY3 = P1^2;
sbit KEY4 = P1^3;
unsigned char dispMode = 0; //显示模式
unsigned char modify = 0; //修改模式
unsigned char count = 0; //修改模式下闪烁计数
unsigned char DIS[6];
unsigned char code C_DAT[]={
0xC0,/*0*/
0xF9,/*1*/
0xA4,/*2*/
0xB0,/*3*/
0x99,/*4*/
0x92,/*5*/
0x82,/*6*/
0xF8,/*7*/
0x80,/*8*/
0x90,/*9*/
0xBF,/*-*/
};
unsigned char code C_BIT[]={0xDF,0xEF,0xF7,0xFB,0xFD,0xFE};
void Delay(unsigned int t)
{
unsigned int a,b;
for (a=0; a<t; a++)
for (b=0; b<123; b++)
;
}
void DS12887_Write(unsigned char addres,unsigned char dat)
{
DS_AS = 1;
DS_DS = 1;
DS_RW = 1;
DS_CS = 0;
DS_DAT = addres;
DS_AS = 0; //add will be write when AS full down
DS_RW = 0;
DS_DAT = dat;
DS_RW = 1;
DS_AS = 1;
DS_CS = 1;
}
unsigned char DS12887_Read(unsigned char addres)
{
unsigned char d;
DS_AS = 1;
DS_DS = 1;
DS_RW = 1;
DS_CS = 0;
DS_DAT = addres;
DS_AS = 0;
DS_DS = 0;
DS_DAT = 0xFF;
d = DS_DAT;
DS_DS = 1;
DS_AS = 1;
DS_CS = 1;
return d;
}
void DS12887_Init(void)
{
if (DS12887_Read(DS_Y_S) == 0)
{
DS12887_Write(DS_Y_S, 0x20);
DS12887_Write(DS_HOR, 0x12);
DS12887_Write(DS_R_A, 0x20);
DS12887_Write(DS_R_B, 0x02); //BCD
}
}
void Display(void)
{
unsigned char i;
if (dispMode == 0) //显示模式0,时分秒
{
i = DS12887_Read(DS_HOR) & 0x7F;
DIS[0] = C_DAT[i >> 4];
DIS[1] = C_DAT[i & 0x0F] & 0x7F;
i = DS12887_Read(DS_MIN);
DIS[2] = C_DAT[i >> 4];
DIS[3] = C_DAT[i & 0x0F] & 0x7F;
i = DS12887_Read(DS_SEC);
DIS[4] = C_DAT[i >> 4];
DIS[5] = C_DAT[i & 0x0F] & 0x7F;
if (modify != 0 && count > CNT_M) //修改模式123下闪烁
{
DIS[2 * (modify - 1)] = 0xFF;
DIS[2 * (modify - 1) + 1] = 0xFF;
}
} else if (dispMode == 1) //显示模式1,年
{
DIS[0] = 0xFF;
i = DS12887_Read(DS_Y_S); //年高两位,在RAM里0x0E
DIS[1] = C_DAT[i >> 4];
DIS[2] = C_DAT[i & 0x0F];
i = DS12887_Read(DS_YER); //年低两位
DIS[3] = C_DAT[i >> 4];
DIS[4] = C_DAT[i & 0x0F];
DIS[5] = 0xFF;
if (modify != 0 && count > CNT_M) //修改模式45下闪烁
{
DIS[2 * (modify - 4) + 1] = 0xFF;
DIS[2 * (modify - 4) + 2] = 0xFF;
}
} else if (dispMode == 2) //显示模式2,月日 星期
{
i = DS12887_Read(DS_MON); //月
if (i < 10)
DIS[0] = 0xFF;
else
DIS[0] = C_DAT[i >> 4];
DIS[1] = C_DAT[i & 0x0F] & 0x7F; //显示小数点
i = DS12887_Read(DS_DAY); //日
DIS[2] = C_DAT[i >> 4];
DIS[3] = C_DAT[i & 0x0F];
i = DS12887_Read(DS_WEK); //星期
DIS[4] = C_DAT[10]; //用'-'隔开
DIS[5] = C_DAT[(i - 1) & 0x0F]; //1~7,第一天是星期天
if (modify != 0 && count > CNT_M) //修改模式789下闪烁
{
if (modify != 9) //星期修改时,‘-’不闪烁
DIS[2 * (modify - 7)] = 0xFF;
DIS[2 * (modify - 7) + 1] = 0xFF;
}
}
for (i=0; i<6; i++)
{
SEG_DAT = DIS[ i];
SEG_BIT = C_BIT[ i];
Delay(1);
SEG_BIT = 0xFF;
}
count++; //用于修改模式下闪烁
if (count > 2 * CNT_M)
count = 0;
}
/*计算当月的天数*/
unsigned char getDay(void)
{
unsigned char tYear,tMonth;
tYear = BCD_DEC(DS12887_Read(DS_YER)); //当前年
tMonth = BCD_DEC(DS12887_Read(DS_MON));//当前月
switch (tMonth)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:return 31; //1、3、5、7、8、10、12 月均为31天
case 4:
case 6:
case 9:
case 11:return 30; //4、6、9、11 月均为30天
case 2:
if (tYear%4==0) //2月闰年为29天
return 29;
else
return 28; //平年为28天
default: return 0;
}
}
void Key(void)
{
unsigned char i;
P1 = 0xFF;
if (KEY1 == 0) //显示模式更改
{
Delay(10);
if (KEY1 == 0)
{
if (modify) //修改模式下用于退出修改
modify = 0;
else {
DS12887_Write(DS_R_B, 0x62);
dispMode++;
if (dispMode > 2)
dispMode = 0;
}
}
while (KEY1 == 0)
Display();
}
if (KEY2 == 0) //修改模式
{
Delay(10);
if (KEY2 == 0)
{
if (modify == 0) //时分秒123,年45,月日星期789
{
modify = 3 * dispMode + 1;
DS12887_Write(DS_R_B, 0xE2);
} else {
modify++;
switch (dispMode) //根据显示模式确定modify初值
{
case 0:
case 2:
if (modify > (3 * dispMode + 3))
//时分秒,日星期模式下每个是3位
{
modify = 0;
DS12887_Write(DS_R_B, 0x62);
}
break;
case 1:
if (modify > (3 * dispMode + 2)) //年模式下是2位
{
modify = 0;
DS12887_Write(DS_R_B, 0x62);
}
break;
}
}
}
while (KEY2 == 0)
Display();
}
if (KEY3 == 0) //+
{
Delay(10);
if (KEY3 == 0)
{
switch (modify)
{
case 1: //时
i = BCD_DEC(DS12887_Read(DS_HOR));
i++;
if (i > 23)
i = 0;
DS12887_Write(DS_HOR, DEC_BCD(i));
break;
case 2: //分
i = BCD_DEC(DS12887_Read(DS_MIN));
i++;
if (i > 59)
i = 0;
DS12887_Write(DS_MIN, DEC_BCD(i));
break;
case 3: //秒
i = BCD_DEC(DS12887_Read(DS_SEC));
i++;
if (i > 59)
i = 0;
DS12887_Write(DS_SEC, DEC_BCD(i));
break;
case 4: //年高两位
i = BCD_DEC(DS12887_Read(DS_Y_S));
i++;
if (i > 21)
i = 19;
DS12887_Write(DS_Y_S, DEC_BCD(i));
break;
case 5: //年低两位
i = BCD_DEC(DS12887_Read(DS_YER));
i++;
if (i > 99)
i = 0;
DS12887_Write(DS_YER, DEC_BCD(i));
break;
case 7: //月
i = BCD_DEC(DS12887_Read(DS_MON));
i++;
if (i > 12)
i = 1;
DS12887_Write(DS_MON, DEC_BCD(i));
break;
case 8: //日
i = BCD_DEC(DS12887_Read(DS_DAY));
i++;
if (i > getDay())
i = 1;
DS12887_Write(DS_DAY, DEC_BCD(i));
break;
case 9: //星期
i = BCD_DEC(DS12887_Read(DS_WEK));
i++;
if (i > 7)
i = 1;
DS12887_Write(DS_WEK, DEC_BCD(i));
break;
}
}
while (KEY3 == 0)
Display();
}
if (KEY4 == 0)
{
Delay(10);
if (KEY4 == 0)
{
switch (modify)
{
case 1: //时
i = BCD_DEC(DS12887_Read(DS_HOR));
if (i == 0)
i = 24;
i--;
DS12887_Write(DS_HOR, DEC_BCD(i));
break;
case 2: //分
i = BCD_DEC(DS12887_Read(DS_MIN));
if (i == 0)
i = 60;
i--;
DS12887_Write(DS_MIN, DEC_BCD(i));
break;
case 3: //秒
i = BCD_DEC(DS12887_Read(DS_SEC));
if (i == 0)
i = 60;
i--;
DS12887_Write(DS_SEC, DEC_BCD(i));
break;
case 4: //年高两位
i = BCD_DEC(DS12887_Read(DS_Y_S));
if (i == 19)
i = 22;
i--;
DS12887_Write(DS_Y_S, DEC_BCD(i));
break;
case 5: //年低两位
i = BCD_DEC(DS12887_Read(DS_YER));
if (i == 0)
i = 99;
else
i--;
DS12887_Write(DS_YER, DEC_BCD(i));
break;
case 7: //月
i = BCD_DEC(DS12887_Read(DS_MON));
if (i == 1)
i = 12;
else
i--;
DS12887_Write(DS_MON, DEC_BCD(i));
break;
case 8: //日
i = BCD_DEC(DS12887_Read(DS_DAY));
if (i == 1)
i = getDay();
else
i--;
DS12887_Write(DS_DAY, DEC_BCD(i));
break;
case 9: //星期
i = BCD_DEC(DS12887_Read(DS_WEK));
if (i == 1)
i = 7;
else
i--;
DS12887_Write(DS_WEK, DEC_BCD(i));
break;
}
}
while (KEY4 == 0)
Display();
}
}
void main (void)
{
unsigned char i;
DS12887_Init();
while (1)
{
Key();
Display();
}
}
|
评分
-
查看全部评分
|