#include
#include "DS1302.H"
sbit K_S = P1^0; //显示模式sbit K_M = P1^1; //修改sbit K_I = P1^2; //加sbit K_D = P1^3; //减
sbit Spk = P1^7; //蜂鸣器
//共阳码表unsigned char code TABLE[]={
0xC0,/*0*/
0xF9,/*1*/
0xA4,/*2*/
0xB0,/*3*/
0x99,/*4*/
0x92,/*5*/
0x82,/*6*/
0xF8,/*7*/
0x80,/*8*/
0x90,/*9*/
0xBF,/*-*/
};
unsigned char SEG[6]; //6位数码管对应缓冲区unsigned char state = 0; //显示模式位unsigned char modify = 0; //修改模式位
#define MC_H 25 //修改状态下闪烁频率,越大闪烁越慢unsigned char mc = 0; //闪烁计时
//延时函数,每单位1msvoid Delay(unsigned int t)
{
unsigned int a,b;
for (a=0; a
for (b=0; b<122; b++)
;
}
//6位数码管显示函数void Display(void)
{
unsigned char i;
SYSTEMTIME T;
DS1302_GetTime_ALL(&T); //读时间数据
if (modify == 0 && T.Minute == 0 && T.Second < 2)
{ //整点报时,修改模式下不报,只响2秒 Spk = 0;
} else {
Spk = 1;
}
if (state == 0) //显示时分秒 {
SEG[0] = TABLE[T.Hour / 10]; //时十位 SEG[1] = TABLE[T.Hour % 10] & 0x7F; //时个位,小数点点亮做分隔 SEG[2] = TABLE[T.Minute / 10]; //分十位 SEG[3] = TABLE[T.Minute % 10] & 0x7F; //分个位,小数点点亮做分隔 SEG[4] = TABLE[T.Second / 10]; //秒十位 SEG[5] = TABLE[T.Second % 10] & 0x7F; //秒个位,小数点点亮做分隔 } else if (state == 1) //显示年份 {
SEG[0] = 0xFF; //不显示 SEG[1] = TABLE[T.tYear / 10]; //年千位 SEG[2] = TABLE[T.tYear % 10]; //年百位 SEG[3] = TABLE[T.Year / 10]; //年十位 SEG[4] = TABLE[T.Year % 10]; //年个位 SEG[5] = 0xFF; //不显示 } else if (state == 2) //显示月日星期 {
SEG[0] = TABLE[T.Month / 10]; //月十位 SEG[1] = TABLE[T.Month % 10] & 0x7F; //月个位,小数点点亮做分隔 SEG[2] = TABLE[T.Day / 10]; //日十位 SEG[3] = TABLE[T.Day % 10]; //日个位 SEG[4] = TABLE[10]; //符号‘-’做分隔 SEG[5] = TABLE[T.Week - 1]; //星期 }
if (modify && (mc > MC_H)) { //修改状态下,对应位闪烁, switch (modify) //通过查询当前修改状态确定闪烁位。 {
case 1: //时闪烁 SEG[0] = SEG[1] = 0xFF; //对于共阳管,段码写0xFF即关闭不显示,得到闪烁效果 break;
case 2: //分闪烁 SEG[2] = SEG[3] = 0xFF;
break;
case 3: //秒闪烁 SEG[4] = SEG[5] = 0xFF;
break;
case 4: //年高两位闪烁 SEG[1] = SEG[2] = 0xFF;
break;
case 5: //年低两位闪烁 SEG[3] = SEG[4] = 0xFF;
break;
case 7: //月闪烁 SEG[0] = SEG[1] = 0xFF;
break;
case 8: //日闪烁 SEG[2] = SEG[3] = 0xFF;
break;
case 9: //星期闪烁 SEG[5] = 0xFF;
break;
}
}
for (i=0; i<6; i++) //数码管动态扫描 {
P0 = SEG[ i ]; //送段码 P2 = ~(0x20 >> i); //送位码 Delay(1);
P2 = 0xFF; //消影 }
if (++mc > 2 * MC_H)
mc = 0;
}
//按键处理函数void Key(void)
{
unsigned char t;
P1 |= 0x0F;
if (!K_S) //按键按下 {
Delay(10); //延时消抖 if (!K_S) //按键确实按下 {
if (!modify) //非修改模式下用于切换显示模式 {
if (++state > 2)
state = 0;
}
if (modify) //如果在修改模式下, {
modify = 0; //就退出修改模式, DS1302_WriteData(0x8e,0x80); //并打开写保护 }
}
while (!K_S) //等待按键释放 Display();
}
if (!K_M)
{
Delay(10);
if (!K_M)
{
if (modify == 0) //进入修改模式, {
modify = 3 * state + 1; //根据显示模式确定modify初值,时分秒123,年45,月日星期789 DS1302_WriteData(0x8e,0x00); //关闭写保护 } else {
modify++;
switch (state) //根据显示模式确定modify初值 {
case 0:
case 2:
if (modify > (3 * state + 3)) //时分秒,日星期模式下每个是3位 {
modify = 0;
DS1302_WriteData(0x8e,0x80);//打开写保护 }
break;
case 1:
if (modify > (3 * state + 2)) //年模式下是2位 {
modify = 0;
DS1302_WriteData(0x8e,0x80);//打开写保护 }
break;
}
}
}
while (!K_M)
Display();
}
if (!K_I)
{
Delay(10);
if (!K_I)
{
switch (modify) //根据当前修改状态确定修改什么值 {
case 0:
break;
case 1: //小时 t = BCD2DEC(DS1302_ReadData(DS1302_HOUR + 1));
if (++t > 23) //不能超过23 t = 0;
DS1302_WriteData(DS1302_HOUR, DEC2BCD(t));
break;
case 2: //分 t = BCD2DEC(DS1302_ReadData(DS1302_MINUTE + 1));
if (++t > 59) //不能超过59 t = 0;
DS1302_WriteData(DS1302_MINUTE, DEC2BCD(t));
break;
case 3: //秒 t = BCD2DEC(DS1302_ReadData(DS1302_SECOND + 1));
if (++t > 59)
t = 0;
DS1302_WriteData(DS1302_SECOND, DEC2BCD(t));
break;
case 4: //年高两位 t = BCD2DEC(DS1302_ReadData(DS1302_TYEAR + 1));
if (++t > 29) //不能超过29,最小19 t = 19;
DS1302_WriteData(DS1302_TYEAR, DEC2BCD(t));
break;
case 5: //年低两位 t = BCD2DEC(DS1302_ReadData(DS1302_YEAR + 1));
if (++t > 99) //不能超过99 t = 0;
DS1302_WriteData(DS1302_YEAR, DEC2BCD(t));
break;
case 7: //不能超过12 t = BCD2DEC(DS1302_ReadData(DS1302_MONTH + 1));
if (++t > 12)
t = 1;
DS1302_WriteData(DS1302_MONTH, DEC2BCD(t));
break;
case 8: //日 t = BCD2DEC(DS1302_ReadData(DS1302_DAY + 1));
if (++t > DS1302_GetTheDay()) //最大日期不能超过当月最大值 t = 1;
DS1302_WriteData(DS1302_DAY, DEC2BCD(t));
break;
case 9: //星期 t = BCD2DEC(DS1302_ReadData(DS1302_WEEK + 1));
if (++t > 7) //不能超过7 t = 1;
DS1302_WriteData(DS1302_WEEK, DEC2BCD(t));
break;
}
}
while (!K_I)
Display();
}
if (!K_D) //减 {
Delay(10);
if (!K_D)
{
switch (modify)
{
case 0:
break;
case 1: //小时 t = BCD2DEC(DS1302_ReadData(DS1302_HOUR + 1));
if (t > 0)
t--;
else
t = 23;
DS1302_WriteData(DS1302_HOUR, DEC2BCD(t));
break;
case 2: //分 t = BCD2DEC(DS1302_ReadData(DS1302_MINUTE + 1));
if (t > 0)
t--;
else
t = 59;
DS1302_WriteData(DS1302_MINUTE, DEC2BCD(t));
break;
case 3: //秒 t = BCD2DEC(DS1302_ReadData(DS1302_SECOND + 1));
if (t > 0)
t--;
else
t = 59;
DS1302_WriteData(DS1302_SECOND, DEC2BCD(t));
break;
case 4: //年高两位 t = BCD2DEC(DS1302_ReadData(DS1302_TYEAR + 1));
if (t > 19)
t--;
else
t = 29;
DS1302_WriteData(DS1302_TYEAR, DEC2BCD(t));
break;
case 5: //年低两位 t = BCD2DEC(DS1302_ReadData(DS1302_YEAR + 1));
if (t > 0)
t--;
else
t = 99;
DS1302_WriteData(DS1302_YEAR, DEC2BCD(t));
break;
case 7: //月 t = BCD2DEC(DS1302_ReadData(DS1302_MONTH + 1));
if (t > 1)
t--;
else
t = 12;
DS1302_WriteData(DS1302_MONTH, DEC2BCD(t));
break;
case 8: //日 t = BCD2DEC(DS1302_ReadData(DS1302_DAY + 1));
if (t > 1)
t--;
else
t = DS1302_GetTheDay();
DS1302_WriteData(DS1302_DAY, DEC2BCD(t));
break;
case 9: //星期 t = BCD2DEC(DS1302_ReadData(DS1302_WEEK + 1));
if (t > 1)
t--;
else
t = 7;
DS1302_WriteData(DS1302_WEEK, DEC2BCD(t));
break;
}
}
while (!K_D)
Display();
}
}
//主函数void main(void)
{
Spk = 1; //关蜂鸣器
DS1302_Init(); //1302初始化
while (1) //主循环 {
Display(); //显示 Key(); //按键处理
}
}