找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 3402|回復(fù): 16
打印 上一主題 下一主題
收起左側(cè)

關(guān)于時(shí)鐘芯片SD3078單片機(jī)驅(qū)動(dòng)的問(wèn)題 [已解決] 及解決方法

[復(fù)制鏈接]
回帖獎(jiǎng)勵(lì) 100 黑幣 回復(fù)本帖可獲得 5 黑幣獎(jiǎng)勵(lì)! 每人限 2 次
跳轉(zhuǎn)到指定樓層
樓主
最近在做手表,感覺(jué)大部分常見(jiàn)RTC要么太大,要么沒(méi)內(nèi)置晶振(誤差大)
前幾周找到了一款芯片,看上去還不錯(cuò):

我就在某寶上買了2片,嘗試驅(qū)動(dòng)
這玩意老貴了,一片就要五塊多
數(shù)據(jù)手冊(cè) SD3078.pdf (858.22 KB, 下載次數(shù): 19)
我按照數(shù)據(jù)手冊(cè)寫(xiě)的驅(qū)動(dòng):
  1. //SD3078.c
  2. //I2C功能O口:準(zhǔn)雙向
  3. #include "STC8H.h"
  4. #include "SD3078.h"
  5. #include "IIC.h"
  6. //#include "UART.c"

  7. #define RTC_READ 0x65
  8. #define RTC_WRITE 0x64

  9. void Rtc_Enable(){        
  10.         IIC_Start(); //發(fā)送起始命令
  11.         IIC_Send(RTC_WRITE); //發(fā)送設(shè)備地址+寫(xiě)命令
  12.         IIC_Ack();
  13.         IIC_Send(0x10); //發(fā)送地址
  14.         IIC_Ack();
  15.         IIC_Send(0x80); //發(fā)送數(shù)據(jù)
  16.         IIC_Ack();
  17.         IIC_Stop(); //發(fā)送停止命令

  18.         IIC_Start(); //發(fā)送起始命令
  19.         IIC_Send(RTC_WRITE); //發(fā)送設(shè)備地址+寫(xiě)命令
  20.         IIC_Ack();
  21.         IIC_Send(0x0F); //發(fā)送地址
  22.         IIC_Ack();
  23.         IIC_Send(0x84); //發(fā)送數(shù)據(jù)
  24.         IIC_Ack();
  25.         IIC_Stop();
  26. }        
  27. void Rtc_Disable(){        
  28.         IIC_Start(); //發(fā)送起始命令
  29.         IIC_Send(RTC_WRITE); //發(fā)送設(shè)備地址+寫(xiě)命令
  30.         IIC_Ack();
  31.         IIC_Send(0x0F); //發(fā)送地址
  32.         IIC_Ack();
  33.         IIC_Send(0x00);
  34.         IIC_Ack();
  35.         IIC_Send(0x00);
  36.         IIC_Ack();
  37.         IIC_Stop();
  38. }        

  39. void Rtc_Write_Time(unsigned char TIME_Set[],bit mode,bit A_P_M){//TIME_Set:秒分時(shí)周日月年  mode1:24h mode0:12h  IN:十進(jìn)制數(shù)
  40.         
  41.         unsigned char i;
  42.         
  43.         for(i=0;i<7;i++){
  44.                 TIME_Set[i]=TIME_Set[i]/10*16+TIME_Set[i]%10;
  45.         }
  46.         if(mode)
  47.                 TIME_Set[2]|=0x80;
  48.         else{
  49.                 if(A_P_M)//AM
  50.                         TIME_Set[2]&=0x5f;
  51.                 else{//PM
  52.                         TIME_Set[2]&=0x7f;
  53.                         TIME_Set[2]|=0x20;
  54.                 }
  55.         }
  56.         IIC_Start(); //發(fā)送起始命令
  57.         IIC_Send(RTC_WRITE); //發(fā)送設(shè)備地址+寫(xiě)命令
  58.         IIC_Ack();
  59.         IIC_Send(0x00);
  60.         IIC_Ack();
  61.         for(i=0;i<7;i++){
  62.                 IIC_Send(TIME_Set[i]);
  63.                 IIC_Ack();
  64.         }
  65.         IIC_Stop();
  66.         
  67. }

  68. void Rtc_Read_Time(TIME_IN *TIME_Read){
  69.         IIC_Regulate(1);
  70.         IIC_Start();
  71.         IIC_Send(RTC_READ);
  72.         IIC_Ack();
  73.         TIME_Read -> second=IIC_Recv();
  74.         IIC_Send_Ack();
  75.         TIME_Read -> minute=IIC_Recv();
  76.         IIC_Send_Ack();
  77.         TIME_Read -> hour=IIC_Recv();
  78.         IIC_Send_Ack();
  79.         TIME_Read -> week=IIC_Recv();
  80.         IIC_Send_Ack();
  81.         TIME_Read -> date=IIC_Recv();
  82.         IIC_Send_Ack();
  83.         TIME_Read -> month=IIC_Recv();
  84.         IIC_Send_Ack();
  85.         TIME_Read -> year=IIC_Recv();
  86.         IIC_Send_Ack();
  87.         IIC_Stop();
  88. }

  89. void SD3078_Init(){
  90.         unsigned char r;
  91.         IIC_Regulate(1);
  92.         Rtc_Enable();//關(guān)寫(xiě)保護(hù)
  93.         IIC_Start();
  94.         IIC_Send(RTC_WRITE);
  95.         IIC_Ack();
  96.         IIC_Send(0x0F);
  97.         IIC_Ack();
  98.         IIC_Start();
  99.         IIC_Send(RTC_READ);
  100.         IIC_Ack();
  101.         r=IIC_Recv();
  102.         IIC_Send_Ack();
  103.         IIC_Stop();
  104.         if(r&0x01){//第一次上電
  105.                 Rtc_Write_Time(TIME_SET,1,0);
  106.         }
  107.         Rtc_Disable();//開(kāi)寫(xiě)保護(hù)
  108. }

  109. void main(){
  110.         
  111.         unsigned char i, j, k;
  112.         
  113.          P0M0 = 0x00;
  114.    P0M1 = 0x00;
  115.    P1M0 = 0x00;
  116.    P1M1 = 0x00;
  117.    P2M0 = 0x00;
  118.    P2M1 = 0x00;
  119.    P3M0 = 0x00;
  120.    P3M1 = 0x00;
  121.    P4M0 = 0x00;
  122.    P4M1 = 0x00;
  123.    P5M0 = 0x00;
  124.    P5M1 = 0x00;
  125.         
  126.         IIC_Init();
  127.         SD3078_Init();
  128.         

  129.         while(1){
  130.                
  131.                 Rtc_Read_Time(&Sys_Time);
  132.                 if(Sys_Time.second==1)P0=0;else P0=1;
  133.                
  134.                 i = 13;
  135.         j = 45;
  136.         k = 214;
  137.         do
  138.         {
  139.                 do
  140.                 {
  141.                         while (--k);
  142.                 } while (--j);
  143.         } while (--i);
  144.         }

  145. }
復(fù)制代碼
.h文件
  1. #ifndef _SD3078_H_
  2. #define _SD3078_H_

  3. typedef struct{
  4.         unsigned char year;
  5.         unsigned char month;
  6.         unsigned char date;
  7.         unsigned char hour;
  8.         unsigned char minute;
  9.         unsigned char second;
  10.         unsigned char week;
  11. }TIME_IN;

  12. TIME_IN Sys_Time;

  13. unsigned char TIME_SET[7]={0,0,0,2,18,7,23};//秒分時(shí)周日月年



  14. #endif
復(fù)制代碼
燒錄后,單片機(jī)似乎死循環(huán)了(似乎是IIC通訊失敗,但I(xiàn)IC的代碼驅(qū)動(dòng)其他器件是正常的),
排查了幾天都不知原因
有哪位大神幫我改改嗎
-----------------------------------------------------------------------------
7月25日:

跟著數(shù)據(jù)手冊(cè)重寫(xiě)了一遍代碼,經(jīng)過(guò)一些微調(diào),SD3078被驅(qū)動(dòng)起來(lái)了。(dòng))
我對(duì)比了一下上面的(有問(wèn)題)代碼,并結(jié)合微調(diào)時(shí)的經(jīng)過(guò),總結(jié)出了上方代碼的問(wèn)題:
1、讀出的數(shù)據(jù)是BCD碼,很重要。ú皇鞘M(jìn)制)
2、 24小時(shí)制時(shí)讀出數(shù)據(jù)時(shí)要把最高位置零(&0x7f),否則讀出數(shù)據(jù)是錯(cuò)誤的···
3、IIC的應(yīng)答要設(shè)定一個(gè)時(shí)間上限,超過(guò)上限就跳出循環(huán),判非應(yīng)答。(方便調(diào)試)
4、好像沒(méi)有了···
另外,我用的單片機(jī)是STC8H8K64U,使用了硬件IIC,請(qǐng)問(wèn)大佬們不加上拉電阻保險(xiǎn)嗎?
(我試著去除上拉電阻,結(jié)果單片機(jī)與SD3078通訊仍正常)

----------------------------------------------------完----------------------------------------------------


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂1 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:401564 發(fā)表于 2023-7-21 12:32 | 只看該作者
1,先驗(yàn)證IIC代碼對(duì)不對(duì),可能用24C01的IIC代碼和功能來(lái)進(jìn)行驗(yàn)證
2,先驗(yàn)證IIC從機(jī)地址對(duì)不對(duì),先不管數(shù)據(jù)讀寫(xiě),先寫(xiě)一個(gè)驗(yàn)證代碼,向從機(jī)發(fā)送地址,看一下有沒(méi)有響應(yīng),可以用一個(gè)LED或者某個(gè)端口的電平來(lái)進(jìn)行驗(yàn)證
3,如果單片機(jī)沒(méi)有內(nèi)置上拉電阻,你就得在時(shí)鐘和數(shù)據(jù)端口上增加上拉電阻
回復(fù)

使用道具 舉報(bào)

板凳
ID:639106 發(fā)表于 2023-7-21 12:56 | 只看該作者
Y_G_G 發(fā)表于 2023-7-21 12:32
1,先驗(yàn)證IIC代碼對(duì)不對(duì),可能用24C01的IIC代碼和功能來(lái)進(jìn)行驗(yàn)證
2,先驗(yàn)證IIC從機(jī)地址對(duì)不對(duì),先不管數(shù)據(jù)讀寫(xiě) ...

單片機(jī)引腳設(shè)置為準(zhǔn)雙向輸出,可以嗎
回復(fù)

使用道具 舉報(bào)

地板
ID:161164 發(fā)表于 2023-7-21 14:54 | 只看該作者
注意電平轉(zhuǎn)換時(shí)間


回復(fù)

使用道具 舉報(bào)

5#
ID:639106 發(fā)表于 2023-7-21 18:58 | 只看該作者
lkc8210 發(fā)表于 2023-7-21 14:54
注意電平轉(zhuǎn)換時(shí)間

時(shí)序按照數(shù)據(jù)手冊(cè)寫(xiě)的,為400k,我把它調(diào)到200k后也沒(méi)反應(yīng)
回復(fù)

使用道具 舉報(bào)

6#
ID:401564 發(fā)表于 2023-7-21 22:05 | 只看該作者
gqzjl 發(fā)表于 2023-7-21 12:56
單片機(jī)引腳設(shè)置為準(zhǔn)雙向輸出,可以嗎

時(shí)鐘和數(shù)據(jù)線必須要加10K的上拉電阻!!!!!
端口設(shè)置為標(biāo)準(zhǔn)雙向模式,也就是傳統(tǒng)的8051模式
回復(fù)

使用道具 舉報(bào)

7#
ID:1085441 發(fā)表于 2023-7-21 22:08 | 只看該作者
gqzjl 發(fā)表于 2023-7-21 12:56
單片機(jī)引腳設(shè)置為準(zhǔn)雙向輸出,可以嗎

看手冊(cè)是有上拉電阻的,你可以接個(gè)上拉電阻試試。
像DS1302的IO口必須接上拉電阻,準(zhǔn)雙向IO口不行。
回復(fù)

使用道具 舉報(bào)

8#
ID:883308 發(fā)表于 2023-7-22 01:49 | 只看該作者
可以看看數(shù)據(jù)手冊(cè)多試試
回復(fù)

使用道具 舉報(bào)

9#
ID:639106 發(fā)表于 2023-7-22 12:03 | 只看該作者
設(shè)置成開(kāi)漏輸出,SDA接了上拉電阻后還是沒(méi)反應(yīng)
是我寫(xiě)的驅(qū)動(dòng)有問(wèn)題嗎
回復(fù)

使用道具 舉報(bào)

10#
ID:384109 發(fā)表于 2023-7-22 13:04 | 只看該作者
看代碼,P0需要至少1分鐘才會(huì)有變化,測(cè)試時(shí)間夠長(zhǎng)嗎
回復(fù)

使用道具 舉報(bào)

11#
ID:639106 發(fā)表于 2023-7-22 14:07 | 只看該作者
夠長(zhǎng),把if判斷的值改成<20也一樣要瘋了
回復(fù)

使用道具 舉報(bào)

12#
ID:401564 發(fā)表于 2023-7-22 17:13 | 只看該作者
gqzjl 發(fā)表于 2023-7-22 12:03
設(shè)置成開(kāi)漏輸出,SDA接了上拉電阻后還是沒(méi)反應(yīng)
是我寫(xiě)的驅(qū)動(dòng)有問(wèn)題嗎

已經(jīng)告訴你了,你上傳的代碼中,你的端口設(shè)置是對(duì)的,就不要再去找端口的毛病了
SDA和SCL都要加上拉10K電阻!!!!!!!
IIC可以驅(qū)動(dòng)其它的IIC器件也不一定是對(duì)的!!!!!
為什么要叫你用24c01,這個(gè)器件是標(biāo)準(zhǔn)的IIC,不支持高速IIC的,在它上面運(yùn)行正常了,在SD3078就能正常了
不要duang!duang!duang!先寫(xiě)一堆幾千行的代碼,然后就進(jìn)行驗(yàn)證,那么多代碼,問(wèn)題出在哪里你都不一定知道

"先驗(yàn)證IIC從機(jī)地址對(duì)不對(duì),先不管數(shù)據(jù)讀寫(xiě),先寫(xiě)一個(gè)驗(yàn)證代碼,向從機(jī)發(fā)送地址,看一下有沒(méi)有響應(yīng),可以用一個(gè)LED或者某個(gè)端口的電平來(lái)進(jìn)行驗(yàn)證"
1,什么其它的代碼都不要,只要端口設(shè)置和IIC寫(xiě)入一個(gè)字節(jié)函數(shù),外加一個(gè)延時(shí)函數(shù),延時(shí)可以設(shè)定為1秒2,P0^1=0;//LED這個(gè)端口先滅燈
3,寫(xiě)入從機(jī)地址   0x64
4,等待IIC從機(jī)應(yīng)答,如果不應(yīng)答就是死循環(huán)
5,P0^1 = 1;//

while(1);
6,燒錄驗(yàn)證,不要仿真!!!!!!!!!

以上6步,從P.01端口的電平信號(hào)就可以知道從機(jī)是否能響應(yīng)主機(jī)的IIC信號(hào)了
低電平:說(shuō)明從機(jī)沒(méi)有應(yīng)答
高電平:說(shuō)明從機(jī)已經(jīng)應(yīng)答,寫(xiě)字節(jié)的IIC代碼是對(duì)的

再不行,把你的所有代碼,原理圖上傳
還是不行,那就放棄吧

評(píng)分

參與人數(shù) 1黑幣 +5 收起 理由
gqzjl + 5 贊一個(gè)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

13#
ID:639106 發(fā)表于 2023-7-22 17:35 | 只看該作者
Y_G_G 發(fā)表于 2023-7-22 17:13
已經(jīng)告訴你了,你上傳的代碼中,你的端口設(shè)置是對(duì)的,就不要再去找端口的毛病了
SDA和SCL都要加上拉10K電阻 ...

好的,我試試
回復(fù)

使用道具 舉報(bào)

14#
ID:821429 發(fā)表于 2023-7-23 16:42 | 只看該作者
if(Sys_Time.second==1)P0=0;else P0=1;    恰好能讀到1嗎?如果0秒后延時(shí),2秒時(shí)才把時(shí)間讀回來(lái),是不是就沒(méi)有反應(yīng)了?這個(gè)看你的延時(shí)多長(zhǎng)時(shí)間,按照12MHz1T估算你的延時(shí),應(yīng)該還是很多時(shí)候能進(jìn)入的,但是也容易出現(xiàn)非預(yù)期的情況。
這條語(yǔ)句的第二個(gè)問(wèn)題,如果延時(shí)不影響,當(dāng)且僅當(dāng)second==1時(shí)點(diǎn)亮/熄滅,也就是60秒鐘點(diǎn)亮/滅1秒,這個(gè)是你預(yù)期的效果?我覺(jué)得不確定能不能看清楚這個(gè)閃爍
關(guān)于調(diào)試的方法,你是怎么感覺(jué)進(jìn)入死循環(huán)的,是測(cè)試出來(lái)的嗎?如果不是必須定位,找到出錯(cuò)點(diǎn),因?yàn)椴荒茉诰調(diào)試,可以注釋現(xiàn)在點(diǎn)亮指示燈的位置,在你覺(jué)得可疑的程序后面點(diǎn)亮指示燈,如果能點(diǎn)亮繼續(xù)找前面的程序。

評(píng)分

參與人數(shù) 1黑幣 +5 收起 理由
gqzjl + 5

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

15#
ID:584814 發(fā)表于 2023-7-24 11:13 | 只看該作者
先找個(gè)任意的IIC器件,調(diào)試成功后再上這個(gè)東東。
目前,標(biāo)準(zhǔn)的IIC驅(qū)動(dòng)是通用的,RTC也就是讀寫(xiě)而已,沒(méi)多復(fù)雜,好像3231和1307的通用。
實(shí)驗(yàn)證明很多器件用STC準(zhǔn)雙向I/O無(wú)需加上拉什么的也可以用。
也可以找廠家要DEMO,國(guó)產(chǎn)可參考“國(guó)芯”,說(shuō)明書(shū)寫(xiě)的是理想也可能是現(xiàn)實(shí)。
包括記得有些廠家宣傳可以免費(fèi)給樣片,然而聯(lián)系過(guò)結(jié)果呵呵呵。
如果自己玩且對(duì)體積沒(méi)要求的話用8025的,幾毛錢的貨就非常好用。
還有就是,目前常見(jiàn)的8025、3231又大又蠢,甚至還有更過(guò)的內(nèi)置了電池,這個(gè)小體積的有“核心技術(shù)”了 ?
建議仔細(xì)查一遍,廠家不給例程自己還調(diào)不過(guò)就過(guò)了罷。

評(píng)分

參與人數(shù) 1黑幣 +5 收起 理由
gqzjl + 5 贊一個(gè)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

16#
ID:639106 發(fā)表于 2023-7-25 19:07 | 只看該作者
liixaofei5 發(fā)表于 2023-7-23 16:42
if(Sys_Time.second==1)P0=0;else P0=1;    恰好能讀到1嗎?如果0秒后延時(shí),2秒時(shí)才把時(shí)間讀回來(lái),是不是就 ...

謝謝指導(dǎo),問(wèn)題解決了
回復(fù)

使用道具 舉報(bào)

17#
ID:639106 發(fā)表于 2023-7-25 19:09 | 只看該作者
man1234567 發(fā)表于 2023-7-24 11:13
先找個(gè)任意的IIC器件,調(diào)試成功后再上這個(gè)東東。
目前,標(biāo)準(zhǔn)的IIC驅(qū)動(dòng)是通用的,RTC也就是讀寫(xiě)而已,沒(méi)多 ...

謝謝指導(dǎo),之前寫(xiě)的程序確實(shí)有忽疏
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表