/* * 讀寫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 void setup() { //這個就是初始化,這個是固定的函數之一 pinMode(RST,OUTPUT); pinMode(SCLK,OUTPUT); pinMode(IO,OUTPUT); Serial.begin(9600); attachInterrupt(0, settm, FALLING ); //這個是中斷的設置,但是這個??? }
void writeData(unsigned char addr,unsigned char dat){ //向芯片里面寫數據, pinMode(IO,OUTPUT); digitalWrite(RST,LOW); //下拉低,再拉高 digitalWrite(SCLK,LOW) ; //SCLK的上升沿, 芯片會讀取IO端口 delayMicroseconds(1); digitalWrite(RST,HIGH); int i; 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); int i; 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); return dat ; } #define SECOND 0x80 //這是一些命令的編號代碼. 感覺寫的似乎有點不是很整齊,有點亂 #define MIN 0x82 #define HOUR 0x84 #define DAY 0x86 #define MONTH 0x88 #define YEAR 0x8C #define WEEK 0x8A void writeTimeUnit(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); //這個可能是格式的變換 return r; }
void writeAllTm(uchar tm[]){ uchar s = SECOND; for(uchar i=0;i<5;i++){ writeTimeUnit(s,tm[5-i]); s+=2; } writeTimeUnit(YEAR,tm[0]); }
void readAllTm(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); }
void printTm(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; void loop() { //這里相當於主函數,主函數里的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); }
上面是從網上摘來的。
但是這個中斷我還是不會,所以把中斷去掉把,這樣直接顯示串口的東西