uchar i;
uchar fen1=0x11,shi1=0; //两个闹钟变量的定义 bit open1;
/*************写一个数据到对应的地址里***************/ void write_ds1302(uchar add,uchar dat) { rst = 1; //把复位线拿高 for(i=0;i<8;i++) { //低位在前 clk = 0; //时钟线拿低开始写数据
io = add & 0x01; add >>= 1; //把地址右移一位 clk = 1; //时钟线拿高 }
for(i=0;i<8;i++) { clk = 0; //时钟线拿低开始写数据 io = dat & 0x01; dat >>= 1; //把数据右移一位 clk = 1; //时钟线拿高
}
rst = 0; //复位线合低 clk = 0; io = 0; }
/*************从对应的地址读一个数据出来***************/ uchar read_ds1302(uchar add) {
uchar value,i; rst = 1; //把复位线拿高 for(i=0;i<8;i++) { //低位在前 clk = 0; //时钟线拿低开始写数据 io = add & 0x01; add >>= 1; //把地址右移一位 clk = 1; //时钟线拿高
22
}
for(i=0;i<8;i++) { clk = 0; //时钟线拿低开始读数据 value >>= 1; if(io == 1) value |= 0x80; clk = 1; //时钟线拿高 }
rst = 0; //复位线合低
clk = 0;
io = 0;
return value; //返回读出来的数据 }
/*************把要的时间 年月日 都读出来***************/ void read_time() {
miao = read_ds1302(read_add[0]); //读秒 fen = read_ds1302(read_add[1]); //读分 shi = read_ds1302(read_add[2]); //读时 ri = read_ds1302(read_add[3]); //读日 yue = read_ds1302(read_add[4]); //读月 nian = read_ds1302(read_add[5]); //读年 week = read_ds1302(read_add[6]); //读星期 Conversion(0,nian,yue,ri); //农历转换
n_nian = year_moon ;
n_yue = month_moon ;
n_ri = day_moon ; }
/*************把要写的时间 年月日 都写入ds1302void write_time() {
23
里
***************/
}
write_ds1302(0x8e,0x00); //打开写保护 //写秒 //写分 //写时 //写日 //写月 //写星期 //写年
//关闭写保护
write_ds1302(write_add[0],miao); write_ds1302(write_add[1],fen); write_ds1302(write_add[2],shi); write_ds1302(write_add[3],ri); write_ds1302(write_add[4],yue); write_ds1302(write_add[5],nian); write_ds1302(write_add[6],week); write_ds1302(0x8e,0x80);
/*************把数据保存到ds1302 RAM中**0-31*************/ void write_ds1302ram(uchar add,uchar dat) {
add <<= 1; //地址是从第二位开始的
add &= 0xfe; //把最低位清零 是写的命令 add |= 0xc0; //地址最高两位为 1 write_ds1302(0x8e,0x00); write_ds1302(add,dat); write_ds1302(0x8e,0x80); }
/*************把数据从ds1302 RAM读出来**0-31*************/ uchar read_ds1302ram(uchar add) {
add <<= 1; //地址是从第二位开始的 add |= 0x01; //把最高位置1 是读命令 add |= 0xc0; //地址最高两位为 1 return(read_ds1302(add)); }
/*************初始化ds1302时间***************/ void init_ds1302() {
uchar i;
rst = 0; //第一次读写数据时要把IO品拿低 clk = 0;
24
ds1302
io = 0;
i = read_ds1302ram(30); if(i != 3) { i = 3; write_ds1302ram(30,i);
//4050 4100 3080
write_ds1302(0x8e,0x00); //打开写保护 for(i=0;i<7;i++) write_ds1302(write_add[i],init_ds[i]); //把最高位值0 允许工作
write_ds1302(0x8e,0x80); //关写保护 } }
DS1302与微处理器进行数据交换时,首先由微处理器向电路发送命令字节,命令字节最高位MSB(D7)必须为逻辑 1,如果D7=0,则禁止写DS1302,即写保护;D6=0,指定时钟数据,D6=1,指定RAM数据;D5~D1指定输入或输出的特定寄存器;最低位LSB(D0)为逻辑0,指定写操作(输入),D0=1,指定读操作(输出) 。 4.2.2 温度程序设计
单总线上最基本的操作有初始化、写和读3种,所有其它的操作都由这3种基本操作组合而成,初始化用于对总线上的器件进行状态复位,写用于主节点向总线上写入一位数据,读用于主节点从总线上读取一位数据。在这3种操作中,只有写操作是单向的,初始化操作和读操作都是双向的。具体程序设计如下:
byte ow_reset(void) {
byte presence;
DQ = 0; //拉低总线
delay(29); // 保持 480us DQ = 1; // 释放总线 delay(3); // 等待回复 presence = DQ; // 读取信号 delay(25); // 等待结束信号
return(presence); // 返回 0:正常 1:不存在 }
//从 1-wire 总线上读取一个字节
25
byte read_byte(void) {
byte i;
byte value = 0; for (i=8;i>0;i--) {
value>>=1; DQ = 0; DQ = 1; delay(1);
if(DQ)value|=0x80;
delay(6); }
return(value); }
//向 1-WIRE 总线上写一个字节 void write_byte(char val) {
byte i;
for (i=8; i>0; i--) // 一次写一位 {
DQ = 0; //
DQ = val&0x01; delay(5); // DQ = 1; val=val/2; }
delay(5); }
26