📄 main.c
字号:
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
// 项目名称:数字时钟
// 作者:吕慧,陈莹莹
// 修改日期:07-9-25
// 版本:0.0
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
#include "I2C.h"
#include "ZLG7290.h"
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
sbit SPEAKER = P1^2;
//定义键盘中断标志,flagINT=1表示有键按下
volatile bit flagINT = 0;
uchar cNum_key1 = 0;
uchar cNum_key2 = 0;
uchar uHour = 0; //小时
uchar uMonth = 0; //月份
uchar uDate = 0; //几号
uchar uSeconds = 0; //秒钟
uchar uMinitues = 0; //分钟
uchar uHoures = 0; //时间中断的小时中间变量
uchar uSeconds_temp = 0;//闹钟定时30s
volatile uint iYear = 0; //年份
volatile ulong iAll_time = 0; //总时间
volatile bit alarm_flag = 0;
bit bChang_week = 1;
bit bChang_year = 1;
bit bChang_alarm = 1;
bit bChang_time = 1;
bit bRealkey2 = 0;
bit bClear_stopwatch=1;
code char DispDat[ ] = //共阴
{ //(显示像素寻址指令)
0XFC,0X60,0XDA,0XF2,0X66,0xB6,0XBE,0XE0,0XFE,0XE6, //0,1,2,3,4,5,6,7,8,9
0xEE,0x3E,0x9C,0x7A,0x9E,0x8E,0xF6,0x6E,0x20, //字母AbCdEFgHiJkLoPqr -的字形数据
0x70,0x0E,0x1C,0x3A,0xCE,0xE6,0x0A,0x02,0x01,0x00
};
uchar idata uTime_DisBuffer[8] ={0,8,27,3,0,27,0,0};
uchar idata uYear_DisBuffer[8] ={0,7,28,0,9,28,2,6};
uchar idata uWeek_DisBuffer[8] ={28,28,28,28,4,28,28,28};
uchar idata uStopwatch_DisBuffer[8]={0,0,27,0,0,27,0,0};
uchar idata uAlarm_DisBuffer[8] ={0,0,26,0,0,26,0,0};// 显示缓冲区地址
ulong iCounter_Inter3 = 0; //进入中断3的次数
ulong iCounter_Inter3_temp = 0;//进入中断3的次数
/*-------------------------------------------------------------
函数:INT0_SVC()
功能:ZLG7290键盘中断服务程序
说明:中断触发方式选择负边沿触发,因此不必等待中断请求信号恢复为高电平
-------------------------------------------------------------*/
void INT0_SVC() interrupt 0 using 0
{
flagINT = 1;
}
/*-------------------------------------------------------------
函数:Delay()
功能:延时10ms~655.36s
参数:
t>0时,延时(t*0.01)s
t=0时,延时655.36s
说明:
晶振采用11.0592MHz
-------------------------------------------------------------*/
void Delay(unsigned int t)
{
uint i;
for( i=0; i<t;i++);
}
/*-------------------------------------------------------------
函数:SystemInit()
功能:系统初始化
-------------------------------------------------------------*/
void SystemInit()
{
I2C_Init();
TMOD = 0x11;
Delay(30); //等待ZLG7290复位完毕
}
/*-------------------------------------------------------------
函数:ClearAll()
功能:清除所有显示
-------------------------------------------------------------*/
void ClearAll()
{
uchar x;
for ( x=0; x<8; x++ )
{
ZLG7290_Download(x,0,0,31);
}
}
/*-------------------------------------------------------------
函数:DispBuf()
功能:测试直接写显存
调用:I2C_Puts(ZLG7290_I2C_ADDR,RegAddr,1,&dat,1)
-------------------------------------------------------------*/
void DispBuf(uchar *p)
{
uchar x;
uchar reg;
uchar dat;
for ( x=0; x<8; x++ )
{
reg = ZLG7290_DpRam + x;
dat = DispDat[p[x]];
ZLG7290_WriteReg(reg,dat); ///
}
}
/*-------------------------------------------------------------
函数名称:Inter_detect_color( ) (定时器1中断)
入口参数:None
功能描述:每10MS进入一次中断
-------------------------------------------------------------*/
void Inter_detect_color( ) interrupt 3 using 3
{
uchar temp;
TH1 = 0XD8; TL1 = 0XF0; TR1 = 1; //每10MS进入一次定时器1中断
iCounter_Inter3++; // 对时间进行处理的标志量
if (iCounter_Inter3==360000)
{
iCounter_Inter3_temp = 0;
}
if (cNum_key1==4) //进入秒表功能
{
if (bRealkey2==1)
{
iCounter_Inter3_temp++;// 对秒表进行处理的标志量
if (bClear_stopwatch==1)
{
iCounter_Inter3_temp=0;
}
temp = iCounter_Inter3_temp%100;
uStopwatch_DisBuffer[6]=temp/10;
uStopwatch_DisBuffer[7]=temp%10;
temp = iCounter_Inter3_temp/100%60;
uStopwatch_DisBuffer[3]=temp/10;
uStopwatch_DisBuffer[4]=temp%10;
temp = iCounter_Inter3_temp/100/60;
uStopwatch_DisBuffer[0]=temp/10;
uStopwatch_DisBuffer[1]=temp%10;
}
}else //计时功能
{
if (!(iCounter_Inter3%100)) //100ms的整数倍
{
uHoures = uTime_DisBuffer[0]*10+uTime_DisBuffer[1];
uMinitues = uTime_DisBuffer[3]*10+uTime_DisBuffer[4];
uSeconds = uTime_DisBuffer[6]*10+uTime_DisBuffer[7];
uSeconds++;
if (uSeconds==60)
{
uMinitues++;
uSeconds = 0;
}
if ((alarm_flag==0)&&(uSeconds>3)) //整点报时
{
SPEAKER = 1;
}
if (uMinitues==60)
{
uHoures++;
uMinitues = 0;
SPEAKER = 0;
}
if (uHoures==24)
{
uHoures=0;
uYear_DisBuffer[7]++;
iYear = 2000+uYear_DisBuffer[0]*10+uYear_DisBuffer[1];
uMonth = uYear_DisBuffer[3]*10+uYear_DisBuffer[4];
uDate = uYear_DisBuffer[6]*10+uYear_DisBuffer[7];
switch (uMonth) //几月份,大月小月
{ //大月
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
if (uDate<31)
{
uDate++;
}else
{
uMonth++;
uDate=1;
}
break;
//平月
case 2:
if( (!(iYear%4)) && ( ((!(iYear%100))&&(!(iYear%400))) || (iYear%100) ) )//闰年
{
if (uDate<29)
{
uDate++;
}else
{
uMonth++;
uDate=1;
}
}else
{
if (uDate<28)
{
uDate++;
}else
{
uMonth++;
uDate=1;
}
}
break;
//小月
case 4:
case 6:
case 9:
case 11:
if (uDate<30)
{
uDate++;
}else
{
uMonth++;
uDate=1;
}
break;
}
if(uMonth==13)
{
iYear++;
uMonth = 1;
}
uYear_DisBuffer[0] = (iYear-2000)/10;
uYear_DisBuffer[1] = (iYear-2000)%10;
uYear_DisBuffer[3] = uMonth/10;
uYear_DisBuffer[4] = uMonth%10;
uYear_DisBuffer[6] = uDate/10;
uYear_DisBuffer[7] = uDate%10;
uWeek_DisBuffer[7]++;
if(uWeek_DisBuffer[7]==8)
{
uWeek_DisBuffer[7]=1;
}
}
uTime_DisBuffer[0]=uHoures/10;
uTime_DisBuffer[1]=uHoures%10;
uTime_DisBuffer[3]=uMinitues/10;
uTime_DisBuffer[4]=uMinitues%10;
uTime_DisBuffer[6]=uSeconds/10;
uTime_DisBuffer[7]=uSeconds%10;
if ( (uAlarm_DisBuffer[0]==uTime_DisBuffer[0])&&(uAlarm_DisBuffer[1]==uTime_DisBuffer[1])
&&(uAlarm_DisBuffer[3]==uTime_DisBuffer[3])&&(uAlarm_DisBuffer[4]==uTime_DisBuffer[4])
&&(uAlarm_DisBuffer[6]==uTime_DisBuffer[6])&&(uAlarm_DisBuffer[7]==uTime_DisBuffer[7]) )
{
SPEAKER = 0;
uSeconds_temp = uSeconds;
alarm_flag=1;
}
if (uSeconds>(uSeconds_temp+10))
{
SPEAKER = 1;
alarm_flag=0;
}
}
}
}
void main()
{
uint i=0;
uint j=0;
uchar KeyValue;
uchar RepeatCnt;
uchar FnKeyValue;
TH1 = 0XD8; TL1 = 0XF0; TR1 = 1; //每1MS进入一次定时器1中断
SPEAKER = 1;
SystemInit(); //系统初始化
ClearAll();
EA = 0;
IT0 = 1; //负边沿触发中断
EX0 = 1; //允许外部中断
ET0 =1; ET1 = 1;
EA = 1;
for (;;)
{
if ( flagINT ) //如果有键按下
{
//清除中断标志
flagINT = 0;
//读取键值、连击计数器值、功能键值
ZLG7290_ReadReg(ZLG7290_Key,&KeyValue);
ZLG7290_ReadReg(ZLG7290_RepeatCnt,&RepeatCnt);
ZLG7290_ReadReg(ZLG7290_FunctionKey,&FnKeyValue);
//显示键值、连击计数器值、功能键值
//DispValue(6,KeyValue);
switch (KeyValue)
{
case 1: //功能设定键
cNum_key1++;
if (cNum_key1 == 6)
{
cNum_key1 = 1;
}
if (cNum_key1 == 4)
{
iCounter_Inter3_temp = 0;
uStopwatch_DisBuffer[6]=0; uStopwatch_DisBuffer[7]=0;
uStopwatch_DisBuffer[3]=0; uStopwatch_DisBuffer[4]=0;
uStopwatch_DisBuffer[0]=0; uStopwatch_DisBuffer[1]=0;
}
break;
case 2: //闪显键
switch (cNum_key1)
{
case 1: //修改时间 00-00-00
//cNum_key2<<=1;
if ( cNum_key2 ==0x00 )
{
cNum_key2=0x01;
}
if(bChang_time == 1)
{
bChang_time = 0;
cNum_key2 = 0x80;
bRealkey2 = 1 ;
}
else
{
bChang_time = 1;
cNum_key2 = 0;
bRealkey2 = 0 ;
}
break;
case 2: //修改年月日
//cNum_key2<<=1;
if ( cNum_key2 ==0x00 )
{
cNum_key2=0x01;
}
if(bChang_year == 1)
{
bChang_year = 0;
cNum_key2 = 0x80;
bRealkey2 = 1 ;
}
else
{
bChang_year = 1;
cNum_key2 = 0;
bRealkey2 = 0 ;
}
break;
case 3: //修改星期 Thursday
if(bChang_week == 1)
{
bChang_week = 0;
cNum_key2 = 0x10;
bRealkey2 = 1 ;
}
else
{
bChang_week = 1;
cNum_key2 = 0;
bRealkey2 = 0 ;
}
break;
case 4: //秒表功能(确定按钮) 00-00-00
bRealkey2 = ~bRealkey2;
if(bRealkey2==0)
{
bClear_stopwatch = 1;
}else
{
bClear_stopwatch=0;
}
TH1 = 0XD8; TL1 = 0XF0; TR1 = 1; //每1MS进入一次定时器1中断
cNum_key2 = 0;
break;
case 5: //设定闹钟(确定按钮) 00-00-00
if(bChang_alarm == 1)
{
bChang_alarm = 0;
cNum_key2 = 0x80;
bRealkey2 = 1 ;
}
else
{
bRealkey2 = 0 ;
bChang_alarm = 1;
cNum_key2 = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -