1、DS1302时钟C语言编程完整实例DS1302时钟C语言编程完整实例1 DS1302 简介:DS1302是美国 DALLAS 公司推出的一种高性能、低功耗的实时 时钟芯片,附加31字节静态 RAM,采用 SPI 三线接口与 CPU 进行同步通信,并可采用突发方式一次传送多个字节的时钟信号和 RAM数据。实时时钟可提供秒、分、时、日、星期、月和年,一个月小与31天时可以自动调整,且具有闰年补偿功能。工作电压宽达2.55.5V。采用双电源供电(主电源和备用电源),可设置备用电源充电 方式,提供了对后背电源进行涓细电流充电的能力。DS1302的外部引脚分配如图1所示及内部结构如图2所示。DS1302
2、用于数据记录, 特别是对某些具有特殊意义的数据点的记录上,能实现数据与出现该数据的时间同时记录,因此广泛应用于测量系统中。图1 DS1302的外部引脚分配图2 DS1302的内部结构各引脚的功能为:Vcc1:主电源;Vcc2:备份电源。当 Vcc2Vcc1+0.2V 时, 由 Vcc2向 DS1302供电,当 Vcc2 Vcc1时,由 Vcc1向 DS1302供电。SCLK:串行时钟,输入,控制数据的输入与输出;I/O:三线接口时的双向数据线;CE:输入信号,在读、写数据期间,必须为高。该引脚有两 个功能:第一,CE 开始控制字访问移位寄存器的控制逻辑;其次,CE 提供结束单字节或多字节数据传
3、输的方法。DS1302有下列几组寄存器: DS1302有关日历、时间的寄存器共有12个,其中有7个寄存器(读时81h8Dh,写时80h8Ch),存放的数据格式为 BCD 码形式, 如图3所示。图 3 DS1302有关日历、时间的寄存器 小时寄存器(85h、84h)的位7用于定义 DS1302是运行于12小时 模式还是24小时模式。当为高时,选择12小时模式。在12小时模式时,位5是 ,当为1时,表示 PM。在24小时模式时,位5是第二个10小时位。秒寄存器(81h、80h)的位7定义为时钟暂停标志(CH)。当该 位置为1时,时钟振荡器停止,DS1302处于低功耗状态;当该位置为0时,时钟开始运
4、行。 控制寄存器(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通信,首先要先了解 DS13
5、02的控制字。DS1302的控制字如图6。图6 控制字(即地址及命令字节)控制字的最高有效位(位7)必须是逻辑1,如果它为0,则不能把 数据写入到 DS1302中。位6:如果为0,则表示存取日历时钟数据,为1表示存取 RAM 数 据;位5至位1(A4A0):指示操作单元的地址;位0(最低有效位):如为0,表示要进行写操作,为1表示进行读 操作。控制字总是从最低位开始输出。在控制字指令输入后的下一个SCLK 时钟的上升沿时,数据被写入 DS1302,数据输入从最低位(0 位)开始。同样,在紧跟8位的控制字指令后的下一个 SCLK 脉冲的 下降沿,读出 DS1302的数据,读出的数据也是从最低位到
6、最高位。 数据读写时序如图7 。以上部分是我拷贝别人的,在此我要感谢他,后面的部分全部是我自己写的,经过调试,系统运行稳定。本来是不准备拷贝的,但考虑读者可能会读不懂程序,所以我才将核心器件的通信协议拿来给大家看看,当初老师叫我随便用C语言编写个单片机程序,于是我就找了个DS1302时钟的程序,写的有点长,可能是我第一次经验不够吧。#include #include #define uchar unsigned char#define uint unsigned intuchar code table= 0xc0,0xf9,0xa4,0xb0, 0x99,0x92,0x82,0xf8, 0x8
7、0,0x90,0x7f;/ 0 1 2 3 4 5 6 7 8 9 .sbit sclk=P36;sbit data_io=P37;sbit rst=P35;sbit k1=P14;/mod功能选择键sbit k2=P15;/- (待机时按此键显示当前日期)sbit k3=P16;/+ (待机时,按此键显示闹钟时间及状态,进入闹钟设定时此键是闹铃开关键)sbit k4=P17;/退出设定sbit didi=P30;/闹钟铃音uchar mod;uchar kaiguan;bit keys(void);/函数申明void show(x,y,z);/函数申明void alarmshow(a_shi
8、,a_fen);/函数申明void delay(uint ms) /1ms延时子程序 uint i,j; for(i=ms;i0;i-) for(j=244;j0;j-);void alarmdisplay(uchar shu,uchar wei)/闹钟显示子程序 P2=0x00; P0=tableshu; P2=(1wei); delay(1); P2=0x00; if(kaiguan%2)/显示ON 12-23,闹钟时间显示格式 P0=0xc0; P2=0x01; delay(1); P2=0x00; P0=0xc8; P2=0x02; delay(1); P2=0x00; P0=0xf7
9、; P0=0x08; delay(1); P2=0x00; else /显示OFF12-23,闹钟时间显示格式 P2=0x00; P0=0xc0; P2=0x01; delay(1); P2=0x00; P0=0x8e; P2=0x02; delay(1); P2=0x00; P0=0x8e; P2=0x04; delay(1); P2=0x00; void display(uchar shu,uchar wei)/显示函数 P2=0x00; P0=tableshu; P2=(1wei); delay(1); P2=0x00;/显示该位数字 P0=0xbf; P2=0x04; delay(1)
10、;/显示横杠 P2=0x00; P0=0xbf; P2=0x20; delay(1);/显示横杠 P2=0x00;void weidisplay(void)/调时间时显示调整哪一个位 uchar wei; P2=0x00; 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=(30;i-) didi=1; delay(1); didi=0; delay(1); if(k1=0) delay(5); if(k1=0) while(k1); break; void write(
11、uchar addr,uchar shu) /写两个字节 uchar temp,t; rst=0; sclk=0; rst=1; temp=addr; for(t=0;t=1; temp=shu; for(t=0;t=1; rst=0;uchar read(uchar addr)/读一个字节 uchar temp ,t; rst=0; sclk=0; rst=1; temp=addr; for(t=0;t=1; temp=0; for(t=0;t=1; return temp;/*8888/*8888void main() /主函数 bit flag; uchar shi,fen,miao,n
12、ian,yue,ri,a_shi,a_fen;/当前时间10:06:53 10-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);/读秒钟
13、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显示日期 delay(5); if(k2=0&mod=0) while(k2) show(nian,yue,ri); flag=keys(); /按键标识位,有按键按下时flag=1; if(1) /程序出现个小错误,原本这里是写flag,但没有办法,只能写1了,感兴趣的
14、话自己分析 if(mod=1) if(k4=0)/如果k4=0,则退出设定 delay(5); if(k4=0) while(k4); mod=0; if(k2=0) delay(5); if(k2=0) while(k2); fen=(fen4)*10+(fen&0x0f); fen+; if(fen=60) fen=0; fen=(fen/10)4)*10+(shi&0x0f); shi+; if(shi=24) shi=0; shi=(shi/10)4)*10+(fen&0x0f); if(fen=0) fen=60; fen-; fen=(fen/10)4)*10+(shi&0x0f)
15、; if(shi=0) shi=24; shi-; shi=(shi/10)4)*10+(ri&0x0f); ri+; if(ri=32) ri=0; ri=(ri/10)4)*10+(yue&0x0f); yue+; if(yue=13) yue=0; yue=(yue/10)4)*10+(nian&0x0f); nian+; if(nian=100) nian=0; nian=(nian/10)4)*10+(ri&0x0f); if(ri=0) ri=32; ri-; ri=(ri/10)4)*10+(yue&0x0f); if(yue=0) yue=32; yue-; yue=(yue/10)4)*10+(nian&0x0f); if(nian=0) nian=100; nian-; nian=(nian/10)4)*10+(a_fen&0x0f); a_fen+; if(a_fen=60) a_fen=0; a_fen=(a_fen/10)4)+(a_fen%10)&0x0f); if(mod=7) if(k4=0)/
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1