微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 点阵万年历(带时间、年月日星期调整及闹钟功能)C程序

点阵万年历(带时间、年月日星期调整及闹钟功能)C程序

时间:11-29 来源:互联网 点击:

/**************************************/
//根据控制字向1302写一个字节数据//
//入口参数:控制参数kong,实际参数can
/*************************************/
void write1302(uchar kong,uchar can)
{
SCLK=0;
RST=0;
RST=1;
delaya(2);
write1302xei(kong);
write1302xei(can);
SCLK=1;
RST=0;
}
/**************************************/
//向1302读一个字节数据//
//入口参数:dat,x
/*************************************/
uchar read1302du()
{
uchar dat,x;
SCLK=0;
for(x=0;x<8;x++)
{
dat>>=1;
if(DATA==1)
dat|=0x80;
SCLK=1;
delaya(2);
SCLK=0;
delaya(2);
}
return dat;
}
/**************************************/
//根据控制字向1302读一个字节数据//
//入口参数:控制参数kong 实际参:dat
/*************************************/
uchar read1302(uchar kong)
{
uchar dat;
RST=0;
SCLK=0;
RST=1;
write1302xei(kong);
dat=read1302du();
SCLK=1;
RST=0;
return dat;
}
/**************************************/
//根据控制字向1302读一个字节数据//
//入口参数:分别写入:日期:2010-03-07 时间:23:59:54 星期天
/*************************************/
void init1302()
{
/*以下是掉电保护函数通过判断标志位是否为1来判断*/
uchar flag;
flag=read1302(0x81);//读秒数据
if(flag&0x80==1)//判断最高位是否为1,若为1则说明芯片停止工作了,若为0则说明没有停止
{
write1302(0x8e,0x00);//去掉保护
write1302(0x80,((12/10)<4)|(12%10));/*显示54秒/*先将BCD码求模得到高位,然后左移四位,
得到了高四位,然后将BCD码求余这样就得到了低四位,然后相或就转换成了二进制代码了*/
write1302(0x82,((59/10)<4)|(59%10));//显示59分
write1302(0x84,((23/10)<4)|(23%10));//显示23点
write1302(0x86,((7/10)<4)|(7%10));//显示07日
write1302(0x88,((3/10)<4)|(3%10));//显示03月
write1302(0x8c,((10/10)<4)|(10%10));//显示10年
write1302(0x8a,((7/10)<4)|(7%10));//显示星期天
write1302(0x90,0xa5);//打开充电方式,选择一个二极管2K电阻
write1302(0x8e,0x80);//打开保护
}

/*以下是开机复位函数*/
/*
write1302(0x8e,0x00);//去掉保护
write1302(0x80,((12/10)<4)|(12%10));/*显示54秒/*先将BCD码求模得到高位,然后左移四位,
//得到了高四位,然后将BCD码求余这样就得到了低四位,然后相或就转换成了二进制代码了
write1302(0x82,((59/10)<4)|(59%10));//显示59分
write1302(0x84,((23/10)<4)|(23%10));//显示23点
write1302(0x86,((7/10)<4)|(7%10));//显示07日
write1302(0x88,((3/10)<4)|(3%10));//显示03月
write1302(0x8c,((10/10)<4)|(10%10));//显示10年
write1302(0x8a,((7/10)<4)|(7%10));//显示星期天
write1302(0x90,0xa5);//打开充电方式,选择一个二极管2K电阻
write1302(0x8e,0x80);//打开保护
*/
}
/******************************************************/
/***************DS1302转换结果子程序********************/
/******************************************************/
void value()
{
readvalue=read1302(0x83);//读入分地址
fen=((readvalue&0x70)>>4)*10+(readvalue&0x0f);//将分16进制转换成10进制
readvalue=read1302(0x85);//读入小时地址
shi=((readvalue&0x70)>>4)*10+(readvalue&0x0f);//将小时16进制转换成10进制
readvalue=read1302(0x87);//读入日地址
ri=((readvalue&0x70)>>4)*10+(readvalue&0x0f);//将分日进制转换成10进制
readvalue=read1302(0x89);//读入月地址
yue=((readvalue&0x70)>>4)*10+(readvalue&0x0f);//将分月进制转换成10进制
readvalue=read1302(0x8d);//读入年地址
nian=((readvalue&0xf0)>>4)*10+(readvalue&0x0f);//将分年进制转换成10进制
readvalue=read1302(0x8b);//读入星期地址
xin=((readvalue&0x70)>>4)*10+(readvalue&0x0f);//将分星期进制转换成10进制
}
/********************************/
/**74HC595移位寄存器送数子函数***/
/********************************/
void song(uchar dat)//带参数函数
{
uchar num;//定义变量
for(num=0;num<6;num++)//移动6次将数据发送完毕
{
dat>>=1;//将数移走一位
DATA1=CY;//为1就将74HC595数据端置1
CLK=0;//上升沿送走数据
CLK=1;//高电平形成上升沿
}
}
/******************************************************/
/***装一线数据子函数(即一行数据)主时间装数函数********/
/******************************************************/
void yixian(uchar shi,uchar ge,uchar z)
{
BUF[0]=table[(8*(shi/10))+line];//显示小时十位
BUF[1]=table[(8*(shi%10))+line];//显示小时个位
BUF[2]=table1[z*8+line];//显示两个小数点,注意是不同的数组内哟
BUF[3]=table[(8*(ge/10))+line];//显示分十位
BUF[4]=table[(8*(ge%10))+line];//显示分个位
}
/******************************************************/
/***装一线数据子函数(即一行数据)显示黑屏子程序********/
/******************************************************/
void yixianhei()
{
uchar linee,i;
if(line>8)//如果是显示下半屏,就会大于8
linee=line-8;
else
linee=line;//否则直接给数
for(i=0;i<5;i++)//循环5次得到5个数组的数
BUF[i]=table1[8+linee];//查表得到数,注意是数组1中的数
}
/******************************************************/
/*******主程序显示子程序(包括上半屏与下半屏)********/
/******************************************************/
void xianzhu(uchar nia,uchar ye,uchar rii,uchar xi)
{
uchar temp;//左移数值变量
char i;//有符号变量
for(move=0;move<8;move++)//左移8次让下半屏形成左移
{
for(line=0;line<8+lk;line++)//lk变量为选择上半屏还是全屏变量,当它等于0时,只显示上半屏时间,否则全屏显示
{
if(line<8)//如果它小于8则说明lk变量为0,只让它显示上半屏的主时间
{
yixian(shi,fen,dian);//调用主时间一线数值装载子函数
for(i=4;i>=0;i--)
song(~BUF[i]);//循环5次,将数组4-0的数全部发数到显示屏上
}
else//如果大于16则就循环左移显示下半屏的"年月日星期等信息"
{
uchar movee;//局部变量
movee=line-8;//line大于16,此时用它减去8就得到实际要显示的值
BUF[0]=table[16+movee];//显示数字"2"字
BUF[1]=table[movee];//显示数字"0"字
BUF[2]=table[(8*(nia/10))+movee];//显示年十位
BUF[3]=table[(8*(nia%10))+movee];//显示年个位
BUF[4]=table1[16+movee];//显示横线"-"
BUF[5]=table[(8*(ye/10))+movee];//显示月份十位
BUF[6]=table[(8*(ye%10))+movee];//显示月份个位
BUF[7]=table1[16+movee];//显示横线"-"
BUF[8]=table[(8*(rii/10))+movee];//显示日十位
BUF[9]=table[(8*(rii%10))+movee];//显示日个位
BUF[10]=table1[16+movee];//显示横线"-"
BUF[11]=table[(8*(xi%10))+movee];//显示星期几
for(i=4;i>=0;i--)//循环5次将数发送给下半屏
{
temp=((BUF[i+mov]>(6-move)));//将左半屏数左移x位,然后将右
//半屏数右移6-x位,然后或一下就得到在左移了,此句是左移关键!
song(~temp);//送数出去
}
delaya(1000);//延时一下
}
LINE=table2[line];//打开行线,即174HC154行线端
CLKR=1;//在74HC595处锁存起来
CLKR=0;
CLKR=1;
delaya(800);//延时一下
}

}
mov++;//显示完一屏后,将移1个字变量加1,这样就完成下一字显示。原理是:显示下一个数组
if(mov>13)//移完14次,就将它清0。原因是,程序全部定了19个数组,前面显示数用了5个加现在14次,刚好19个数组
mov=0;//清0,重新开始显示
}
/******************************************************/
/**********闪烁间断显示子程序(包括下半屏)************/
/******************************************************/
void xianshan()
{
char ii;//有符号变量
for(line=0;line<8;line++)//扫描8次,即完成一个字的移动
{
if(flag1==0)//如果标志位为0,则以0.5秒速度显示时分钟主界面
yixian(shi,fen,dian);//调用时分秒主界面子程序
if(flag1==1)//如果标志位为1,则以0.5秒速度显示黑屏界面,形成闪烁效果
yixianhei();//调用黑屏子程序
for(ii=4;ii>=0;ii--)//循环5次将数发往显示屏
song(~BUF[ii]);//送数
LINE=table2[line];//打开行线,即174HC154行线端
CLKR=1;//在74HC595处锁存起来
CLKR=0;
CLKR=1;
delaya(800);
}
}
/******************************************************/
/**********年调整界面显示子程序(包括下半屏)************/
/******************************************************/
void xiannian(uchar nia)//变量年
{
uchar movee;
char ii;
for(line=8;line<16;line++)//扫描8次,即完成一个字的移动,line等于8,表示在下半屏显示
{
if(flag1==0)//如果标志位为1,则执行显示部分
{
movee=line-8;
BUF[0]=table[16+movee];//显示数字2
BUF[1]=table[movee];//显示数字0
BUF[2]=table[(8*(nia/10))+movee];//显示年十位
BUF[3]=table[(8*(nia%10))+movee];
BUF[4]=table1[16+movee];//显示横线
}
if(flag1==1)
yixianhei();//否则显示黑屏
for(ii=4;ii>=0;ii--)//循环5次将数发往显示屏
song(~BUF[ii]);//送数
LINE=table2[line];//打开行线,即174HC154行线端
CLKR=1;//在74HC595处锁存起来
CLKR=0;
CLKR=1;
delaya(800);
}
}
/******************************************************/
/*********月/日调整界面显示子程序(包括下半屏)********/
/******************************************************/
void xianriyue(uchar ye,uchar rii)//月与日变量
{
uchar movee;
char ii;
for(line=8;line<16;line++)//扫描8次,即完成一个字的移动,line等于8,表示在下半屏显示
{
if(flag1==0)//同上如果为0就显示,为1就黑屏,形成闪烁
{
movee=line-8;
BUF[0]=table[(8*(ye/10))+movee];//显示月十位
BUF[1]=table[(8*(ye%10))+movee];//月个位
BUF[2]=table1[16+movee];//显示横线
BUF[3]=table[(8*(rii/10))+movee];//显示日十位
BUF[4]=table[(8*(rii%10))+movee];//显示横线
}
if(flag1==1)//为1就黑屏显示
yixianhei();
for(ii=4;ii>=0;ii--)//循环5次将数发往显示屏
song(~BUF[ii]);//送数
LINE=table2[line];//打开行线,即174HC154行线端
CLKR=1;//在74HC595处锁存起来
CLKR=0;
CLKR=1;
delaya(800);
}
}
/******************************************************/
/*********星期调整界面显示子程序(包括下半屏)********/
/******************************************************/
void xi(uchar xi)
{
uchar movee;
char ii;
for(line=8;line<16;line++)//扫描8次,即完成一个字的移动,line等于8,表示在下半屏显示
{
if(flag1==0)//0.5秒显示
{
movee=line-8;
BUF[0]=table1[16+movee];//显示横线"-"
BUF[1]=table1[16+movee];//显示横线"-"
BUF[2]=table[(8*(xi%10))+movee];//显示出星期个位
BUF[3]=table1[16+movee];//显示横线"-"
BUF[4]=table1[16+movee];//显示横线"-"
}
if(flag1==1)
yixianhei();
for(ii=4;ii>=0;ii--)//循环5次将数发往显示屏
song(~BUF[ii]);//送数
LINE=table2[line];//打开行线,即174HC154行线端
CLKR=1;//在74HC595处锁存起来
CLKR=0;
CLKR=1;
delaya(800);
}
}
/******************************************************/
/***************闹钟时间调整显示子程序*****************/
/******************************************************/
void xianniao(uchar shi,uchar ge,uchar z)
{
char ii;
for(line=0;line<8;line++)//扫描8次,即完成一个字的移动
{
if(flag1==0)//同样0.5秒显示时间
{
BUF[0]=table[(8*(shi/10))+line];//显示小时十位
BUF[1]=table[(8*(shi%10))+line];
BUF[2]=table1[z*8+line];//显示横线
BUF[3]=table[(8*(ge/10))+line];//显示分钟十位
BUF[4]=table[(8*(ge%10))+line];
}
if(flag1==1)//同样0.5秒显示黑屏
yixianhei();
for(ii=4;ii>=0;ii--)//循环5次将数发往显示屏
song(~BUF[ii]);//送数
LINE=table2[line];//打开行线,即174HC154行线端
CLKR=1;//在74HC595处锁存起来
CLKR=0;
CLKR=1;
delaya(800);
}
}
/******************************************************/
/***************按键按下后处理子程序*******************/
/******************************************************/
void skey()
{
if(shr!=0)//如果标志位shr不为0,则执行以下内容------如果按下了加按键则程序复位
{
if(key1==0)
{
delay(10);
if(key1==0)//如果加按键按下了,则全部复位
{
yin=0;//将按键计数器清0
shr=0;//标志位清0
lk=0;//显示上半屏,此变量是全屏与半屏控制变量,当它为8时,就执行全屏,否则半屏
clockbiao=~clockbiao;
bbtsoud();//蜂鸣器响一声子程序
while(!key1);//按键释放
}
}
}
if(a!=0)//如果标志位不为0,则执行以下内容-------闪烁进入调整模式
xianshan();//闪烁
if(b!=0)//如果标志位不为0,则执行以下内容,进行主时间小时调整
{
xianshan();//调用主时间显示子程序
if(key1==0)
{
delay(10);
if(key1==0)
{
xianshan();
shi++;
if(shi==24)//小时等于24?
shi=0;//清0
write1302(0x8e,0x00);//去掉保护
write1302(0x84,((shi/10)<4)|(shi%10));//时数据写入
write1302(0x8e,0x80);//打开保护
readvalue=read1302(0x85);
shi=((readvalue&0xf0)>>4)*10+(readvalue&0x0f);//将小时转换出来
while(!key1);
}
}
if(key2==0)//以下是处理主时间小时减部分
{
delay(10);
if(key2==0)
{
shi--;
if(shi==(0-1))
shi=23;
write1302(0x8e,0x00);//去掉保护
write1302(0x84,((shi/10)<4)|(shi%10));//时数据写入
write1302(0x8e,0x80);//打开保护
readvalue=read1302(0x85);
shi=((readvalue&0xf0)>>4)*10+(readvalue&0x0f);
while(!key2);
}
}
}
if(c!=0)//如果标志位不为0,则执行以下内容------以下是处理主时间分钟调整部分
{
xianshan();
if(key1==0)//加分钟部分
{
delay(10);
if(key1==0)
{
xianshan();//调用主时间显示子程序
fen++;
if(fen==60)
fen=00;
write1302(0x8e,0x00);//去掉保护
write1302(0x82,((fen/10)<4)|(fen%10));//分数据写入
write1302(0x8e,0x80);//打开保护
readvalue=read1302(0x83);
fen=((readvalue&0xf0)>>4)*10+(readvalue&0x0f);//将它转换出来
while(!key1);
}
}
if(key2==0)//减分钟部分
{
delay(10);
if(key2==0)
{
xianshan();
fen--;
if(fen==(0-1))
fen=59;
write1302(0x8e,0x00);//去掉保护
write1302(0x82,((fen/10)<4)|(fen%10));//分数据写入
write1302(0x8e,0x80);//打开保护
readvalue=read1302(0x83);
fen=((readvalue&0xf0)>>4)*10+(readvalue&0x0f);
while(!key2);
}

}
}
if(d!=0)//如果标志位不为0,则执行以下内容-----调整年
{
xiannian(nian);//调用年显示子程序
if(key1==0)//年时间加部分处理
{
delay(10);
if(key1==0)
{
xiannian(nian);
nian++;
if(nian==99)//年到了99吗?
nian=0;
write1302(0x8e,0x00);//去掉保护
write1302(0x8c,((nian/10)<4)|(nian%10));//年数据写入
write1302(0x8e,0x80);//打开保护
readvalue=read1302(0x8d);
nian=((readvalue&0xf0)>>4)*10+(readvalue&0x0f);//年数据转换
while(!key1);
}
}
if(key2==0)//年时间减部分处理
{
delay(10);
if(key2==0)
{
xiannian(nian);
nian--;
if(nian==(0-1))
nian=99;
write1302(0x8e,0x00);//去掉保护
write1302(0x8c,((nian/10)<4)|(nian%10));//年数据写入
write1302(0x8e,0x80);//打开保护
readvalue=read1302(0x8d);
nian=((readvalue&0xf0)>>4)*10+(readvalue&0x0f);//年数据转换
while(!key2);
}

}
}
if(e!=0)//如果标志位不为0,则执行以下内容-----处理月
{
xianriyue(yue,ri);
if(key1==0)//月加部分处理
{
delay(10);
if(key1==0)
{
xianriyue(yue,ri);
yue++;
if(yue==13)
yue=1;
write1302(0x8e,0x00);//去掉保护
write1302(0x88,((yue/10)<4)|(yue%10));//月数据写入
write1302(0x8e,0x80);//打开保护
readvalue=read1302(0x89);
yue=((readvalue&0xf0)>>4)*10+(readvalue&0x0f);
while(!key1);
}
}
if(key2==0)//月减部分处理
{
delay(10);
if(key2==0)
{
xianriyue(yue,ri);
yue--;
if(yue==(1-1))
yue=12;
write1302(0x8e,0x00);//去掉保护
write1302(0x88,((yue/10)<4)|(yue%10));//月数据写入
write1302(0x8e,0x80);//打开保护
readvalue=read1302(0x89);
yue=((readvalue&0xf0)>>4)*10+(readvalue&0x0f);//月转换
while(!key2);
}

}
}
if(f!=0)//如果标志位不为0,则执行以下内容-------调整日
{
xianriyue(yue,ri);
if(key1==0)//加日部分
{
delay(10);
if(key1==0)
{
xianriyue(yue,ri);
ri++;
if(ri==32)
ri=1;
write1302(0x8e,0x00);//去掉保护
write1302(0x86,((ri/10)<4)|(ri%10));//日数据写入
write1302(0x8e,0x80);//打开保护
readvalue=read1302(0x87);
ri=((readvalue&0xf0)>>4)*10+(readvalue&0x0f);
while(!key1);
}
}
if(key2==0)//减日部分
{
delay(10);
if(key2==0)
{
xianriyue(yue,ri);
ri--;
if(ri==(1-1))
ri=31;
write1302(0x8e,0x00);//去掉保护
write1302(0x86,((ri/10)<4)|(ri%10));//日数据写入
write1302(0x8e,0x80);//打开保护
readvalue=read1302(0x87);
ri=((readvalue&0xf0)>>4)*10+(readvalue&0x0f);
while(!key2);
}

}
}
if(g!=0)//如果标志位不为0,则执行以下内容-----星期调整部分
{
xi(xin);
if(key1==0)//星期加部分
{
delay(10);
if(key1==0)
{
xi(xin);
xin++;//将星期+1
if(xin==8)//如果星期到了8就清它清1
xin=1;//清1
write1302(0x8e,0x00);//去掉保护
write1302(0x8a,((xin/10)<4)|(xin%10));//显示星期天
write1302(0x8e,0x80);//打开保护
readvalue=read1302(0x8b);//读星期
xin=((readvalue&0xf0)>>4)*10+(readvalue&0x0f);//将星期值还原
while(!key1);
}
}
if(key2==0)//星期减部分
{
delay(10);
if(key2==0)
{
xi(xin);
xin--;//减1
if(xin==(1-1))//如果到了(1-1)就给它7,因为星期只1---7
xin=7;//将它给7
write1302(0x8e,0x00);//去掉保护
write1302(0x8a,((xin/10)<4)|(xin%10));//显示星期天
write1302(0x8e,0x80);//打开保护
readvalue=read1302(0x8b);
xin=((readvalue&0xf0)>>4)*10+(readvalue&0x0f);//读星期值
while(!key2);
}

}
}
if(h!=0)////如果标志位不为0,则执行以下内容------------以下是闹钟小时调整部分
{
xianniao(shin,fenn,2);//调整闹钟小时与分钟显示子程序
if(key1==0)//闹钟小时加处理
{
delay(10);
if(key1==0)
{
xianniao(shin,fenn,2);
shin++;//将星期+1
if(shin==24)//如果星期到了8就清它清1
shin=0;//清1
while(!key1);
}
}
if(key2==0)//闹钟小时减处理
{
delay(10);
if(key2==0)
{
xianniao(shin,fenn,2);
shin--;
if(shin==(0-1))
shin=23;
while(!key2);
}

}
}
if(i!=0)//如果标志位不为0,则执行以下内容----------闹钟分钟调整
{
xianniao(shin,fenn,2);
if(key1==0)//闹钟分钟加处理
{
delay(10);
if(key1==0)
{
xianniao(shin,fenn,2);
fenn++;//将星期+1
if(fenn==60)//如果星期到了8就清它清1
fenn=0;//清1
while(!key1);
}
}
if(key2==0)//闹钟分钟减处理
{
delay(10);
if(key2==0)
{
xianniao(shin,fenn,2);
fenn--;
if(fenn==(0-1))
fenn=59;
while(!key2);
}

}
}
}
/******************************************************/
/*******************响闹子程序*************************/
/******************************************************/
void xiangniao()
{
bit clock;//定义一个标志位
if(clockbiao==0)//闹钟总标志为0时才可以执行闹钟处理程序
{
if(clock==0)//如果标志位为0,就执行下面内容
{
if(shin==shi)//主时间小时与闹钟小时相等吗?
{
if(fenn==fen)//主时间分钟与闹钟分钟相等吗?
bbtsoud();//相等了就执行闹钟响一声子程序,即小时与分钟都相等了就执行闹铃
}
}
if(fenn!=fen)//如果分钟不等
clock=0;//将标志位清0,以便下次再响铃
if(key1==0)//判断加"+"按键有没有被按下,如果按下了,就让闹铃停止响
{
delay(10);
if(key1==0)
{
clock=1;//将标志位清0,让闹钟在响铃时立马停下来
while(!key1);
}
}
}
if(key2==0)//如果减按键按下了,则则关闭闹铃全部功能
{
delay(10);
if(key2==0)//如果加按键按下了,则全部复位
{
clockbiao=~clockbiao;
bbtsoud();//蜂鸣器响一声子程序
while(!key2);//按键释放
}
}
}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top