找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4224|回复: 0
收起左侧

关于DS1307时钟芯片的读写问题

[复制链接]
ID:357775 发表于 2018-6-24 14:29 | 显示全部楼层 |阅读模式
使用STC的15W系列单片机对DS1307进行时间的读写,读出来的数据全是00,求高手指点,代码如下:
  1. #define         MAIN_Fosc                        12000000L        //定义主时钟
  2. #include        "STC15Fxxxx.H"

  3. #define                Baudrate1                                        9600L
  4. #define         CNT_END                                         12000
  5. #define         DS1307_ADDR                         0xD0

  6. sbit WARNING=P3^3;

  7. sbit I2C_SCL=P5^5;                     //时钟信号引脚定义
  8. sbit I2C_SDA=P5^4;                     //数据信号引脚定义

  9. //sbit I2C_SCL=P1^6;                     //时钟信号引脚定义
  10. //sbit I2C_SDA=P1^7;                     //数据信号引脚定义
  11. u8 B_TX1_Busy=0;
  12. u8 Send_Buff[16];
  13. u8 DS1307_Data[7]={0};                                                //数据读出缓存
  14. u8 DS1307_Buff[7]={0,57,13,7,27,5,18};        //数据写入缓存
  15. u8 i;
  16. u16 cnt=0;
  17. bit temp_flag=0;
  18. void        UART1_Config_withT2(u16 dat);        // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
  19. void delay_ms(u8 ms);
  20. void DelayXus(u8 n);

  21. void Send_I2C_Byte(u8 txd);
  22. u8 Receive_I2C(void);
  23. u8 read_byte(u8 add);
  24. void write_byte(u8 add,u8 dat);
  25. void SendByte(u8 dat);
  26. void Read_RTC(u8 *p);
  27. void Set_RTC(u8 *p);



  28. //========================================================================
  29. // 函数: void main(void)
  30. // 描述: 主函数
  31. //========================================================================
  32. void main(void)
  33. {
  34.         P1M1 = 0;        P1M0 = 1;        //设置为准双向口
  35.         P3M1 = 0;        P3M0 = 1;        //设置为准双向口
  36.         P5M1 = 0;        P5M0 = 0;        //设置为准双向口
  37.         WARNING=0;
  38.         I2C_SCL=1;
  39.         I2C_SDA=1;
  40.         UART1_Config_withT2(2);
  41.         EA=1;
  42.        

  43.                 Set_RTC(DS1307_Buff);                //设置时间
  44.        
  45. //向其他寄存器写入数据
  46.                 write_byte(0x09,0xF1);

  47.        
  48.         while (1)
  49.         {
  50.                
  51.                
  52.                 delay_ms(200);
  53.                 delay_ms(200);
  54.                 delay_ms(200);
  55.                 delay_ms(200);
  56.                 delay_ms(200);
  57.                 SendByte(read_byte(0x09));

  58.                 //读取时间测试
  59.                 Read_RTC(DS1307_Data);                //读取时间
  60.                 for(i=0;i<7;i++)                                        //读取时间并用串口发送
  61.                 {
  62.                         SendByte(DS1307_Data[i]);               
  63.                 }
  64.                 SendByte(read_byte(0x09));
  65.         }
  66. }


  67. //========================================================================
  68. // 描述: 设置Timer2做波特率发生器。
  69. // 参数: dat: Timer2的重装值.
  70. //========================================================================
  71. void        UART1_Config_withT2(u16 dat)        // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
  72. {
  73.         AUXR |= 0x01;                        //S1 BRT Use Timer2;
  74.         AUXR &= ~(1<<4);        //Timer stop
  75.         AUXR &= ~(1<<3);        //Timer2 set As Timer
  76.         AUXR |=  (1<<2);        //Timer2 set as 1T mode
  77.         TH2 = dat / 256;
  78.         TL2 = dat % 256;
  79.         IE2  &= ~(1<<2);        //禁止中断
  80.         AUXR |=  (1<<4);        //Timer run enable
  81.        
  82.         SCON = (SCON & 0x3f) | 0x40;        //UART1模式, 0x00: 同步移位输出, 0x40: 8位数据,可变波特率, 0x80: 9位数据,固定波特率, 0xc0: 9位数据,可变波特率
  83. //        PS  = 1;        //高优先级中断
  84.         ES  = 1;        //允许中断
  85.         REN = 1;        //允许接收
  86.         P_SW1 &= 0x3f;
  87.         P_SW1 |= 0x00;                //UART1 switch to, 0x00: P3.0 P3.1, 0x40: P3.6 P3.7, 0x80: P1.6 P1.7 (必须使用内部时钟)
  88. //        PCON2 |=  (1<<4);        //内部短路RXD与TXD, 做中继, ENABLE,DISABLE

  89.         B_TX1_Busy = 0;
  90. }

  91. /*--------------------------------延时相关函数--------------------------------*/
  92. void  delay_ms(u8 ms)
  93. {
  94.      unsigned int i;
  95.          do{
  96.               i = MAIN_Fosc / 13000;
  97.                   while(--i)        ;   //14T per loop
  98.      }while(--ms);
  99. }
  100. /**************************************
  101. 延时X微秒(@12M)
  102. 不同的工作环境,需要调整此函数
  103. 此延时函数是使用1T的指令周期进行计算,与传统的12T的MCU不同
  104. **************************************/
  105. void DelayXus(u8 n)
  106. {
  107.         while (n--)
  108.         {
  109.                 _nop_();
  110.                 _nop_();
  111.         }
  112. }

  113. /*-------------------------------IIC通信相关函数-----------------------------------*/

  114. void Start_I2C()                  //启动IIC
  115. {
  116.         I2C_SDA=1;
  117.         DelayXus(1);
  118.         I2C_SCL=1;
  119.         DelayXus(3);
  120.         I2C_SDA=0;
  121.         DelayXus(3);
  122.         I2C_SCL=0;
  123. }

  124. void Stop_I2C()                  //关闭IIC
  125. {
  126.         I2C_SDA=0;
  127.         DelayXus(3);
  128.         I2C_SCL=1;
  129.         DelayXus(3);
  130.         I2C_SDA=1;
  131.         DelayXus(3);
  132.         I2C_SCL=0;
  133. }
  134. bit Wait_Ack(void)                                                        //等待应答信号
  135. {
  136.         u8 ucErrTime=0;

  137.         I2C_SCL=1;
  138.         DelayXus(3);
  139.         while(I2C_SDA)
  140.         {
  141.                 ucErrTime++;
  142.                 if(ucErrTime>250)
  143.                 {
  144.                         Stop_I2C();
  145.                         return 1;
  146.                 }
  147.         }
  148.         I2C_SCL=1;
  149.         return 0;
  150. }
  151. void I2CAck()                    //发送应答信号
  152. {
  153.         I2C_SCL=1;
  154.         DelayXus(3);
  155.         I2C_SDA=1;
  156.         DelayXus(3);
  157.         I2C_SCL=0;
  158. }
  159. void I2CNotAck()                 //发送非应答信号
  160. {
  161.         I2C_SCL=1;
  162.         DelayXus(3);
  163.         I2C_SDA=0;
  164.         DelayXus(3);
  165.         I2C_SCL=0;
  166. }
  167. void Send_I2C_Byte(u8 txd)            //在总线上发送一个字节
  168. {  
  169.         u8 i;
  170.        
  171.         for(i=0;i<8;i++)
  172.         {
  173.                 I2C_SCL=0;
  174.                 DelayXus(3);
  175.                 if(txd&0x80)
  176.                         I2C_SDA=1;
  177.                 else
  178.                         I2C_SDA=0;
  179.                 txd<<=1;
  180.                 DelayXus(3);
  181.                 I2C_SCL=1;
  182.                 DelayXus(3);
  183.         }
  184.         I2C_SCL=0;
  185. }
  186. u8 Receive_I2C()        //在总线上接收一个字节
  187. {
  188.         u8 i,receive=0,Data_R;
  189.         I2C_SCL=1;
  190.         DelayXus(3);
  191.   for(i=0;i<8;i++ )
  192.         {
  193.                 I2C_SCL=0;
  194.                 DelayXus(3);
  195.                 I2C_SCL=1;
  196.                 DelayXus(3);
  197.                 Data_R=I2C_SDA;
  198.                 if(Data_R==0X08)
  199.                         receive|=0X80>>i;
  200.         }                                         
  201.         I2C_SCL=0;
  202.         DelayXus(3);
  203.         return receive;
  204. }
  205. u8 read_byte(u8 add)        //从D1307指定地址读出一个字节数据
  206. {
  207.         u8 dat,temp;

  208.         Start_I2C();
  209.         Send_I2C_Byte(DS1307_ADDR);
  210.         Wait_Ack();
  211.         Send_I2C_Byte(add);
  212.         Wait_Ack();
  213.         Stop_I2C();
  214.         Start_I2C();
  215.         Send_I2C_Byte(DS1307_ADDR+1);
  216.         Wait_Ack();
  217.         dat=Receive_I2C();
  218.         I2CAck();
  219.         Stop_I2C();
  220.         temp=dat/16;
  221.         dat=dat%16;
  222.         dat=dat+temp*10;

  223.         return dat;
  224. }


  225. void write_byte(u8 add,u8 dat) //向D1307中地址为address的寄存器写入一字节数据
  226. {
  227.         u8 temp;
  228.         temp=dat/10;
  229.         temp<<=4;
  230.         temp=dat%10+temp;
  231.        
  232.         Start_I2C();
  233.         Send_I2C_Byte(DS1307_ADDR);
  234.         Wait_Ack();
  235.         Send_I2C_Byte(add);
  236.         Wait_Ack();
  237.         Send_I2C_Byte(temp);
  238.         Stop_I2C();
  239. }
  240. void Read_RTC(u8 *p)                //读取时间
  241. {
  242.         u8 i;

  243.         for(i=0;i<7;i++)
  244.         {
  245.                 p[i]=(read_byte(i));
  246.         }
  247. }
  248. void Set_RTC(u8 *p)                        //设置时间
  249. {
  250.         u8 i,temp,dat;
  251.         Start_I2C();
  252.         Send_I2C_Byte(DS1307_ADDR);
  253.         Wait_Ack();
  254.         Send_I2C_Byte(0);
  255.         Wait_Ack();
  256.         for(i=0;i<7;i++)
  257.         {
  258.                 dat=*p;
  259.                 temp=dat/10;
  260.                 temp<<=4;
  261.                 temp=dat%10+temp;
  262.                 Send_I2C_Byte(temp);
  263.                 p++;
  264.                 Wait_Ack();
  265.         }
  266.         Stop_I2C();
  267. }




  268. void SendByte(u8 dat)
  269. {
  270.         B_TX1_Busy = 1;                                        //标志发送忙
  271.         SBUF = dat;                                                                //发一个字节
  272.         while(B_TX1_Busy > 0);        //等待发送完成
  273. }
  274. //========================================================================
  275. // 函数: void UART1_int (void) interrupt UART1_VECTOR
  276. // 描述: UART1中断函数。
  277. //========================================================================
  278. void UART1_int (void) interrupt 4
  279. {
  280.         if(RI)
  281.         {
  282.                 RI = 0;
  283.         }

  284.         if(TI)
  285.         {
  286.                 TI = 0;
  287.                 B_TX1_Busy = 0;
  288.         }
  289. }
复制代码



回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表