[STM32F1] SD3078问题

[复制链接]
7912|17
 楼主| LianBinbing 发表于 2018-1-18 16:20 | 显示全部楼层 |阅读模式
sd, ic, iic, ck, ST
有人用过SD3078 IC做实时时钟吗?我这写了个程序,IIC读不到应答ACK,不知道是什么原因?求大神指教,有STM32F10x的例程就更好了,万分感谢!
mmuuss586 发表于 2018-1-18 18:00 | 显示全部楼层
没有呢;
模拟IIC好了;
为啥不选DS1302呢
jiekou001 发表于 2018-1-18 20:28 | 显示全部楼层
51的程序有,要不要
jiekou001 发表于 2018-1-18 20:29 | 显示全部楼层

  1. //************************************************************
  2. // 实时时钟SD30XX读写C51演示程序
  3. // AT89S52   11.0592MHz
  4. // E-mail:   FAE@whwave.com.cn
  5. // TEL:                 0755-83114387
  6. // Last update:                   2014/11/14
  7. //************************************************************

  8. #pragma code
  9. #include <reg51.h>
  10. #include <intrins.h>

  11. #define                RTC_Address                        0x64                //RTC器件地址
  12. #define                IDcode                                0x72                //8字节ID号起始地址
  13. #define                Bat_bit8                        0x1A                //电量最高位寄存器地址
  14. #define                Bat_Low8                        0x1B                //电量低八位寄存器地址

  15. #define                true                          1
  16. #define         false                         0

  17. //*********变量及IO口定义*********
  18. typedef unsigned char uchar;
  19. typedef unsigned int uint;

  20. sbit        SDA=P3^4;                
  21. sbit        SCL=P3^5;               

  22. uchar        Batbit8,Batlow7;        //电池电量寄存器值
  23. uint          Bat;                        //电池电量值
  24. uchar        Sram[8];                //通用数据缓存器
  25. uchar        data1[8];                //通用数据缓存器
  26. typedef        struct
  27. {
  28.         uchar         second;
  29.         uchar        minute;
  30.         uchar        hour;
  31.         uchar        week;
  32.         uchar        day;
  33.         uchar        month;
  34.         uchar        year;
  35. }S_Time;       

  36. S_Time  RTC={0x55,0x59,0x14,0x01,0x12,0x11,0x14};        //初始化时间结构体变量(设置时间:2014年11月12日 14:59:55  星期一)
  37. //           55秒 59分 14时 周一 10日 11月 14年
  38. /********SD30XX函数名********/
  39. uchar I2CReadOneByte(uchar DeviceAddress,uchar add);//读一字节
  40. bit I2CWriteOneByte(uchar DeviceAddress,uchar add, uchar date);//写一字节
  41. uchar I2CReadSerial(uchar DeviceAddress, uchar Address, uchar length,uchar *ps);//连续读
  42. uchar I2CWriteSerial(uchar DeviceAddress, uchar Address, uchar length,uchar *ps);//连续写
  43. bit I2CWriteDate(S_Time        SetRTC);//写时间       
  44. bit I2CReadDate(S_Time        *psRTC);//读时间
  45. bit        WriteTimeOn(void);//写允许
  46. bit        WriteTimeOff(void);//写禁止
  47. void Delay(uint nn);

  48. /*********I2C延时4us***********/
  49. void I2CWait(void)//4us
  50. {       
  51.         _nop_();_nop_();_nop_();_nop_();//AT89S52一个nop是1us
  52. }

  53. /********开启SD30XX的I2C总线********/
  54. bit I2CStart(void)
  55. {
  56.         SDA=1;
  57.         SCL=1;
  58.         I2CWait();
  59.         if(!SDA)return false;        //SDA线为低电平则总线忙,退出
  60.         SDA=0;
  61.         I2CWait();
  62.         while(SDA)return false;        //SDA线为高电平则总线出错,退出
  63.         SCL=0;
  64.         I2CWait();
  65.         return true;
  66. }

  67. /********关闭SD30XX的I2C总线*******/
  68. void I2CStop(void)
  69. {
  70.         SDA=0;
  71.         SCL=0;
  72.         I2CWait();
  73.         SCL=1;
  74.         I2CWait();
  75.         SDA=1;
  76. }

  77. /*********发送 ACK*********/
  78. void I2CAck(void)
  79. {       
  80.         SDA=0;
  81.         SCL=0;
  82.         I2CWait();
  83.         SCL=1;
  84.         I2CWait();
  85.         SCL=0;
  86. }

  87. /*********发送NO ACK*********/
  88. void I2CNoAck(void)
  89. {       
  90.         SDA=1;
  91.         SCL=0;
  92.         I2CWait();
  93.         SCL=1;
  94.         I2CWait();
  95.         SCL=0;
  96. }

  97. /*********读取ACK信号*********/
  98. bit I2CWaitAck(void)          //返回为:1=有ACK,0=无ACK
  99. {
  100.         SCL=0;
  101.         SDA=1;                //设置SDA为输入(其它类型的单片机需要配置IO输入输出寄存器)
  102.         I2CWait();
  103.         SCL=1;
  104.         I2CWait();
  105.         while(SDA)
  106.         {
  107.                 SCL=0;
  108.                 return false;
  109.         }
  110.         SCL=0;
  111.         return true;
  112. }

  113. /************MCU向SD30XX发送一个字节*************/
  114. void I2CSendByte(uchar demand) //数据从高位到低位//
  115. {
  116.         uchar i=8;                       
  117.                                         
  118.        
  119.         while(i--)
  120.         {
  121.                 SCL=0;
  122.                 _nop_();
  123.                 SDA=(bit)(demand&0x80);
  124.                 demand<<=1;
  125.                 I2CWait();
  126.                 SCL=1;
  127.                 I2CWait();
  128.         }
  129.         SCL=0;
  130. }

  131. /*********MCU从SD30XX读入一字节*********/
  132. uchar I2CReceiveByte(void)      //数据从高位到低位//
  133. {
  134.         uchar i=8;
  135.         uchar ddata=0;
  136.         SDA=1;                        //设置SDA为输入(其它类型的单片机需要配置IO输入输出寄存器)
  137.         while(i--)
  138.         {
  139.                 ddata<<=1;      //数据从高位开始读取
  140.                 SCL=0;
  141.                 I2CWait();
  142.                 SCL=1;
  143.                 I2CWait();        //从高位开始 ddata|=SDA;ddata<<=1
  144.                 if(SDA)
  145.                 {
  146.                         ddata|=0x01;
  147.                 }
  148.         }
  149.         SCL=0;
  150.         return ddata;
  151. }

  152. /******I2C写一个字节******/
  153. bit I2CWriteOneByte(uchar DeviceAddress,uchar add, uchar date)
  154. {               
  155.         if(!I2CStart())return false;
  156.         I2CSendByte(DeviceAddress);      
  157.         I2CWaitAck();   
  158.         I2CSendByte(add);                //设置写地址      
  159.         I2CWaitAck();       
  160.         I2CSendByte(date);                //写数据
  161.         I2CWaitAck();       
  162.         I2CStop();
  163.         return        true;
  164. }

  165. /******I2C读一个字节程序******/
  166. uchar I2CReadOneByte(uchar DeviceAddress,uchar add)
  167. {               
  168.         uchar dat;
  169.         if(!I2CStart())return false;
  170.         I2CSendByte(DeviceAddress);      
  171.         if(!I2CWaitAck()){I2CStop(); return false;}
  172.           I2CSendByte(add);                //设置要读的地址
  173.         I2CWaitAck();
  174.         I2CStart();       
  175.         I2CSendByte(DeviceAddress+1);       
  176.         I2CWaitAck();       
  177.         dat=I2CReceiveByte();                //读数据
  178.         I2CNoAck();
  179.         I2CStop();
  180.         return  dat;
  181. }

  182. /******写SD30XX允许程序******/
  183. bit WriteTimeOn(void)
  184. {               
  185.         if(!I2CWriteOneByte(RTC_Address,0x10,0x80))return false;
  186.         I2CWriteOneByte(RTC_Address,0x0f,0xff);
  187.         return        true;
  188. }

  189. /******写SD30XX禁止程序******/
  190. bit WriteTimeOff(void)
  191. {               
  192.         if(!I2CWriteOneByte(RTC_Address,0x0f,0x7b))return false;
  193.         I2CWriteOneByte(RTC_Address,0x10,0);
  194.         return        true;
  195. }

  196. /******读SD30XX实时数据寄存器******/
  197. bit I2CReadDate(S_Time        *psRTC)
  198. {
  199.        
  200.         if(!I2CStart())return false;
  201.         I2CSendByte(RTC_Address+1);
  202.             if(!I2CWaitAck()){I2CStop(); return false;}
  203.         psRTC->second=I2CReceiveByte();
  204.         I2CAck();
  205.         psRTC->minute=I2CReceiveByte();
  206.         I2CAck();
  207.         psRTC->hour=I2CReceiveByte();
  208.         I2CAck();
  209.         psRTC->week=I2CReceiveByte();
  210.         I2CAck();
  211.         psRTC->day=I2CReceiveByte();
  212.         I2CAck();
  213.         psRTC->month=I2CReceiveByte();
  214.         I2CAck();
  215.         psRTC->year=I2CReceiveByte();
  216.         I2CNoAck();                //读时间完成,发送NoAck
  217.         I2CStop();
  218.         return        true;
  219. }

  220. /******写SD30XX实时数据寄存器******/
  221. bit I2CWriteDate(S_Time        SetRTC)        //写时间操作要求一次对实时时间寄存器(00H~06H)依次写入,
  222. {                               //不可以单独对7个时间数据中的某一位进行写操作,否则可能会引起时间数据的错误进位.
  223.                                 //要修改其中某一个数据 , 应一次性写入全部 7 个实时时钟数据.
  224.         S_Time         *psRTC;
  225.             psRTC=&SetRTC;
  226.         WriteTimeOn();                                //使能,开锁
  227.         if(!I2CStart())return false;
  228.         I2CSendByte(RTC_Address);
  229.         if(!I2CWaitAck()){I2CStop(); return false;}
  230.         I2CSendByte(0x00);                        //设置写起始地址      
  231.         I2CWaitAck();       
  232.         I2CSendByte(psRTC->second);                //second     
  233.         I2CWaitAck();       
  234.         I2CSendByte(psRTC->minute);                //minute      
  235.         I2CWaitAck();       
  236.         I2CSendByte(psRTC->hour|0x80);                //hour ,同时设置小时寄存器最高位(0:为12小时制,1:为24小时制)
  237.         I2CWaitAck();       
  238.         I2CSendByte(psRTC->week);                //week      
  239.         I2CWaitAck();       
  240.         I2CSendByte(psRTC->day);                //day      
  241.         I2CWaitAck();       
  242.         I2CSendByte(psRTC->month);                //month      
  243.         I2CWaitAck();       
  244.         I2CSendByte(psRTC->year);                //year      
  245.         I2CWaitAck();       
  246.         I2CStop();
  247.        
  248.         WriteTimeOff();                                //使能,关锁
  249.         return        true;
  250. }


  251. /******设置SD30XX报警中断演示程序演示******/
  252. void WriteALARM(void)                                //设置报警时间:2015年2月14日 8:00
  253. {                                                //只有设置未来的时间才有效
  254.         WriteTimeOn();
  255.         I2CWriteOneByte(RTC_Address,0x09,0x08);        //8时
  256.         I2CWriteOneByte(RTC_Address,0x0b,0x14);        //14日
  257.         I2CWriteOneByte(RTC_Address,0x0c,0x02);        //02月
  258.         I2CWriteOneByte(RTC_Address,0x0d,0x15);        //15年
  259.         I2CWriteOneByte(RTC_Address,0x0e,0x74);        //设置报警允许(使能年、月、日、小时报警)
  260.         I2CWriteOneByte(RTC_Address,0x10,0x92);        //设置INT中断选通(INTS1,INTS0),及报警中断总允许位(INTAE)
  261.         WriteTimeOff();
  262. }

  263. /******关闭SD30XX报警中断程序******/
  264. void ClrALARM(void)                                //关闭报警中断
  265. {
  266.         WriteTimeOn();
  267.         I2CWriteOneByte(RTC_Address,0x10,0x90);
  268.         WriteTimeOff();
  269. }
  270. /******设置SD30XX倒计时中断演示******/
  271. void SetDjs(void)                                //设置倒计时中断
  272. {
  273.         WriteTimeOn();
  274.         I2CWriteOneByte(RTC_Address,0x10,0x0f);//先清倒计时中断总允许位(INTDE)
  275.         I2CWriteOneByte(RTC_Address,0x10,0xf4);//设置周期性中断(IM=1)INT中断选通(INTS1,INTS0),配置倒计时中断总允许位(INTDE)
  276.         I2CWriteOneByte(RTC_Address,0x11,0x30);//选择定时器频率源(TDS1、TDS0)为1/60HZ
  277.         I2CWriteOneByte(RTC_Address,0x13,0x05);//倒计时初值寄存器,设置8位倒计时计数初值(5min)
  278.         WriteTimeOff();
  279. }

  280. /******关闭SD30XX倒计时中断程序******/
  281. void ClrDjs(void)         
  282. {
  283.         WriteTimeOn();
  284.         I2CWriteOneByte(RTC_Address,0x10,0xf0);
  285.         WriteTimeOff();
  286. }
  287. /******设置SD30XX频率中断演示******/
  288. void SetFrq(void)                                       
  289. {
  290.         WriteTimeOn();
  291.         I2CWriteOneByte(RTC_Address,0x10,0xa1);        //选通频率中断(INTS1,INTS0),设置频率中断总允许位(INTFE)
  292.         I2CWriteOneByte(RTC_Address,0x11,0x09);        //设置2Hz频率中断
  293.         WriteTimeOff();
  294. }
  295. /******关闭SD30XX频率中断******/
  296. void ClrFrq(void)         
  297. {
  298.         WriteTimeOn();
  299.         I2CWriteOneByte(RTC_Address,0x10,0xa0);
  300.         WriteTimeOff();
  301. }
  302. //|************I2C连续读多个字节************|
  303. uchar I2CReadSerial(uchar DeviceAddress, uchar Address, uchar length,uchar *ps)
  304. {
  305.         uchar        i;
  306.         if(!I2CStart())return false;
  307.         I2CSendByte(DeviceAddress);      
  308.         if(!I2CWaitAck()){I2CStop(); return false;}
  309.           I2CSendByte(Address);                        //设置要读的地址
  310.         I2CWaitAck();
  311.         I2CStart();       
  312.         I2CSendByte(DeviceAddress+1);
  313.         I2CWaitAck();
  314.         for(i=0;i<length-1;i++,ps++)
  315.         {
  316.                 *ps=I2CReceiveByte();                //读数据
  317.                 I2CAck();
  318.         }
  319.         *ps=I2CReceiveByte();       
  320.         I2CNoAck();
  321.         I2CStop();
  322.         return        true;
  323. }

  324. //|******************I2C连续写多个字节******************|
  325. uchar I2CWriteSerial(uchar DeviceAddress, uchar Address, uchar length,uchar *ps)
  326. {
  327.         uchar        i;
  328.         if(!WriteTimeOn())return false;
  329.         if(!I2CStart())return false;
  330.         I2CSendByte(DeviceAddress);      //器件地址
  331.         if(!I2CWaitAck()){I2CStop(); return false;}
  332.           I2CSendByte(Address);                //设置起始地址
  333.         I2CWaitAck();
  334.         for(i=0;i<length;i++)
  335.         {
  336.                 I2CSendByte(*(ps++));               
  337.                 I2CAck();                                       
  338.         }
  339.         I2CStop();
  340.         WriteTimeOff();
  341.         return        true;
  342. }

  343. /*********延时子程序*********/
  344. void Delay2_5ms()      //延时2.5ms
  345. {
  346.         uchar        i=255;
  347.         while(i--);
  348. }

  349. void Delayms(uchar n)
  350. {
  351.         while(n--)
  352.                 Delay2_5ms();
  353. }
  354. //////*****主程序演示*****//////
  355. void main()
  356. {

  357.         I2CWriteDate(RTC);        //设置时间演示
  358. //        WriteALARM();            //设置报警中断时间演示
  359. //        SetDjs();                         //设置倒计时中断演示
  360.         SetFrq();                        //设置频率中断演示
  361.        
  362.         I2CReadSerial(RTC_Address,IDcode,8,Sram);                //读内部8字节ID号
  363.         I2CWriteSerial(RTC_Address,0x30,8,Sram);                //把内部8字节的ID号写入用户通用存储器的0x30-0x37地址
  364.        
  365.         I2CReadSerial(RTC_Address,0x30,8,data1);                //读从用户RAM寄存器把先前存入的ID号读出来(0x30-0x37地址)
  366.         Batbit8=I2CReadOneByte(RTC_Address,Bat_bit8);                //读SD30XX的电池电量最高位
  367.         Batlow7=I2CReadOneByte(RTC_Address,Bat_Low8);                //读SD30XX的电池电量低八位
  368.         Bat=(Batbit8>>7)*255+Batlow7;                                //计算电池电量值演示。如Bat=285则表示2.85V

  369.     while(1)
  370.         {
  371.                 I2CReadDate(&RTC);                //读时间演示
  372.                 Delayms(100);                        //延时250ms,1s读4次
  373.             }

  374. }
  375. //特别提醒:当写实时时间数据时 (00H~06H), 不可以单独 对 7 个时间数据中的某一位进行写操作 ,
  376. //否则可能会引起时间数据的错误进位 , 所以要修改其中某一个数据 , 应一次性写入全部 7 个实时时钟数据 .
jiekou001 发表于 2018-1-18 20:29 | 显示全部楼层
一会儿给你找找32的
jiekou001 发表于 2018-1-18 20:31 | 显示全部楼层
SD3088_STM32_demo.rar (400.63 KB, 下载次数: 99)



jiekou001 发表于 2018-1-18 20:32 | 显示全部楼层

     SD3078是一种具有标准IIC接口的实时时钟芯片,CPU可使用该接口通过7位地址寻址来读写片内122字节寄存器的数据(包括时间寄存器、报警寄存器、控制寄存器、用户SRAM寄存器及ID码寄存器)。
    SD3078内置晶振及数字温度计,用户可以不用顾虑因外接晶振、谐振电容等所带来的元件匹配误差问题、晶振温度特性问题及可靠性问题,实现在常温及宽温范围内不需用户干预、全自动、全电源环境补偿的高精度、高可靠计时功能。
           
主要性能特点:
l 低功耗: 0.8μA 典型值(VBAT =3.0V,Ta=25℃)。   
l 工作电压:2.7V~5.5V,工作温度为-40℃~+85℃。
l 标准IIC总线接口方式,最高速度400KHZ(4.5V~5.5V)。
l 年、月、日、星期、时、分、秒的BCD码输入/输出,并可通过独立的地址访问各时间寄存器。
l 闰年自动调整功能(从2000年~2099年)。
l 可选择12/24小时制式.
l 内置年、月、日、星期、时、分、秒共7字节的报警数据寄存器及1字节的报警允许寄存器,共有96种组合报警
   方式,并有单事件报警和周期性报警两种中断输出模式,报警时间最长可设至100年。
l 周期性频率中断输出:从4096Hz~1/16Hz……1秒共十四种方波脉冲.
l 自动重置的三字节共24位的倒计时定时器,可选的4种时钟源(4096HZ、1024HZ、1秒、1分钟),最小定时为244us,最长定时可到31年,通过计算可获得较精确的毫秒级定时值。
l 三种中断均可选择从INT脚输出,并具有两个中断标志位.
l 内置70字节通用SRAM寄存器可用于存储用户的一般数据。
l 具有可控的32768HZ方波输出脚F32K,可以位允许/禁止32K输出。
l 内置8bit转换结果的数字温度传感器,为了节省电池电量消耗,设为VDD模式下60S间隔测温一次,电池模式600S间隔测温一次。
l 内置晶振和谐振电容,芯片内部通过高精度补偿方法,实现在宽温范围内高精度的计时功能,其中25℃精度<±3.8ppm(即每月误差10S)。     
l 具有一次性或充电的后备电池输入脚VBAT ,其内部的3.3V稳压充电电路可选择性地对外接的充电电池进行自动充电,内置的充电限流电阻可位选2KΩ、5KΩ和10KΩ三种。
l 内置电池电压检测功能,可读取当前电池电压值(三位有效数),设置高低电池报警电压值并从INT脚输出中断。
l 芯片依据不同的电压自动从VDD切换到VBAT或从VBAT切换到VDD。当芯片检测到主电源VDD掉到2.4V电压以下且VDD小于VBAT,芯片会转为由接在VBAT的后备电池供电;当VDD大于VBAT或VDD大于2.4V,则芯片会转为由VDD供电。(内置电源模式指示位PMF,VDD模式时PMF=0,VBAT模式时PMF=1)。
l 内置8字节的ID码(OTP型),芯片出厂之前设定的、全球唯一的身份识别码。
l 内置IIC总线0.5秒自动复位功能(从Start命令开始计时),该功能可以避免IIC总线挂死问题。
l 内置三个时钟数据写保护位, 避免对数据的误写操作,可更好地保护数据。
l 内置软件可控VBAT模式IIC总线通信禁止功能(BATIIC=0,VBAT模式下禁止IIC通信;BATIIC=1,VBAT模式下允许IIC通信.上电默认值BATIIC=0),从而避免在电池供电时CPU对时钟操作所消耗的电池电量,也可避免在VDD上、下电的过程中因CPU的I/O端口所输出的不受控的杂波信号对时钟芯片的误写操作,进一步提高时钟芯片的可靠性。
l 内置上电指示位RTCF,当包括电池在内的所有电源第一次上电时该位置1。
l 内置电池电压欠压指示位BLF,当电池电压低于2.2V时BLF位置1。 
l 内置停振检测位OSF,当内部振荡器停止振荡时该位置1。 
l 芯片管脚抗静电(ESD)>2KV。
l 芯片在兴威帆的评估板上可通过4KV的群脉冲(EFT)干扰。
l CMOS 工艺
l 封装形式:SOP8(宽度208mil)。
jiekou001 发表于 2018-1-18 20:32 | 显示全部楼层
  1. //************************************************************
  2. // 实时时钟SD30XX读写STM8参考程序
  3. // MCU: STM8S103F3
  4. // Last update:              2017/7/19
  5. //************************************************************

  6. #include "stm8s103f3p.h"

  7. #define uchar unsigned char
  8. #define SCL_H  PC_ODR |= 0X08
  9. #define SDA_H  PA_ODR |= 0X08
  10. #define SCL_L  PC_ODR &= 0XF7
  11. #define SDA_L  PA_ODR &= 0XF7
  12. #define SDAM  ((PA_IDR & 0X08) >> 3)
  13. #define SET_SCL_OUT()    {PC_DDR |= 0X08; PC_CR1 |= 0X08; PC_CR2 &= 0XF7;}//scl选择管脚为PC3
  14. #define SET_SDA_OUT()    {PA_DDR |= 0X08; PA_CR1 |= 0X08; PA_CR2 &= 0XF7;}//sda选择管脚为PA3
  15. #define SET_SDA_IN()     {PA_DDR &= 0XF7; PA_CR1 &= 0XF7; PA_CR2 &= 0XF7;}//浮空输入

  16. uchar s_data[7] = {0};

  17. void GPIO_I2c_Master_Init(void)
  18. {
  19.   I2C_CR1 &= 0xFE;      
  20.   SET_SCL_OUT();    //PC3 输出;推挽;2MHz时钟;
  21.   SET_SDA_OUT();    //PA3 输出;推挽;2MHz时钟;
  22. }

  23. void Delay_5us(void)
  24. {
  25.   uchar i = 10;    //fcpu 16MHz

  26.   for (; i > 0; i--);
  27. }

  28. void I2C_Start(void)//起始信号
  29. {
  30.   SDA_H;                    
  31.   SCL_H;                    
  32.   Delay_5us();               
  33.   SDA_L;                  
  34.   Delay_5us();               
  35.   SCL_L;                    
  36. }

  37. void I2C_Stop(void)//结束信号
  38. {
  39.   SDA_L;                  
  40.   SCL_H;                  
  41.   Delay_5us();               
  42.   SDA_H;                  
  43.   Delay_5us();               
  44. }

  45. void I2C_SendACK(uchar ack)//应答或者非应答信号
  46. {
  47.   if (ack == 0)
  48.   {
  49.     SDA_L;
  50.   }
  51.   else
  52.   {
  53.     SDA_H;
  54.   }
  55.   SCL_H;                  
  56.   Delay_5us();  
  57.   
  58.   SCL_L;                    
  59.   Delay_5us();     
  60. }

  61. uchar I2C_SendByte(uchar sendDAT)//发送字节
  62. {
  63.   uchar i = 0;
  64.   uchar revack = 0;

  65.   for (i= 0 ; i< 8; i++)         
  66.   {
  67.     SCL_L;               
  68.     Delay_5us();  
  69.   
  70.     if (sendDAT & 0x80)  
  71.     {
  72.       SDA_H;
  73.     }
  74.     else  
  75.     {      
  76.       SDA_L;
  77.     }
  78.     sendDAT <<=  1;
  79.     SCL_H;               
  80.     Delay_5us();     
  81.   }
  82.   SCL_L;               
  83.   Delay_5us();  
  84.   SET_SDA_IN();
  85.   SCL_H;   
  86.   _asm("nop");
  87.   _asm("nop");
  88.   revack = (uchar)SDAM;
  89.   Delay_5us();   
  90.   SCL_L;   
  91.   SET_SDA_OUT();
  92.   Delay_5us();  

  93.   return revack;
  94. }

  95. uchar I2C_RecvByte(void)//接收字节
  96. {
  97.   uchar i = 0;
  98.   uchar revDAT = 0;
  99.   
  100.   SDA_H;  
  101.   SET_SDA_IN();
  102.   for (i = 0; i < 8; i++)         
  103.   {
  104.      revDAT <<= 1;      
  105.      SCL_H;
  106.      _asm("nop");
  107.      _asm("nop");
  108.      if (SDAM)
  109.      {
  110.         revDAT |= 0x01;
  111.      }
  112.      else
  113.      {
  114.         revDAT &= 0xfe;
  115.      }

  116.      Delay_5us();
  117.      SCL_L;               
  118.      Delay_5us();  
  119.   }   
  120.   SET_SDA_OUT();
  121.   
  122.   return revDAT;
  123. }

  124. void WriteOn(void)//打开写保护
  125. {
  126.   I2C_Start();
  127.   I2C_SendByte(0x64);
  128.   I2C_SendByte(0x10);
  129.   I2C_SendByte(0x80);
  130.   I2C_Stop();
  131.   
  132.   I2C_Start();
  133.   I2C_SendByte(0x64);
  134.   I2C_SendByte(0x0f);
  135.   I2C_SendByte(0x84);
  136.   I2C_Stop();
  137. }

  138. void WriteOff(void)//关闭写保护
  139. {
  140.   I2C_Start();
  141.   I2C_SendByte(0x64);
  142.   I2C_SendByte(0x10);
  143.   I2C_SendByte(0x00);
  144.   I2C_Stop();
  145.   
  146.   I2C_Start();
  147.   I2C_SendByte(0x64);
  148.   I2C_SendByte(0x0f);
  149.   I2C_SendByte(0x00);
  150.   I2C_Stop();
  151. }

  152. void read_time_from_sd30xx(void)//从sd30xx读时间
  153. {
  154.   uchar n = 0;

  155.   I2C_Start();
  156.   if (I2C_SendByte(0x65))
  157.   {
  158.     I2C_Stop();

  159.     return;
  160.   }
  161.   for (n = 0; n < 7; n++)
  162.   {
  163.     s_data[n] = I2C_RecvByte();
  164.     if (n == 6)
  165.     {
  166.       I2C_SendACK(1);
  167.     }
  168.     I2C_SendACK(0);
  169.   }
  170.   I2C_Stop();
  171. }



  172. void write_time_to_sd30xx(void)//写时间到sd30xx
  173. {
  174.   uchar n = 0;

  175.   WriteOn();
  176.   
  177.   I2C_Start();
  178.   I2C_SendByte(0x64);
  179.   I2C_SendByte(0x00);
  180.   for (n = 0; n < 7; n++)
  181.   {
  182.     I2C_SendByte(s_data[n]);
  183.   }
  184.   I2C_Stop();
  185.   
  186.   WriteOff();
  187. }
 楼主| LianBinbing 发表于 2018-1-19 08:33 | 显示全部楼层

谢谢!谢谢!真是太感谢了!
dsyq 发表于 2018-7-2 09:23 | 显示全部楼层
请教楼上各位,这个芯片稳定不稳定啊
DENGXUEYING 发表于 2019-4-15 16:31 | 显示全部楼层
有谁弄过STM32F030R8T6的的PCF8563实时时钟芯片的求分享代码
manufact 发表于 2019-4-15 21:44 | 显示全部楼层
用过PCF8563,还不错,比较好用
KloppGuo 发表于 2020-2-26 10:57 | 显示全部楼层
我现在是不明白 如何去调整时间?谁有这方面的历程可以参考下
归依龙井 发表于 2022-9-27 18:19 | 显示全部楼层
本帖最后由 归依龙井 于 2022-10-11 11:52 编辑

SD3077官网32例程说设置成推挽会有问题?有谁遇到过吗?
wenfen 发表于 2022-10-13 22:29 | 显示全部楼层
选DS1302
月亮一键变蓝 发表于 2022-10-15 19:57 | 显示全部楼层
读不到应答的话,你看硬件是否连接正确,然后再用逻辑分析仪抓一下波形吧

失物招領 发表于 2022-10-15 20:19 | 显示全部楼层
话说,这时钟IC好用不呢?正常都是用8010或者DS1302

温室雏菊 发表于 2022-10-15 20:41 | 显示全部楼层
如果对时钟要求精度不是很高,就用内置的RTC也是可以的

风凉 发表于 2022-10-15 21:03 | 显示全部楼层
你这个单片机采用的硬件I2CDS3078相连接的么?

捧一束彼岸花 发表于 2022-10-15 21:25 | 显示全部楼层
不是很建议使用STM32F1的硬件I2C哈,听说不是很稳

您需要登录后才可以回帖 登录 | 注册

本版积分规则

30

主题

129

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部