全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:6000
推到 Plurk!
推到 Facebook!

萬年曆IC求解 DS1302

答題得分者是:DavidLo
現在想見妳
一般會員


發表:3
回覆:11
積分:2
註冊:2009-08-20

發送簡訊給我
#1 引用回覆 回覆 發表時間:2009-09-01 14:56:10 IP:163.21.xxx.xxx 訂閱
我又來這邊想請大家一起幫我解決問題了,
我現在做的是DS1302的實驗,這一個是萬年曆IC,可是我在讀裡面資料的時候好像會跑步出來,
我想請大家幫忙一下,以下是我的程式:

[code cpp]
//************************************************************

//************************************************************
#include
#include "LCD.H"
#define Time ACC
sbit RST = P0^0;
sbit IO = P0^1;
sbit SCLK = P0^2;

sbit Time0 = Time^0;
sbit Time7 = Time^7;
unsigned char T[7]={0};
//************************************************************
void writeTdata(unsigned char Tdata);
void write1302(unsigned char cmd,unsigned char T);
unsigned char Readdata(void);
unsigned char Read1302(unsigned char m);
//void SetTime(void);
void ReadTime(void);
unsigned char BCD2DEC(unsigned char BCD);
void SetTimeSet(void);
void LED(unsigned char L);
//************************************************************
void writeTdata(unsigned char Tdata)
{
unsigned char i;
SCLK = 0;
Time = Tdata;

for( i = 0; i < 8; i )
{
IO = Time0;
SCLK = 1;
SCLK = 0;
Time = Time >> 1;
}

SCLK = 1;
}
//************************************************************
void write1302(unsigned char cmd,unsigned char T)
{
RST = 0;
SCLK = 0;
RST = 1;
writeTdata(cmd);
writeTdata(T);
RST = 0;
}
//************************************************************
unsigned char Readdata(void)
{
unsigned char i;

for( i = 0; i < 8; i )
{
Time7 = IO;
Time = Time >> 1;
SCLK = 0;
SCLK = 1;
}

SCLK = 1;
return Time;
}
//************************************************************
unsigned char Read1302(unsigned char m)
{
unsigned char Tdat;
RST = 0;
SCLK = 0;
RST = 1;
writeTdata(m);
Tdat = Readdata();
RST = 0;
return Tdat;
}
//************************************************************
void ReadTime(void)
{
unsigned char i;
unsigned char mde = 0x81;

for( i = 0; i < 7; i )
{
T[i] = Read1302(mde);
mde = 2;
}
}
//************************************************************
//void SetTime(void)
//{
//unsigned char i;
//unsigned char cmd = 0x80;

//write1302(0x8e,0x00);

//for( i = 0; i < 7; i )
//{
//write1302(cmd,0x03);
//cmd = 2;
//}

//write1302(0x8e,0x80);
//}
//************************************************************
void SetTimeSet(void)
{
write1302(0x80,0x30);
write1302(0x82,0x30);
write1302(0x84,0x00);
write1302(0x86,0x02);
write1302(0x88,0x05);
write1302(0x8a,0x03);
write1302(0x8c,0x55);
}
//************************************************************
main()
{
unsigned char m;
LCD_init();
//SetTime();
SetTimeSet();

while(1)
{
LED(Read1302(0x83));
}
}
//************************************************************

[/code]
我目前是想把資料讀出來然後顯示到LCD上,main後面的是單純測試,沒有啥意思,
我現在主要是想知道為何ReadTime那裡出不來,
一值在那裡循環,所以不解,想求大家找錯誤。

PS:順便附上DS1302的DATASHEET。
pdf1.alldatasheet.com/datasheet-pdf/view/58478/DALLAS/DS1302.html


編輯記錄
taishyang 重新編輯於 2009-09-01 17:34:58, 註解 分類成[問題]‧
現在想見妳 重新編輯於 2009-09-02 14:38:34, 註解 無‧
現在想見妳 重新編輯於 2009-09-02 15:10:21, 註解 無‧
現在想見妳 重新編輯於 2009-09-03 15:49:24, 註解 無‧
現在想見妳 重新編輯於 2009-09-03 15:56:47, 註解 無‧
現在想見妳 重新編輯於 2009-09-03 15:57:54, 註解 無‧
DavidLo
高階會員


發表:17
回覆:225
積分:168
註冊:2004-07-21

發送簡訊給我
#2 引用回覆 回覆 發表時間:2009-09-02 17:13:58 IP:61.228.xxx.xxx 訂閱
m要改為Local variable!
現在想見妳
一般會員


發表:3
回覆:11
積分:2
註冊:2009-08-20

發送簡訊給我
#3 引用回覆 回覆 發表時間:2009-09-03 15:54:46 IP:163.21.xxx.xxx 訂閱
感謝DAVIDLO,這個問題我也發現了,只是我現在是卡在好像不知道是沒有寫進去,
或是沒有讀出來,我想把設定的時間讀出來,
先顯示在LED上,但是我發現讀出來的數值一直都是0x00,
所以搞不清楚是寫入或是讀出的問題,想請教大家。

PS:順便問一下DATASHEET上,秒的bit7那ㄧ個CH是做啥用?
DavidLo
高階會員


發表:17
回覆:225
積分:168
註冊:2004-07-21

發送簡訊給我
#4 引用回覆 回覆 發表時間:2009-09-03 16:49:00 IP:61.228.xxx.xxx 訂閱
Good day!

readdata之前,先設定IO腳High!
  1. unsigned char Readdata(void)
  2. {
  3. unsigned char i;
  4. IO=1; <--- New add
  5. for( i = 0; i < 8; i )
  6. {
  7. Time7 = IO;
  8. Time = Time >> 1;
  9. SCLK = 0;
  10. SCLK = 1;
  11. }
  12. SCLK = 1;
  13. return Time;
  14. }
現在想見妳
一般會員


發表:3
回覆:11
積分:2
註冊:2009-08-20

發送簡訊給我
#5 引用回覆 回覆 發表時間:2009-09-03 16:58:46 IP:163.21.xxx.xxx 訂閱
改完以後燒入進去,讀出來的資料還是一樣0x00,
沒有改變。

順便問一下為啥IO要設成1?
DavidLo
高階會員


發表:17
回覆:225
積分:168
註冊:2004-07-21

發送簡訊給我
#6 引用回覆 回覆 發表時間:2009-09-03 17:06:51 IP:61.228.xxx.xxx 訂閱


IO 設定 HIGH ,才能讀到DS1302的輸出.

Why #define Time ACC ???

現在想見妳
一般會員


發表:3
回覆:11
積分:2
註冊:2009-08-20

發送簡訊給我
#7 引用回覆 回覆 發表時間:2009-09-03 17:09:06 IP:163.21.xxx.xxx 訂閱
喔,原來要設定成1才能讀輸入喔,可是我現在燒錄以後還是一樣讀不到或是沒寫進去,
定義那樣是因為我不想用ACC這個名稱,單純是這樣而已。
DavidLo
高階會員


發表:17
回覆:225
積分:168
註冊:2004-07-21

發送簡訊給我
#8 引用回覆 回覆 發表時間:2009-09-03 17:15:39 IP:61.228.xxx.xxx 訂閱
C程式中,最好不要直接使用ACC暫存器!Unless...expert!

bdata unsigned char Time=0;
sbit Time7 =Time^0;
sbit Time0 =Time^1;
...
現在想見妳
一般會員


發表:3
回覆:11
積分:2
註冊:2009-08-20

發送簡訊給我
#9 引用回覆 回覆 發表時間:2009-09-03 17:22:59 IP:163.21.xxx.xxx 訂閱
sbit   Time7    =Time^0;
sbit Time0 =Time^1;

上面這是對的嗎?
第一個應該是Time︿7;第二個應該是Time︿0;

我改完以後,情況還是一樣。

PS:可以問一下聯絡的即時通或是MSN?!不然在這互回好像怪怪的。
編輯記錄
現在想見妳 重新編輯於 2009-09-03 17:29:34, 註解 無‧
DavidLo
高階會員


發表:17
回覆:225
積分:168
註冊:2004-07-21

發送簡訊給我
#10 引用回覆 回覆 發表時間:2009-09-03 21:13:02 IP:218.169.xxx.xxx 訂閱

稍為看一下DS1302 Spec,你的SCLK時序不太對!
Read/Write皆為上緣觸發鎖定.
現在想見妳
一般會員


發表:3
回覆:11
積分:2
註冊:2009-08-20

發送簡訊給我
#11 引用回覆 回覆 發表時間:2009-09-03 23:07:27 IP:114.44.xxx.xxx 訂閱
可是我看裡面,讀的動作,SCLK是正緣寫入命令,負緣讀出資料,
寫的動作是正緣,不是這樣嗎?
我搞反了嗎?
DavidLo
高階會員


發表:17
回覆:225
積分:168
註冊:2004-07-21

發送簡訊給我
#12 引用回覆 回覆 發表時間:2009-09-04 14:23:23 IP:61.228.xxx.xxx 訂閱
這個IC DS1302我沒玩過! 試 試 看!
我沒有看到CE(chip enable)腳訊號控制?讀寫時CE要High!
但有看到RSTHigh/Low一下!
  1. unsigned char Readdata(void)
  2. {
  3. unsigned char i;
  4. CE=1; IO=1;
  5. for( i = 0; i < 8; i )
  6. {
    • SCLK = 0;
    • SCLK = 1;
    • Time7 = IO;
    • Time = Time >> 1;
    • }
    • CE=0;
    • SCLK = 0;
    • return Time;
    • }
現在想見妳
一般會員


發表:3
回覆:11
積分:2
註冊:2009-08-20

發送簡訊給我
#13 引用回覆 回覆 發表時間:2009-09-04 15:37:35 IP:163.21.xxx.xxx 訂閱
我想CE的這隻腳應該就跟RST這隻腳是一樣的,因為做這個IC的廠商,
我看過DATASHEET,有個是標CE,有的是RST,
我想應該都是控制訊號。
現在想見妳
一般會員


發表:3
回覆:11
積分:2
註冊:2009-08-20

發送簡訊給我
#14 引用回覆 回覆 發表時間:2009-09-08 14:39:12 IP:163.21.xxx.xxx 訂閱

[code cpp]
//************************************************************

//************************************************************
#include
#include "LCD.H"
sbit RST = P3^0;
sbit IO = P3^1;
sbit SCLK = P3^2;
bdata unsigned char Time=0;
sbit Time7 = Time^7;
sbit Time0 = Time^0;
//************************************************************
void writeRTCdata(unsigned char d);
void writeDS1302(unsigned char wAd,unsigned char dat);
void ProtectCode(int b);
unsigned char ReadRTCdata(void);
unsigned char ReadDS1302(unsigned char rAd);
void SetDS1302(void);
void LED(unsigned char L);
//************************************************************
void writeRTCdata(unsigned char d)
{
unsigned char i;
Time = d;
for( i = 0; i < 8; i )
{
IO = Time0;
Time = Time >> 1;
SCLK = 1;
SCLK = 0;
}
}
//************************************************************
void writeDS1302(unsigned char wAd,unsigned char dat)
{
RST = 0;
SCLK = 0;
IO = 1;
RST = 1;
writeRTCdata(wAd);
writeRTCdata(dat);
SCLK = 1;
RST = 0;
}
//************************************************************
void ProtectCode(int b)//0 禁止寫入 1 致能寫入
{
if( b )
{
writeDS1302(0x8e,0x00);
}
else
{
writeDS1302(0x8e,0x80);
}
}
//************************************************************
unsigned char ReadRTCdata(void)
{
unsigned char i;
Time = 0;
for( i = 0; i < 8; i )
{
Time7 = IO;
Time = Time >> 1;
SCLK = 1;
SCLK = 0;
}
return ( Time );
}
//************************************************************
unsigned char ReadDS1302(unsigned char rAd)
{
unsigned char T;
RST = 0;
SCLK = 0;
IO = 1;
RST = 1;
writeRTCdata(rAd);
T = ReadRTCdata();
SCLK = 1;
RST = 0;
return T;
}
//************************************************************
void SetDS1302(void)
{
unsigned char i,cmd = 0x80;
RST = 0;
SCLK = 0;
ProtectCode(1);
for( i = 0; i < 8; i )
{
writeDS1302(cmd,0x00);
cmd = 2;
}
ProtectCode(0);
}
//************************************************************
void LED(unsigned char L)
{
P0 = L;
//delay_10m(30);
}
//************************************************************
main()
{
LCD_init();
SetDS1302();
ProtectCode(1);
while(1)
{
LED(ReadDS1302(0x81));
}
}
//************************************************************
[/code]

不知道有沒有人碰過這顆IC,我現在還是一樣讀出來的數值還是0x00,
我有用示波器看過X1,X2,
電晶體是有震盪的,
所以不知道出問題在哪裡,希望有玩過這個IC的人幫忙一下。

編輯記錄
現在想見妳 重新編輯於 2009-09-09 17:48:41, 註解 無‧
ererer40
初階會員


發表:37
回覆:91
積分:45
註冊:2008-05-02

發送簡訊給我
#15 引用回覆 回覆 發表時間:2009-09-08 15:40:07 IP:60.248.xxx.xxx 訂閱
會不會是因為P0....

試試P1~P3
DavidLo
高階會員


發表:17
回覆:225
積分:168
註冊:2004-07-21

發送簡訊給我
#16 引用回覆 回覆 發表時間:2009-09-09 01:28:50 IP:218.169.xxx.xxx 訂閱
P0 need pull-high.
Also
  1. unsigned char ReadRTCdata(void)
  2. {
  3. unsigned char i;
  4. IO=1;
  5. for( i = 0; i < 8; i )
  6. {
  7. Time7 = IO;
  8. Time = Time >> 1;
  9. SCLK = 1;
  10. SCLK = 0;
  11. }
  12. return ( Time );
  13. }
Good Luck!

現在想見妳
一般會員


發表:3
回覆:11
積分:2
註冊:2009-08-20

發送簡訊給我
#17 引用回覆 回覆 發表時間:2009-09-09 18:29:09 IP:163.21.xxx.xxx 訂閱
現在好像已經可以讀出東西來了,可是又出現問題啦,
程式碼是用#14的,
我在MAIN裡面想說先讀看看秒的數值,
然後還是一樣先丟LED顯示,想說秒數顯示LED應該會很快的變化,
可是51上電源以後,發現沒有動靜,等了一下,
發現LED開始變化,然後繼續等,
發現原來一分鐘會變化一次,奇怪的是,我在MAIN裡讀取的命令明明就是0x81(SEC的讀取),
可是出來的卻是分鐘,而且分鐘的變化也很奇怪,我看了一下,把燈的變化列在下面,

7 6 5 4 3 2 1 0 LED
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 0 1 0
0 0 0 0 0 0 1 1
0 0 0 0 0 1 0 0
0 0 0 0 1 0 0 0
0 0 0 0 1 0 0 1
0 0 0 0 1 0 1 0
0 0 0 0 1 0 1 1
0 0 0 0 1 1 0 0
0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 1
0 0 0 1 0 0 1 0
0 0 0 1 0 0 1 1
0 0 0 1 0 1 0 0
0 0 0 1 1 0 0 0
0 0 0 1 1 0 0 1
0 0 0 1 1 0 1 0
0 0 0 1 1 0 1 1
0 0 0 1 1 1 0 0
0 0 1 0 0 0 0 0
0 0 1 0 0 0 0 1
之後應該是繼續重複了,所以先看到這,
希望大家一起來解決。

100到1000中間會停很久,567都沒有顯示出來,用LCD看也是一樣,
奇怪的是居然還會有ABC的燈號出現?!

編輯記錄
現在想見妳 重新編輯於 2009-09-10 10:46:58, 註解 無‧
現在想見妳 重新編輯於 2009-09-11 12:05:58, 註解 無‧
現在想見妳
一般會員


發表:3
回覆:11
積分:2
註冊:2009-08-20

發送簡訊給我
#18 引用回覆 回覆 發表時間:2009-09-11 16:58:02 IP:163.21.xxx.xxx 訂閱
我今天DS1302又有一點前進了,現在已經可以在LCD讀取到秒數的值了,
但是秒數的值跟正常時間有很大的落差,
我比對電路板上LCD的時間跟電腦上的時間,
當剛好都是00(秒)開始,以電路板上的數到59以後,
我看電腦的時間大約是數了80秒左右,
怎麼會落差這麼大阿,我現在是要修改硬體或是修改軟體。
ererer40
初階會員


發表:37
回覆:91
積分:45
註冊:2008-05-02

發送簡訊給我
#19 引用回覆 回覆 發表時間:2009-10-21 10:28:44 IP:60.248.xxx.xxx 訂閱
1.振盪器的頻率是否跟DATASHEET上寫的一樣
2.作動前三個腳設為H
3.防寫的WA要設為L,才有辦法執行寫入指令,寫完後要設回H,時間才不會錯亂
4.秒數暫存器的第7位要設為L才會開始計時
5.每執行完SCLK與RST,需等待一個時間 ( 好像是一個脈衝的樣子 )
我是用AVR控制的,也是搞很久才試出來,如果你看得懂DATASHEET會事半功倍,我查過對岸、日本、台灣網站上的範例,結果發現還是自已理解他的DATASHEET才是正確做法,直接拿別人寫的範例會比較省時,但如果不成功,較難查出原因
編輯記錄
ererer40 重新編輯於 2009-10-21 10:30:07, 註解 無‧
系統時間:2024-05-06 19:42:03
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!