找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2469|回复: 3
收起左侧

单片机驱动ds3231只显示0000,不知道什么问题

[复制链接]
回帖奖励 10 黑币 回复本帖可获得 10 黑币奖励! 每人限 1 次
ID:404720 发表于 2018-12-12 13:51 | 显示全部楼层 |阅读模式
可能代码有点多哈,关于数码管的iic驱动是正常的,测试过了,现在的问题是3231的驱动,不知道怎么回事只显示0000,也不增加
  1. #include <reg51.h>
  2. #include <intrins.h>

  3. #define uchar unsigned char  
  4. #define uint unsigned int
  5. void get_show_time(void);//函数在下面先声明一下
  6. void TimeDisplay(uchar Dhour,uchar Dmin,uchar Dsec);
  7. sbit SDA=P1^0;     //模拟I2C数据传送位SDA        
  8. sbit SCL=P1^1;     //模拟I2C时钟控制位SCL
  9. sbit INT=P3^2;      
  10. sbit RESET=P3^3;
  11. sbit SCL1=P1^2; //clk
  12. sbit SDA1=P1^3; //dio 这是数码TM1637的定义引脚
  13. char min;//个位的分
  14. char sec;//个位的秒
  15. char min10;//个位的分
  16. char sec10;//个位的秒
  17. bit  ack;          //应答标志位
  18. #define DS3231_WriteAddress 0x56    //器件写地址
  19. #define DS3231_ReadAddress  0x57  //器件读地址
  20. #define DS3231_SECOND       0x00    //秒
  21. #define DS3231_MINUTE       0x01    //分
  22. #define DS3231_HOUR         0x02    //时
  23. #define DS3231_WEEK         0x03    //星期
  24. #define DS3231_DAY          0x04    //日
  25. #define DS3231_MONTH        0x05    //月
  26. #define DS3231_YEAR         0x06    //年
  27. //闹铃1
  28. #define DS3231_SALARM1ECOND 0x07    //秒
  29. #define DS3231_ALARM1MINUTE 0x08    //分
  30. #define DS3231_ALARM1HOUR   0x09    //时
  31. #define DS3231_ALARM1WEEK   0x0A    //星期/日
  32. //闹铃2
  33. #define DS3231_ALARM2MINUTE 0x0b    //分
  34. #define DS3231_ALARM2HOUR   0x0c    //时
  35. #define DS3231_ALARM2WEEK   0x0d    //星期/日
  36. #define DS3231_CONTROL      0x0e    //控制寄存器
  37. #define DS3231_STATUS       0x0f    //状态寄存器
  38. #define BSY                 2       //忙
  39. #define OSF                 7       //振荡器停止标志
  40. #define DS3231_XTAL         0x10    //晶体老化寄存器
  41. #define DS3231_TEMPERATUREH 0x11    //温度寄存器高字节(8位)
  42. #define DS3231_TEMPERATUREL 0x12    //温度寄存器低字节(高2位)

  43. uchar code dis_code[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f};// 0,1,2,3,4,5,6,7,8,9
  44. uchar data dis_buf[10]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
  45. void IIC_delay(void)
  46. {
  47.     unsigned char i;
  48.     for(i=0;i<20;i++) _nop_();
  49. }

  50. void start_IIC(void) //数码管开始信号
  51. {
  52.     SCL1=1; //给芯片发送开始信号
  53.     SDA1=1;
  54.     IIC_delay();
  55.     SDA1=0;
  56.     IIC_delay();
  57.     SCL1=0; //开始信号传送完
  58.     IIC_delay();
  59. }
  60. void stop_IIC(void) //数码管结束信号
  61. {
  62.     SCL1=0;
  63.     IIC_delay();
  64.     SDA1=0;
  65.     IIC_delay();
  66.     SCL1=1;
  67.     IIC_delay();
  68.     SDA1=1;
  69. }
  70. void ack_IIC() //数码管应答信号
  71. {
  72.     SCL1=0;
  73.     _nop_();_nop_();_nop_();
  74.     while(SDA1);
  75.     SCL1=1;
  76.     _nop_();_nop_();_nop_();
  77.     SCL1=0;
  78. }
  79. void WriteByte(unsigned char WriteData) //数码管写信号
  80. {
  81.     unsigned char i;
  82.     for(i=0;i<8;i++)//开始传送8位数据,每循环一次传送一位数据
  83.     {
  84.         SCL1=0;
  85.         IIC_delay();
  86.         WriteData=WriteData>>1;
  87.         SDA1=CY;
  88.         IIC_delay();
  89.         SCL1=1;
  90.         IIC_delay();
  91.     }
  92. //8位数据传送完
  93.     ack_IIC(); //判断芯片发过来的ACK应答信号
  94. }
  95. void write_LEDSROM(unsigned char addr,unsigned char WData) //数码管指定地址
  96. {
  97.     start_IIC(); //调用开始信号
  98.     WriteByte(addr); //写起始地址命令(C0H),地址00H单元。
  99.     WriteByte(WData);//给显示寄存器写显示数据,值可根据实参改变
  100.     stop_IIC(); //调用结束信号,一个字节命令发送完毕,可以发送下一个命令
  101. }
  102. void xsled(void)
  103. {
  104.     SDA1=1;
  105.     SCL1=1;
  106.     start_IIC(); //调用开始信号
  107.     WriteByte(0x40);//写命令40H(数据设置)
  108.     stop_IIC(); //调用结束信号,一个字节命令发送完毕,可以发送下一个命令
  109.               write_LEDSROM(0xC1,min);//第2个数码管
  110.    write_LEDSROM(0xC3,sec);//第4个数码管
  111.    write_LEDSROM(0xC2,sec10);//第3个数码管
  112.                 write_LEDSROM(0xC0,min10);//第1个数码管

  113.     IIC_delay();
  114.     start_IIC(); //调用开始信号
  115.     WriteByte(0x8f); //送开屏命令,(8BH),亮度可以根据低三位调节。//显示亮度
  116.     stop_IIC(); //调用结束信号,一个字节命令发送完毕,可以发送下一个命令
  117. }

  118. uchar BCD2HEX(uchar date)                                                 //从时钟芯片中读出的时间数据,需转换为十进制数。
  119. {
  120.     uchar temp;

  121.     temp = ((date>>4)*10 + (date&0x0f));
  122.     return temp;
  123. }
  124. uchar HEX2BCD(uchar date)                                                //往时钟芯片写入数据时,需将待写的十进制数转换为8421码。
  125. {
  126.    uchar temp;
  127.     temp = (((date/10)<<4) + (date%10));
  128.     return temp;
  129. }
  130. void delayus(uint us)
  131. {
  132.     while (us--);
  133. }
  134. void Start_I2C()
  135. {
  136.        SDA=1;                  //发送起始条件的数据信号
  137.     delayus(5);
  138.        SCL=1;
  139.     delayus(6);             //起始条件建立时间大于4.7us,延时
  140.        SDA=0;                  //发送起始信号
  141.     delayus(6);             // 起始条件锁定时间大于4μs
  142.        SCL=0;                  //钳住I2C总线,准备发送或接收数据
  143.     delayus(6);
  144. }
  145. void Stop_I2C()
  146. {
  147.                         SDA=0;                  //发送结束条件的数据信号
  148.     delayus(5);             //发送结束条件的时钟信号
  149.                         SCL=1;                  //结束条件建立时间大于4us
  150.     delayus(6);
  151.                         SDA=1;                  //发送I2C总线结束信号
  152.     delayus(6);
  153. }
  154. void SendByte(uchar c)
  155. {
  156.     uchar BitCnt;
  157.    
  158.     for(BitCnt=0;BitCnt<8;BitCnt++)         //要传送的数据长度为8位
  159.     {
  160.         if((c<<BitCnt)&0x80)
  161.             SDA=1;                          //判断发送位
  162.         else
  163.             SDA=0;               
  164.           delayus(1);
  165.           SCL=1;                            //置时钟线为高,通知被控器开始接收数据位
  166.           delayus(5);                       //保证时钟高电平周期大于4μs   
  167.           SCL=0;
  168.     }
  169.        delayus(2);
  170.     SDA=1;                                  //8位发送完后释放数据线,准备接收应答位
  171.     delayus(2);  
  172.     SCL=1;
  173.     delayus(3);
  174.     if(SDA==1)
  175.         ack=0;   
  176.     else
  177.         ack=1;                              //判断是否接收到应答信号
  178.     SCL=0;
  179.     delayus(2);
  180. }
  181. uchar RcvByte()
  182. {
  183.    uchar retc;
  184.    uchar BitCnt;

  185.    retc=0;
  186.    SDA=1;                           //置数据线为输入方式
  187.    for(BitCnt=0;BitCnt<8;BitCnt++)
  188.    {
  189.         delayus(1);  
  190.         SCL=0;                      //置时钟线为低,准备接收数据位
  191.       
  192.         delayus(5);                 //时钟低电平周期大于4.7μs
  193.       
  194.         SCL=1;                      //置时钟线为高使数据线上数据有效
  195.         delayus(3);
  196.         retc=retc<<1;
  197.         if(SDA==1)
  198.             retc=retc+1;            //读数据位,接收的数据位放入retc中
  199.         delayus(2);
  200.    }
  201.    SCL=0;
  202.    delayus(2);
  203.    return(retc);
  204. }

  205. void Ack_I2C(bit a)
  206. {
  207.      if(a==0)
  208.         SDA=0;              //在此发出应答或非应答信号
  209.     else
  210.         SDA=1;
  211.     delayus(3);     
  212.     SCL=1;
  213.        delayus(5);             //时钟低电平周期大于4μs
  214.        SCL=0;                  //清时钟线,钳住I2C总线以便继续接收
  215.     delayus(2);   
  216. }


  217. uchar write_byte(uchar addr, uchar write_data)
  218. {
  219.     Start_I2C();
  220.     SendByte(DS3231_WriteAddress);
  221.     if (ack == 0)
  222.         return 0;
  223.        SendByte(addr);   
  224.     if (ack == 0)
  225.         return 0;
  226.        SendByte(write_data);
  227.     if (ack == 0)
  228.         return 0;
  229.        Stop_I2C();
  230.     delayus(10);      
  231.     return 1;
  232. }
  233. uchar read_current()
  234. {
  235.     uchar read_data;
  236.     Start_I2C();
  237.     SendByte(DS3231_ReadAddress);
  238.     if(ack==0)
  239.         return(0);
  240.        read_data = RcvByte();
  241.     Ack_I2C(1);
  242.     Stop_I2C();
  243.     return read_data;
  244. }

  245. uchar read_random(uchar random_addr)
  246. {
  247.     Start_I2C();
  248.     SendByte(DS3231_WriteAddress);
  249.     if(ack==0)
  250.         return(0);
  251.        SendByte(random_addr);
  252.     if(ack==0)
  253.         return(0);
  254.        return(read_current());
  255. }
  256. void ModifyTime(uchar yea,uchar mon,uchar da,uchar hou,uchar min,uchar sec)
  257. {
  258.     uchar temp=0;
  259.        temp=HEX2BCD(yea);
  260.     write_byte(DS3231_YEAR,temp);   //修改年
  261.    
  262.     temp=HEX2BCD(mon);
  263.     write_byte(DS3231_MONTH,temp);  //修改月
  264.    
  265.     temp=HEX2BCD(da);
  266.     write_byte(DS3231_DAY,temp);    //修改日
  267.    
  268.     temp=HEX2BCD(hou);
  269.     write_byte(DS3231_HOUR,temp);   //修改时
  270.    
  271.     temp=HEX2BCD(min);
  272.     write_byte(DS3231_MINUTE,temp); //修改分
  273.    
  274.     temp=HEX2BCD(sec);
  275.     write_byte(DS3231_SECOND,temp); //修改秒
  276. }

  277. void get_show_time(void)
  278. {
  279.     uchar Htemp1,Htemp2,Mtemp1,Mtemp2,Stemp1,Stemp2;

  280.     Htemp1=read_random(DS3231_HOUR);    //时 24小时制
  281.     Htemp1&=0x3f;                  
  282.     Htemp2=BCD2HEX(Htemp1);
  283.    
  284.     Mtemp1=read_random(DS3231_MINUTE);  //分
  285.     Mtemp2=BCD2HEX(Mtemp1);
  286.    
  287.     Stemp1=read_random(DS3231_SECOND);  //秒
  288.     Stemp2=BCD2HEX(Stemp1);
  289.    
  290.     TimeDisplay(Htemp2,Mtemp2,Stemp2);
  291. }
  292. void TimeDisplay(uchar Dhour,uchar Dmin,uchar Dsec)
  293. {
  294. dis_buf[7]=dis_code[Dhour / 10];        // 时十位
  295. dis_buf[6]=dis_code[Dhour % 10];        // 时个位
  296. dis_buf[4]=dis_code[Dmin / 10];         // 分十位
  297. dis_buf[3]=dis_code[Dmin % 10];         // 分个位
  298. dis_buf[1]=dis_code[Dsec / 10];         // 秒十位
  299. dis_buf[0]=dis_code[Dsec % 10];         // 秒个位
  300. }



  301. void main()
  302. {
  303.     RESET=0x1;          //DS3231复位操作,正常操作下不需要每次都复位
  304.     delayus(5000);
  305.    ModifyTime(18,12,6,20,59,59);       //初始化时钟,年月日时分秒  时采用24小时制
  306.     while(1)
  307.     {   
  308.                                    get_show_time();   
  309. min10=dis_buf[4];
  310. min=dis_buf[3];
  311. sec10=dis_buf[1];
  312. sec=dis_buf[0];
  313.                         xsled();
  314.     }
  315.    }
复制代码


回复

使用道具 举报

ID:396881 发表于 2018-12-12 14:57 | 显示全部楼层
很显然,你的3231驱动有问题,查查datesheet手册,相信你可以的。
回复

使用道具 举报

ID:404720 发表于 2018-12-12 16:08 | 显示全部楼层
18656265250 发表于 2018-12-12 14:57
很显然,你的3231驱动有问题,查查datesheet手册,相信你可以的。

全英文看不懂啊
回复

使用道具 举报

ID:440349 发表于 2018-12-14 18:23 | 显示全部楼层
3231驱动问题
回复

使用道具 举报

5#
无效楼层,该帖已经被删除
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

Powered by 单片机教程网

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