/** 读写DS1302 时钟芯片
* @author Yangtf
* 很棒的文档http://www.21ic.com/jichuzhishi/datasheet/DS1302/data/185858.html* 时序图http://www.21ic.com/d/file/201307/0a93263a0126e1580cc71c89dce1fda9.jpg**/
#define RST 13 //这是模块的引脚
#define SCLK 11
#define IO 12
//#define L(item) digitalWrite((item),LOW)//#define H(item) digitalWrite((item),HIGH)
#define uchar unsigned char
voidsetup() { //这个就是初始化,这个是固定的函数之一
pinMode(RST,OUTPUT);
pinMode(SCLK,OUTPUT);
pinMode(IO,OUTPUT);
Serial.begin(9600);
attachInterrupt(0, settm, FALLING ); //这个是中断的设置,但是这个???
}void writeData(unsigned char addr,unsigned chardat){ //向芯片里面写数据,
pinMode(IO,OUTPUT);
digitalWrite(RST,LOW);//下拉低,再拉高
digitalWrite(SCLK,LOW) ; //SCLK的上升沿, 芯片会读取IO端口
delayMicroseconds(1);
digitalWrite(RST,HIGH);inti;for(i =0;i<8;i++){
digitalWrite(SCLK,LOW);
digitalWrite(IO, addr&1);
addr=addr>>1;
digitalWrite(SCLK,HIGH);
delayMicroseconds(1);
}for(i =0;i<8;i++){
digitalWrite(SCLK,LOW);
digitalWrite(IO, dat&1);
dat=dat>>1;
digitalWrite(SCLK,HIGH);
delayMicroseconds(1);
}
digitalWrite(RST,LOW);
}
uchar readData(uchar addr){ //从芯片里去读源数据,但是数据还是要经过一定的格式化才行啊
addr= addr | 1; //读操作最低位置为1 要看懂这些就需要查看芯片的手册才是呀
pinMode(IO,OUTPUT);
digitalWrite(RST,LOW);//下拉低,再拉高
digitalWrite(SCLK,LOW) ; //SCLK的上升沿, 芯片会读取IO端口
delayMicroseconds(1);
digitalWrite(RST,HIGH);inti;for(i =0;i<8;i++){ //读取命令是先要写一些命令代码,根据代码,芯片会吐出相应的元素.
digitalWrite(SCLK,LOW);
digitalWrite(IO, addr&1);
addr=addr>>1;
digitalWrite(SCLK,HIGH);
delayMicroseconds(1);
}
pinMode(IO,INPUT); //设置io口为向内读入.这样这个引脚就可以读取数据了.int dat = 0;for(i =0;i<8;i++){
digitalWrite(SCLK,LOW);
delayMicroseconds(10);
uchar b=digitalRead(IO);
dat= dat >>1; //先向右平移
dat= dat | (b<<7); //将所得放入最高位
digitalWrite(SCLK,HIGH);
delayMicroseconds(1);
}
digitalWrite(RST,LOW);returndat ;
}#define SECOND 0x80 //这是一些命令的编号代码. 感觉写的似乎有点不是很整齐,有点乱
#define MIN 0x82
#define HOUR 0x84
#define DAY 0x86
#define MONTH 0x88
#define YEAR 0x8C
#define WEEK 0x8A
voidwriteTimeUnit(uchar TYPE,uchar data){
uchar high= data / 10;
uchar low= data % 10;
uchar d= ((data /10) << 4) | (data % 10);
writeData(TYPE,data);
}
uchar readTimeUnit(uchar TYPE){ //这个是从ds1302芯片中读取一个元素,,,这个参数,决定了要提取的是哪个??
uchar r=readData(TYPE);
r= 10*(r >> 4)+ (r & 0xf); //这个可能是格式的变换returnr;
}voidwriteAllTm(uchar tm[]){
uchar s=SECOND;for(uchar i=0;i<5;i++){
writeTimeUnit(s,tm[5-i]);
s+=2;
}
writeTimeUnit(YEAR,tm[0]);
}voidreadAllTm(uchar tm[]){ //不知道这个是什么???,既然tm是个全局变量,又何必穿过来,??
uchar s=SECOND;for(uchar i=0;i<5;i++){
tm[5-i] =readTimeUnit(s); //这个就是从芯片里读取一个数来.
s+=2;
}
tm[0] =readTimeUnit(YEAR);
tm[6] =readTimeUnit(WEEK);
}voidprintTm(uchar tm[]){
Serial.print(tm[0]);
Serial.print("-");
Serial.print(tm[1]);
Serial.print("-");
Serial.print(tm[2]);
Serial.print(" ");
Serial.print(tm[3]);
Serial.print(":");
Serial.print(tm[4]);
Serial.print(":");
Serial.print(tm[5]);
Serial.print("week");
Serial.print(tm[6]);
Serial.println();
}
uchar st= 0;voidloop() { //这里相当于主函数,主函数里的while
uchar tm[7] = {0}; //年月日,时分秒,星期,一个共是七个数
readAllTm(tm);
printTm(tm);
delay(1000);
}void settm()//中断函数
{
uchar tm[]= {11,12,13,4,5,6 ,0}; //2011-12-22 3:4:1
Serial.println("set tm ...");
writeAllTm(tm);
}