DS1302时钟C语言编程完整实例Word格式.docx
- 文档编号:22998273
- 上传时间:2023-02-06
- 格式:DOCX
- 页数:30
- 大小:484.56KB
DS1302时钟C语言编程完整实例Word格式.docx
《DS1302时钟C语言编程完整实例Word格式.docx》由会员分享,可在线阅读,更多相关《DS1302时钟C语言编程完整实例Word格式.docx(30页珍藏版)》请在冰豆网上搜索。
①DS1302有关日历、时间的寄存器共有12个,其中有7个寄存器
(读时81h~8Dh,写时80h~8Ch),存放的数据格式为BCD码形式,如图3所示。
图3DS1302有关日历、时间的寄存器小时寄存器(85h、84h)的位7用于定义DS1302是运行于12小时模式还是24小时模式。
当为高时,选择12小时模式。
在12小时模式时,
位5是,当为1时,表示PM。
在24小时模式时,位5是第二个10小时
位。
秒寄存器(81h、80h)的位7定义为时钟暂停标志(CH)。
当该位置为1时,时钟振荡器停止,DS1302处于低功耗状态;
当该位置为
0时,时钟开始运行。
控制寄存器(8Fh、8Eh)的位7是写保护位(WP),其它7位均置
为0。
在任何的对时钟和RAM的写操作之前,WP位必须为0。
当
WP位为1时,写保护位防止对任一寄存器的写操作。
②DS1302有关RAM的地址
DS1302中附加31字节静态RAM的地址如图4所示。
图4
③DS1302的工作模式寄存器
所谓突发模式是指一次传送多个字节的时钟信号和RAM数据。
突发模式寄存器如图5所示。
图5
④此外,DS1302还有充电寄存器等。
2读写时序说明
DS1302是SPI总线驱动方式。
它不仅要向寄存器写入控制字,还需要读取相应寄存器的数据。
要想与DS1302通信,首先要先了解DS1302的控制字。
DS1302
的控制字如图6。
图6控制字(即地址及命令字节)
控制字的最高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入到DS1302中。
位6:
如果为0,则表示存取日历时钟数据,为1表示存取RAM数据;
位5至位1(A4~A0):
指示操作单元的地址;
位0(最低有效位):
如为0,表示要进行写操作,为1表示进行读操作。
控制字总是从最低位开始输出。
在控制字指令输入后的下一个
SCLK时钟的上升沿时,数据被写入DS1302,数据输入从最低位(0位)开始。
同样,在紧跟8位的控制字指令后的下一个SCLK脉冲的下降沿,读出DS1302的数据,读出的数据也是从最低位到最高位。
数据读写时序如图7。
以上部分是我拷贝别人的,在此我要感谢他,后面的部分全部是我自己写的,经过调试,系统运行稳定。
本来是不准备拷贝的,但考虑读者可能会读不懂程序,所以我才将核心器件的通信协议拿来给大家看看,当初老师叫我随便用C语言编写个单片机程序,于是我就找了个DS1302时钟的程序,写的有点长,可能是我第一次经验不够吧。
#include<
reg51.h>
stdio.h>
#defineucharunsignedchar
#defineuintunsignedint
ucharcodetable[]=
{0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x80,0x90,0x7f};
//0123456789.
sbitsclk=P3^6;
sbitdata_io=P3^7;
sbitrst=P3^5;
sbitk1=P1^4;
//mod功能选择键
sbitk2=P1^5;
//--(待机时按此键显示当前日期)
sbitk3=P1^6;
//++(待机时,按此键显示闹钟时间及状态,进入闹钟设定时此键是闹铃开关键)
sbitk4=P1^7;
//退出设定
sbitdidi=P3^0;
//闹钟铃音
ucharmod;
ucharkaiguan;
bitkeys(void);
//函数申明
voidshow(x,y,z);
voidalarmshow(a_shi,a_fen);
voiddelay(uintms)//1ms延时子程序
{
uinti,j;
for(i=ms;
i>
0;
i--)
for(j=244;
j>
j--);
}
voidalarmdisplay(ucharshu,ucharwei)//闹钟显示子程序
P2=0x00;
P0=table[shu];
P2=(1<
<
wei);
delay
(1);
if(kaiguan%2)//显示ON12-23,闹钟时间显示格式
{
P0=0xc0;
P2=0x01;
delay
(1);
P2=0x00;
P0=0xc8;
P2=0x02;
P0=0xf7;
P0=0x08;
}
else//显示OFF12-23,闹钟时间显示格式
{
P2=0x00;
P0=0xc0;
P2=0x01;
delay
(1);
P0=0x8e;
P2=0x02;
P2=0x04;
}
voiddisplay(ucharshu,ucharwei)//显示函数
//显示该位数字
P0=0xbf;
P2=0x04;
//显示横杠
P2=0x20;
voidweidisplay(void)//调时间时显示调整哪一个位
ucharwei;
P0=0x7f;
if(mod==1||mod==4||mod==7)
wei=3;
if(mod==2||mod==5)
wei=0;
if(mod==3||mod==6)
wei=6;
P2=(3<
delay(3);
voidalarm()//闹钟铃音子程序
uinti;
for(i=59;
didi=1;
didi=0;
if(k1==0)
delay(5);
if(k1==0)
{
while(~k1);
break;
}
voidwrite(ucharaddr,ucharshu)//写两个字节
uchartemp,t;
rst=0;
sclk=0;
rst=1;
temp=addr;
for(t=0;
t<
8;
t++)
if(temp&
0x01)
data_io=1;
elsedata_io=0;
sclk=1;
delay
(1);
sclk=0;
temp>
>
=1;
temp=shu;
if(temp&
elsedata_io=0;
sclk=1;
sclk=0;
temp>
rst=0;
ucharread(ucharaddr)//读一个字节
uchartemp,t;
data_io=1;
}
temp=0;
7;
if(data_io==1)
temp=temp|0x80;
elsetemp=temp&
0x7f;
returntemp;
//************************************************8888
voidmain()//主函数
bitflag;
ucharshi,fen,miao,nian,yue,ri,a_shi,a_fen;
//当前时间10:
06:
5310-12-20
write(0x80,0x53);
write(0x82,0x06);
//秒寄存器(初始化年月日,时分秒,闹铃)
write(0x84,0x10);
//时寄存器
write(0x86,0x20);
//日寄存器
write(0x88,0x12);
//月寄存器
write(0x8c,0x10);
//年寄存器
a_shi=0x07;
//初始化闹钟时间7:
30
a_fen=0x30;
while
(1)
shi=read(0x85);
//读小时
fen=read(0x83);
//读分钟
miao=read(0x81);
//读秒钟
if(kaiguan%2)//判断闹钟
if(a_shi==shi&
&
a_fen==fen)
alarm();
if(k3==0&
mod==0)//待机情况下按k3显示闹铃时间
delay(5);
if(k3==0&
mod==0)
{
while(~k3)
alarmshow(a_shi,a_fen);
}
if(k2==0&
mod==0)//待机情况下按k2显示日期
if(k2==0&
while(~k2)
show(nian,yue,ri);
flag=keys();
//按键标识位,有按键按下时flag=1;
if
(1)//程序出现个小错误,原本这里是写flag,但没有办法,只能写1了,感兴趣的话自己分析
if(mod==1)
if(k4==0)//如果k4=0,则退出设定
delay(5);
if(k4==0)
{
while(~k4);
mod=0;
}
if(k2==0)
if(k2==0)
while(~k2);
fen=(fen>
4)*10+(fen&
0x0f);
fen++;
if(fen==60)
fen=0;
fen=((fen/10)<
4)+((fen%10)&
write(0x82,fen);
}
if(mod==2)
if(k4==0)//如果k4=0,则退出设定
shi=(shi>
4)*10+(shi&
shi++;
if(shi==24)
shi=0;
shi=((shi/10)<
4)+((shi%10)&
write(0x84,shi);
if(mod==1)
if(k3==0)
if(k3==0)
while(~k3);
if(fen==0)
fen=60;
fen--;
if(shi==0)
shi=24;
shi--;
if(mod==3)
ri=(ri>
4)*10+(ri&
ri++;
if(ri==32)
ri=0;
ri=((ri/10)<
4)+((ri%10)&
write(0x86,ri);
if(mod==4)
yue=(yue>
4)*10+(yue&
yue++;
if(yue==13)
yue=0;
yue=((yue/10)<
4)+((yue%10)&
write(0x88,yue);
if(mod==5)
nian=(nian>
4)*10+(nian&
nian++;
if(nian==100)
nian=0;
nian=((nian/10)<
4)+((nian%10)&
write(0x8c,nian);
if(mod==3)//年月日减
if(ri==0)
ri=32;
ri--;
if(k4==0)//如果k4=0,则退出设定
if(yue==0)
yue=32;
yue--;
if(nian==0)
nian=100;
nian--;
//*################################################################################
if(mod==6)
if(k4==0)//如果k4=0,则退出设定
while(~k3);
kaiguan++;
while(~k2);
a_fen=(a_fen>
4)*10+(a_fen&
a_fen++;
if(a_fen==60)
a_fen=0;
a_fen=((a_fen/10)<
4)+((a_fen%10)&
if(mod==7)
if(k4==0)/
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- DS1302 时钟 语言 编程 完整 实例