找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3115|回复: 5
打印 上一主题 下一主题
收起左侧

DS3231时钟模块与单片机开发板怎么接线

[复制链接]
跳转到指定楼层
楼主
DS3231时钟模块与单片机开发板怎么接线,求大神



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:96682 发表于 2017-10-1 23:52 | 只看该作者
没源程序说啥都白搭
回复

使用道具 举报

板凳
ID:236639 发表于 2017-10-2 14:17 | 只看该作者
wc86110 发表于 2017-10-1 23:52
没源程序说啥都白搭
  1. #include <reg51.h>
  2. #include <intrins.h>
  3. #define uchar   unsigned char  
  4. #define uint    unsigned int
  5. sbit SDA=P3^6;     //模拟I2C数据传送位SDA        
  6. sbit SCL=P3^7;     //模拟I2C时钟控制位SCL
  7. sbit INT=P3^2;      
  8. sbit RESET=P3^3;
  9. sbit led0=P1^0;
  10. sbit led1=P1^1;
  11. sbit led2=P1^2;
  12. sbit led3=P1^3;
  13. sbit led4=P1^4;
  14. sbit led5=P1^5;
  15. sbit led6=P1^6;
  16. sbit led7=P1^7;
  17. bit  ack;          //应答标志位

  18. #define DS3231_WriteAddress 0xD0    //器件写地址
  19. #define DS3231_ReadAddress  0xD1    //器件读地址
  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[11]={0xc0,0xf9,0xa4,0xb0,   // 0,1,2,3
  44.             0x99,0x92,0x82,0xf8,0x80,0x90, 0xff};       // 4,5,6,7,8,9,off
  45. uchar data dis_buf[8];
  46. uchar data dis_index;
  47. uchar data dis_digit;

  48. uchar BCD2HEX(uchar val)    //BCD转换为Byte
  49. {
  50.     uchar temp;
  51.     temp=val&0x0f;
  52.     val>>=4;
  53.     val&=0x0f;
  54.     val*=10;
  55.     temp+=val;
  56.    
  57.     return temp;
  58. }

  59. uchar HEX2BCD(uchar val)    //B码转换为BCD码
  60. {
  61.     uchar i,j,k;
  62.     i=val/10;
  63.     j=val;
  64.     k=j+(i<<4);
  65.     return k;
  66. }

  67. void delayus(uint us)
  68. {
  69.     while (us--);
  70. }

  71. void Start_I2C()
  72. {
  73.     SDA=1;                  //发送起始条件的数据信号
  74.     delayus(1);
  75.     SCL=1;
  76.     delayus(5);             //起始条件建立时间大于4.7us,延时
  77.    
  78.     SDA=0;                  //发送起始信号
  79.     delayus(5);             // 起始条件锁定时间大于4μs
  80.       
  81.     SCL=0;                  //钳住I2C总线,准备发送或接收数据
  82.     delayus(2);
  83. }

  84. void Stop_I2C()
  85. {
  86.     SDA=0;                  //发送结束条件的数据信号
  87.     delayus(1);             //发送结束条件的时钟信号
  88.     SCL=1;                  //结束条件建立时间大于4us
  89.     delayus(5);
  90.    
  91.     SDA=1;                  //发送I2C总线结束信号
  92.     delayus(4);
  93. }

  94. void SendByte(uchar c)
  95. {
  96.     uchar BitCnt;
  97.    
  98.     for(BitCnt=0;BitCnt<8;BitCnt++)         //要传送的数据长度为8位
  99.     {
  100.         if((c<<BitCnt)&0x80)
  101.             SDA=1;                          //判断发送位
  102.         else
  103.             SDA=0;               
  104.           delayus(1);
  105.           SCL=1;                            //置时钟线为高,通知被控器开始接收数据位
  106.           delayus(5);                       //保证时钟高电平周期大于4μs   
  107.           SCL=0;
  108.     }
  109.    
  110.     delayus(2);
  111.     SDA=1;                                  //8位发送完后释放数据线,准备接收应答位
  112.     delayus(2);  
  113.     SCL=1;
  114.     delayus(3);
  115.     if(SDA==1)
  116.         ack=0;   
  117.     else
  118.         ack=1;                              //判断是否接收到应答信号
  119.     SCL=0;
  120.     delayus(2);
  121. }

  122. uchar RcvByte()
  123. {
  124.    uchar retc;
  125.    uchar BitCnt;

  126.    retc=0;
  127.    SDA=1;                           //置数据线为输入方式
  128.    for(BitCnt=0;BitCnt<8;BitCnt++)
  129.    {
  130.         delayus(1);  
  131.         SCL=0;                      //置时钟线为低,准备接收数据位
  132.       
  133.         delayus(5);                 //时钟低电平周期大于4.7μs
  134.       
  135.         SCL=1;                      //置时钟线为高使数据线上数据有效
  136.         delayus(3);
  137.         retc=retc<<1;
  138.         if(SDA==1)
  139.             retc=retc+1;            //读数据位,接收的数据位放入retc中
  140.         delayus(2);
  141.    }
  142.    SCL=0;
  143.    delayus(2);
  144.    return(retc);
  145. }


  146. void Ack_I2C(bit a)
  147. {

  148.     if(a==0)
  149.         SDA=0;              //在此发出应答或非应答信号
  150.     else
  151.         SDA=1;
  152.     delayus(3);     
  153.     SCL=1;
  154.    
  155.     delayus(5);             //时钟低电平周期大于4μs
  156.    
  157.     SCL=0;                  //清时钟线,钳住I2C总线以便继续接收
  158.     delayus(2);   
  159. }


  160. uchar write_byte(uchar addr, uchar write_data)
  161. {
  162.     Start_I2C();
  163.     SendByte(DS3231_WriteAddress);
  164.     if (ack == 0)
  165.         return 0;
  166.    
  167.     SendByte(addr);   
  168.     if (ack == 0)
  169.         return 0;
  170.    
  171.     SendByte(write_data);
  172.     if (ack == 0)
  173.         return 0;
  174.    
  175.     Stop_I2C();
  176.     delayus(10);      
  177.     return 1;
  178. }


  179. uchar read_current()
  180. {
  181.     uchar read_data;
  182.     Start_I2C();
  183.     SendByte(DS3231_ReadAddress);
  184.     if(ack==0)
  185.         return(0);
  186.    
  187.     read_data = RcvByte();
  188.     Ack_I2C(1);
  189.     Stop_I2C();
  190.     return read_data;
  191. }


  192. uchar read_random(uchar random_addr)
  193. {
  194.     Start_I2C();
  195.     SendByte(DS3231_WriteAddress);
  196.     if(ack==0)
  197.         return(0);
  198.    
  199.     SendByte(random_addr);
  200.     if(ack==0)
  201.         return(0);
  202.    
  203.     return(read_current());
  204. }


  205. void ModifyTime(uchar yea,uchar mon,uchar da,uchar hou,uchar min,uchar sec)
  206. {
  207.     uchar temp=0;
  208.    
  209.     temp=HEX2BCD(yea);
  210.     write_byte(DS3231_YEAR,temp);   //修改年
  211.    
  212.     temp=HEX2BCD(mon);
  213.     write_byte(DS3231_MONTH,temp);  //修改月
  214.    
  215.     temp=HEX2BCD(da);
  216.     write_byte(DS3231_DAY,temp);    //修改日
  217.    
  218.     temp=HEX2BCD(hou);
  219.     write_byte(DS3231_HOUR,temp);   //修改时
  220.    
  221.     temp=HEX2BCD(min);
  222.     write_byte(DS3231_MINUTE,temp); //修改分
  223.    
  224.     temp=HEX2BCD(sec);
  225.     write_byte(DS3231_SECOND,temp); //修改秒
  226. }


  227. void TimeDisplay(uchar Dhour,uchar Dmin,uchar Dsec)
  228. {
  229.     dis_buf[7]=dis_code[Dhour / 10];        // 时十位
  230.     dis_buf[6]=dis_code[Dhour % 10];        // 时个位
  231.     dis_buf[4]=dis_code[Dmin / 10];         // 分十位
  232.     dis_buf[3]=dis_code[Dmin % 10];         // 分个位
  233.     dis_buf[1]=dis_code[Dsec / 10];         // 秒十位
  234.     dis_buf[0]=dis_code[Dsec % 10];         // 秒个位
  235.     dis_buf[2]=0xbf;                        // 显示"-"
  236.     dis_buf[5]=0xbf;
  237. }


  238. void DateDisplay(uchar Dyear,uchar Dmonth,uchar Dday)
  239. {
  240.     dis_buf[7]=dis_code[Dyear / 10];        // 年十位
  241.     dis_buf[6]=dis_code[Dyear % 10];        // 年个位
  242.     dis_buf[4]=dis_code[Dmonth / 10];       // 月十位
  243.     dis_buf[3]=dis_code[Dmonth % 10];       // 月个位
  244.     dis_buf[1]=dis_code[Dday / 10];         // 天十位
  245.     dis_buf[0]=dis_code[Dday % 10];         // 天个位
  246.     dis_buf[2]=0xbf;                        // 显示"-"
  247.     dis_buf[5]=0xbf;
  248. }


  249. void get_show_time(void)
  250. {
  251.     uchar Htemp1,Htemp2,Mtemp1,Mtemp2,Stemp1,Stemp2;

  252.     Htemp1=read_random(DS3231_HOUR);    //时 24小时制
  253.     Htemp1&=0x3f;                  
  254.     Htemp2=BCD2HEX(Htemp1);
  255.    
  256.     Mtemp1=read_random(DS3231_MINUTE);  //分
  257.     Mtemp2=BCD2HEX(Mtemp1);
  258.    
  259.     Stemp1=read_random(DS3231_SECOND);  //秒
  260.     Stemp2=BCD2HEX(Stemp1);
  261.    
  262.     TimeDisplay(Htemp2,Mtemp2,Stemp2);
  263. }


  264. void get_show_date(void)
  265. {
  266.     uchar Ytemp1,Ytemp2,Mtemp1,Mtemp2,Dtemp1,Dtemp2;
  267.    
  268.     Ytemp1=read_random(DS3231_YEAR);        //年
  269.     Ytemp2=BCD2HEX(Ytemp1);
  270.    
  271.     Mtemp1=read_random(DS3231_MONTH);       //月
  272.     Mtemp2=BCD2HEX(Mtemp1);
  273.    
  274.     Dtemp1=read_random(DS3231_DAY);         //日
  275.     Dtemp2=BCD2HEX(Dtemp1);
  276.    
  277.     DateDisplay(Ytemp2,Mtemp2,Dtemp2);
  278. }


  279. void get_show_Temperature(void)
  280. {
  281.     uchar Ttemp1,Ttemp2,Ttemp3,Ttemp4;
  282.    
  283.     Ttemp1=read_random(DS3231_TEMPERATUREH);    //温度 高字节
  284.     Ttemp2=BCD2HEX(Ttemp1);
  285.    
  286.     Ttemp3=read_random(DS3231_TEMPERATUREL);    //温度低字节
  287.     Ttemp4=BCD2HEX(Ttemp3);
  288.    
  289.     DateDisplay(0,Ttemp2,Ttemp4);
  290. }


  291. void timer0() interrupt 1
  292. {
  293.     TH0=0xFC;
  294.     TL0=0x17;
  295.    
  296.     P2=0xff;                    // 先关闭所有数码管
  297.     P0=dis_buf[dis_index];      // 显示代码传送到P0口
  298.     P2=dis_digit;
  299.    
  300.     if (dis_digit & 0x80)
  301.         dis_digit=(dis_digit << 1) | 0x1;
  302.     else
  303.         dis_digit=(dis_digit << 1);
  304.    
  305.     dis_index++;
  306.     dis_index&=0x07;            // 8个数码管全部扫描完一遍之后,再回到第一个开始下一次扫描
  307. }


  308. void main()
  309. {
  310.     uint ii = 0;
  311.    
  312.    
  313.     RESET=0x1;          //DS3231复位操作,正常操作下不需要每次都复位
  314.     delayus(5000);
  315.    
  316.     led0=0;
  317.     led1=0;
  318.     led2=0;
  319.     led3=0;
  320.     led4=0;
  321.    
  322.     P0=0xff;
  323.     P2=0xff;
  324.    
  325.     dis_digit=0xfe;
  326.     dis_index=0;
  327.    
  328.     TimeDisplay(12, 5, 18);
  329.    
  330.    
  331.     TMOD=0x11;          // 定时器0, 1工作模式1, 16位定时方式
  332.     TH0=0xFC;
  333.     TL0=0x17;
  334.    
  335.     TCON=0x01;
  336.     IE=0x82;            // 使能timer0,1 中断
  337.    
  338.     TR0=1;
  339.    
  340.    
  341.     if (write_byte(DS3231_CONTROL, 0x1C) == 0)
  342.         led0=1;
  343.    
  344.     if (write_byte(DS3231_STATUS, 0x00) == 0)
  345.         led1=1;
  346.    
  347.     ModifyTime(10,6,13,15,30,00);       //初始化时钟,2010/6/13,15/30/00
  348.                                         //小时采用24小时制
  349.     while(1)
  350.     {
  351.         //get_show_date();              //显示日期
  352.         //get_show_Temperature();       //显示温度
  353.         get_show_time();                //显示时间
  354.         delayus(50000);
  355.     }
  356.    
  357. }
复制代码
回复

使用道具 举报

地板
ID:82765 发表于 2017-10-2 17:35 来自手机 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

5#
ID:236639 发表于 2017-10-2 19:13 | 只看该作者
cjjcjj1 发表于 2017-10-2 17:35
你好!你发的程序用八个数码管显示,你的板子只有四个数码管
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #include<stdlib.h>

  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. /*端口定义*/
  7. sbit LCD_RS=P2^6;
  8. sbit LCD_RW=P2^5;
  9. sbit LCD_EN=P2^4;
  10. sbit LCD_PSB=P2^3;
  11. sbit DQ=P3^7;                              //18b20
  12. sbit SDA=P1^4;                              //ds32321            //模拟I2C数据传送位SDA        
  13. sbit SCL=P1^3;                                   //模拟I2C时钟控制位SCL
  14. //***按键功能****//
  15. ////***K1停止时间显示****//
  16. ////***K2选择修改位置****//
  17. ////***K3进行加1的修改****//
  18. ////***K4将修改写入ds3231,同时启动时间显示****//
  19. sbit K1=P3^2;                       
  20. sbit K2=P3^3;
  21. sbit K3=P3^4;
  22. sbit K4=P3^5;
  23. //定义变量               
  24. uchar numbr[10]="0123456789";                      //字模


  25. uchar dis4[]="   ";                                                            //          第四行显示   自己添加
  26. uchar t[]="  .   ℃" ;                                            //18b20
  27. uint sdata,xiaoshu1,xiaoshu2;                                 //整数、小数1位、小数2位
  28. bit fg=1;                                  //温度正负标志
  29. uchar tempL=0,tempH=0;                                                                // 变量         
  30. uchar year,month,date,hour,min,sec;                                 //    ds3231
  31. uchar a[]="2011年22月33日";
  32. uchar b[]="11时22分33秒";
  33.                                 ///函数
  34. //******************延时子程序 *******************************

  35. //这个延时程序的具体延时时间是time=i*8+10,适用于小于2ms的延时

  36. //************************************************************
  37. void delay(unsigned char i)
  38. {
  39. for(i;i>0;i--);
  40. }
  41. //***********************************************************
  42. //                     延时子程序
  43. //************************************************************
  44. void delay1ms(uchar j)
  45. {
  46. while(j!=0)
  47. {uchar i;
  48. for(i=124;i>0;i--);  //延时124*8+10=1002us
  49. j--;
  50. }
  51. }
  52. /**************************12864部分*************************************/
  53. /**************************12864部分*************************************/     
  54.                                                                                              /*写指令数据到LCD
  55.                                                                                              RS=L——表示DB0-DB7为显示指令数据
  56.                                                                                              RW=L——表示DB0-DB7数据被write(当E=“H-L”,指令数据被写到IR或DR)
  57.                                                                                              E=高脉冲
  58.                                                                                              此时DB0-DB7=指令码   */
  59. void write_cmd(uchar cmd)
  60. {
  61.          LCD_RS=0;
  62.          LCD_RW=0;
  63.          LCD_EN=0;
  64.          P0=cmd;
  65.          delay1ms(5);
  66.          LCD_EN=1;
  67.          delay1ms(5);
  68.          LCD_EN=0;
  69. }
  70.                                                                                     /*设定显示位置*/
  71. void lcd_pos(uchar X, uchar Y)
  72. {
  73.          ucharpos;

  74.          if(X== 0)
  75.          {
  76.                    X= 0x80;
  77.          }
  78.          elseif(X == 1)
  79.          {
  80.                    X= 0x90;
  81.          }
  82.          elseif(X == 2)
  83.          {
  84.                    X= 0x88;
  85.          }
  86.          elseif(X == 3)
  87.          {
  88.                    X= 0x98;
  89.          }
  90.          pos= X + Y;
  91.          write_cmd(pos);                                                     //显示地址
  92. }

  93.                                                                                                                 /*写显示数据到LCD*/
  94.                                                                                                                 /*
  95.                                                                                                                          RS=H——表示DB0-DB7为显示数据
  96.                                                                                                                          RW=L——RW=L,E='H-L',DB0-DB7数据被写到IR或DR   
  97.                                                                                                                           E=高脉冲
  98.                                                                                                                          DB0-DB7=显示数据        */
  99. void write_dat(uchar dat)
  100. {
  101.          LCD_RS=1;
  102.          LCD_RW=0;
  103.          LCD_EN=0;
  104.          P0=dat;
  105.          delay1ms(5);
  106.          LCD_EN=1;
  107.          delay1ms(5);
  108.          LCD_EN=0;
  109. }
  110.                                                                                                                          /*LCD初始化*/
  111. void lcd_init()
  112. {        uinti;

  113.          LCD_PSB=1;                                                                                //并口方式
  114.          write_cmd(0x30);                                                            //基本操作指令
  115.          delay1ms(5);
  116.          write_cmd(0x0c);                                                            //打开显示,光标关闭
  117.          delay1ms(5);
  118.          write_cmd(0x01);                                                            //清除LCD显示类容
  119.          delay1ms(5);


  120.          lcd_pos(3,0);
  121.                                      i=0;
  122.                                      while(dis4[ i]!='\0')
  123.                                                {
  124.                                                delay1ms(1);
  125.                                                write_dat(dis4);
  126.                                                delay1ms(1);
  127.                                                i++;
  128.                                                }
  129. }
  130. /**********************************18b20************************************************/
  131. /**********************************18b20************************************************/
  132. void Init_DS18B20(void)                                                                                              //初始化
  133. {
  134. uchar x=0;
  135. DQ=1; //DQ先置高
  136. delay(8); //稍延时
  137. DQ=0; //发送复位脉冲
  138. delay(80); //延时(>480us)
  139. DQ=1; //拉高数据线
  140. delay(5); //等待(15~60us)
  141. x=DQ; //用X的值来判断初始化有没有成功,18B20存在的话X=0,否则X=1
  142. delay(20);
  143. }
  144. //**********读一个字节************//
  145. ReadOneChar(void)  //主机数据线先从高拉至低电平1us以上,再使数据线升为高电平,从而产生读信号
  146. {
  147. unsigned char i=0; //每个读周期最短的持续时间为60us,各个读周期之间必须有1us以上的高电平恢复期
  148. unsigned char dat=0;
  149. for (i=8;i>0;i--) //一个字节有8位
  150. {
  151. DQ=1;
  152. delay(1);
  153. DQ=0;
  154. dat>>=1;
  155. DQ=1;
  156. if(DQ)
  157. dat|=0x80;
  158. delay(4);
  159. }
  160. return(dat);
  161. }
  162. //*********************** **写一个字节**************************//
  163. void WriteOneChar(unsigned char dat)
  164. {
  165. unsigned char i=0; //数据线从高电平拉至低电平,产生写起始信号。15us之内将所需写的位送到数据线上,
  166. for(i=8;i>0;i--) //在15~60us之间对数据线进行采样,如果是高电平就写1,低写0发生。
  167.   {
  168.   DQ=0; //在开始另一个写周期前必须有1us以上的高电平恢复期。
  169.   DQ=dat&0x01;
  170.   delay(5);
  171.   DQ=1;
  172.   dat>>=1;
  173.   }
  174. delay(4);
  175. }
  176. void ReadTemperature(void)                                                                                      //读温度值(低位放tempL;高位放tempH;)//
  177.          {
  178.           Init_DS18B20(); //初始化
  179.           WriteOneChar(0xcc); //跳过读序列号的操作
  180.           WriteOneChar(0x44); //启动温度转换
  181.           delay(125); //转换需要一点时间,延时
  182.           Init_DS18B20(); //初始化
  183.           WriteOneChar(0xcc); //跳过读序列号的操作
  184.           WriteOneChar(0xbe); //读温度寄存器(头两个值分别为温度的低位和高位)
  185.           tempL=ReadOneChar(); //读出温度的低位LSB
  186.           tempH=ReadOneChar(); //读出温度的高位MSB
  187.                    if(tempH>0x7f)      //最高位为1时温度是负
  188.                    {
  189.                     tempL=~tempL;         //补码转换,取反加一
  190.                     tempH=~tempH+1;      
  191.                     fg=0;     //读取温度为负时fg=0
  192.       }
  193.                    sdata= tempL/16+tempH*16;      //整数部分
  194.                    xiaoshu1= (tempL&0x0f)*10/16; //小数第一位
  195.                    xiaoshu2= (tempL&0x0f)*100/16%10;//小数第二位
  196.                    t[0]=numbr[sdata/10];
  197.                    t[1]=numbr[sdata%10];
  198.                    t[3]=numbr[xiaoshu1];
  199.                    t[4]=numbr[xiaoshu2];
  200.          }
  201. /*****************************************ds3231********************************************/
  202. #define ADDRTW          0xD0    //器件写地址
  203. #define ADDRTD          0xD1 //器件读地址
  204. #define DS3231_SEC      0x00   //秒
  205. #define DS3231_MIN      0x01   //分
  206. #define DS3231_HOUR     0x02   //时
  207. #define DS3231_DAY      0x03   //星期
  208. #define DS3231_DATE     0x04   //日
  209. #define DS3231_MONTH    0x05   //月
  210. #define DS3231_YEAR     0x06   //年
  211. //闹铃1            
  212. #define DS3231_Al1SEC   0x07   //秒
  213. #define DS3231_AL1MIN   0x08   //分
  214. #define DS3231_AL1HOUR  0x09   //时
  215. #define DS3231_AL1DAY   0x0A   //星期/日
  216. //闹铃2
  217. #define DS3231_AL2MIN   0x0b   //分
  218. #define DS3231_AL2HOUR  0x0c   //时
  219. #define DS3231_AL2DAY   0x0d   //星期/日
  220. #define DS3231_CONTROL  0x0e   //控制寄存器
  221. #define DS3231_STATUS   0x0f   //状态寄存器
  222. bit ack;
  223. uchar BCD2HEX(uchar val)           //BCD转换为Byte           
  224. {        uchari;
  225.    i= val&0x0f;
  226.    val >>= 4;
  227.    val &= 0x0f;
  228.    val *= 10;
  229.     i+= val;
  230.    return i;
  231. }
  232. uchar HEX2BCD(uchar val)//B码转换为BCD码
  233.          {
  234.          uchari,j,k;
  235.            i=val/10;
  236.            j=val%10;
  237.            k=j+(i<<4);
  238.            return k;
  239.          }
  240. void Start()      
  241. {
  242.    SDA=1;                  //发送起始条件的数据信号
  243.    delay(1);
  244.    SCL=1;
  245.    delay(5);             //起始条件建立时间大于4.7us,延时
  246.      SDA=0;                  //发送起始信号
  247.    delay(5);             // 起始条件锁定时间大于4μs
  248.    SCL=0;                  //钳住I2C总线,准备发送或接收数据
  249.    delay(2);
  250. }
  251. void Stop()
  252. {
  253.    SDA=0;                  //发送结束条件的数据信号
  254.    delay(1);             //发送结束条件的时钟信号
  255.    SCL=1;                  //结束条件建立时间大于4us
  256.     delay(5);
  257.    SDA=1;                  //发送I2C总线结束信号
  258.    delay(4);
  259. }
  260. /********************************************************/
  261. /*******************************************************************
  262.                   字节数据发送函数               
  263. 函数原型:     void  SendByte(uchar Dat);
  264. 功能:      将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
  265.           此状态位进行操作.(不应答或非应答都使ack=0)
  266.           ack=1        发送数据正常,
  267.           ack=0        被控器无应答或损坏。
  268. ********************************************************************/
  269. void SendByte(uchar Dat)
  270. {
  271. uchar BitCnt;
  272.    for(BitCnt=0;BitCnt<8;BitCnt++)         //要传送的数据长度为8位
  273.     {
  274.        if((Dat<<BitCnt)&0x80)
  275.            SDA=1;                          //判断发送位
  276.        else
  277.            SDA=0;               
  278.          delay(1);
  279.          SCL=1;                            //置时钟线为高,通知被控器开始接收数据位
  280.          delay(5);                       //保证时钟高电平周期大于4μs   
  281.          SCL=0;
  282.     }
  283.    delay(2);
  284.    SDA=1;                                 //8位发送完后释放数据线,准备接收应答位
  285.    delay(2);  
  286.    SCL=1;
  287.     delay(3);
  288.    if(SDA==1)
  289.        ack=0;   
  290.    else
  291.        ack=1;                             //判断是否接收到应答信号
  292.    SCL=0;
  293.    delay(2);
  294. }
  295. uchar RcvByte()                                                                                  //功能:     用来接收从器件传来的数据,并判断总线错误(不发应答信号),发完后请用应答函数应答从机。
  296. {
  297. uchar retc;
  298. uchar BitCnt;
  299.   retc=0;
  300.   SDA=1;                          //置数据线为输入方式
  301.   for(BitCnt=0;BitCnt<8;BitCnt++)
  302.    {
  303.        delay(1);  
  304.        SCL=0;                      //置时钟线为低,准备接收数据位
  305.        delay(5);                 //时钟低电平周期大于4.7μs
  306.        SCL=1;                      //置时钟线为高使数据线上数据有效
  307.        delay(3);
  308.        retc=retc<<1;
  309.        if(SDA==1)
  310.            retc=retc+1;            //读数据位,接收的数据位放入retc中
  311.        delay(2);
  312.    }
  313.   SCL=0;
  314.   delay(2);
  315.   return(retc);
  316. }
  317. void I2CACK(bit a)                       // 功能:       主控器进行应答信号(可以是应答或非应答信号,由位参数a决定)
  318. {
  319.    if(a==0)
  320.        SDA=0;              //在此发出应答或非应答信号
  321.    else
  322.        SDA=1;
  323.    delay(3);     
  324.    SCL=1;
  325.    delay(5);             //时钟低电平周期大于4μs
  326.    SCL=0;                  //清时钟线,钳住I2C总线以便继续接收
  327.    delay(2);   
  328. }
  329. uchar I2CRead()                                                                                  /************从DS3231当前地址读一个字节************/
  330. {
  331. uchar read_data;
  332.          Start();
  333.    SendByte(ADDRTD);                                             
  334.    if(ack==0)
  335.     {
  336. return(0);
  337.     }
  338.    read_data = RcvByte();
  339.    I2CACK(1);
  340.    Stop();
  341.    return read_data;
  342. }
  343. uchar I2CReadAdd(uchar addr)                                                      /************从DS3231指定地址读一个字节************/
  344.          {
  345.              Start();
  346.              SendByte(ADDRTW);                           
  347.              if(ack==0)
  348.              {        
  349.            return(0);
  350.              }
  351.              SendByte(addr);
  352.              if(ack==0)
  353.              {        
  354.            return(0);
  355.              }
  356.              return(I2CRead());
  357.          }
  358. void Readtime()                                                                                            /*********************读取时间**********************/
  359.          {
  360.           uchar temp;
  361.           temp=I2CReadAdd(DS3231_SEC);//秒
  362.           sec=BCD2HEX(temp);
  363.           temp=I2CReadAdd(DS3231_MIN);//分
  364.           min=BCD2HEX(temp);
  365.           temp=I2CReadAdd(DS3231_HOUR);  //时                  
  366.           hour=BCD2HEX(temp);
  367.           temp=I2CReadAdd(DS3231_DATE);  //日
  368.           date=BCD2HEX(temp);
  369.           temp=I2CReadAdd(DS3231_MONTH); //月
  370.           month=BCD2HEX(temp);
  371.           temp=I2CReadAdd(DS3231_YEAR);  //年
  372.           year=BCD2HEX(temp);
  373.           }
  374. void InitDS3231()                                                                                                            //ds3231初始化
  375.          {SCL=1;
  376.           delay(5);
  377.           SDA=1;
  378.           delay(5);
  379.          }
  380. void TimeDisplay(uchar Dhour,ucharDmin,uchar Dsec)                                     //时分秒数组赋值
  381.          {        b[0]=numbr[Dhour / 10];        // 时十位
  382.              b[1]=numbr[Dhour % 10];        // 时个位
  383.              b[4]=numbr[Dmin / 10];         // 分十位
  384.              b[5]=numbr[Dmin % 10];         // 分个位
  385.              b[8]=numbr[Dsec / 10];         // 秒十位
  386.              b[9]=numbr[Dsec % 10];         // 秒个位
  387.          }
  388. void DateDisplay(uchar Dyear,ucharDmonth,uchar Dday)                       //年月天数组赋值   
  389.          {        a[2]=numbr[Dyear / 10];        // 年十位
  390.              a[3]=numbr[Dyear % 10];        // 年个位
  391.              a[6]=numbr[Dmonth / 10];       // 月十位
  392.              a[7]=numbr[Dmonth % 10];       // 月个位
  393.              a[10]=numbr[Dday / 10];         // 天十位
  394.              a[11]=numbr[Dday % 10];         // 天个位                                   
  395.          }
  396. void Start_I2C()
  397. {
  398.    SDA=1;                  //发送起始条件的数据信号
  399.    delay(1);
  400.    SCL=1;
  401.    delay(5);             //起始条件建立时间大于4.7us,延时
  402.    SDA=0;                  //发送起始信号
  403.    delay(5);             // 起始条件锁定时间大于4μs
  404.    SCL=0;                  //钳住I2C总线,准备发送或接收数据
  405.    delay(2);
  406. }
  407. void Stop_I2C()
  408. {
  409.     SDA=0;                  //发送结束条件的数据信号
  410.    delay(1);             //发送结束条件的时钟信号
  411.    SCL=1;                  //结束条件建立时间大于4us
  412.    delay(5);
  413.    SDA=1;                  //发送I2C总线结束信号
  414.    delay(4);
  415. }
  416. uchar write_byte(uchar addr, ucharwrite_data)
  417. {
  418.    Start_I2C();
  419.    SendByte(ADDRTW);                //////*******************************************************************///////////
  420.    if (ack == 0)
  421.        return 0;
  422.    SendByte(addr);   
  423.    if (ack == 0)
  424.        return 0;
  425.    SendByte(write_data);
  426.    if (ack == 0)
  427.        return 0;
  428.    Stop_I2C();
  429.     delay1ms(10);      
  430.    return 1;
  431. }
  432. void ModifyTime(uchar yea,uchar mon,ucharda,uchar hou,uchar min,uchar sec)
  433. {     uchar temp=0;
  434.    temp=HEX2BCD(yea);
  435.    write_byte(DS3231_YEAR,temp);   //修改年
  436.    temp=HEX2BCD(mon);
  437.    write_byte(DS3231_MONTH,temp);  //修改月
  438.    temp=HEX2BCD(da);                                                                                     /////////////////////
  439.    write_byte(DS3231_DATE,temp);   //修改日
  440.    temp=HEX2BCD(hou);
  441.    write_byte(DS3231_HOUR,temp);   //修改时
  442.    temp=HEX2BCD(min);
  443.    write_byte(DS3231_MIN,temp); //修改分
  444.    temp=HEX2BCD(sec);
  445.    write_byte(DS3231_SEC,temp); //修改秒
  446. }
  447. void xianshi(void)
  448.    {
  449.                             {uint i;
  450.                    TimeDisplay(hour,min,sec);                                                                                         
  451.                                      lcd_pos(1,1);                         //时间
  452.                                      i=0;
  453.                                      while(b[ i]!='\0')
  454.                                                {
  455.                                                delay1ms(1);
  456.                                                write_dat(b);
  457.                                                delay1ms(1);
  458.                                                i++;
  459.                                                }
  460.                                      DateDisplay(year,month,date);        //显示日期                                                                                                                                                                    
  461.                                      delay1ms(1);
  462.                                      lcd_pos(0,0);
  463.                                      i=0;
  464.                                      while(a[ i]!='\0')
  465.                                                {
  466.                                                delay1ms(1);
  467.                                                write_dat(a);
  468.                                                delay1ms(1);
  469.                                                i++;
  470.                                                }
  471.                                      ReadTemperature();                                                                //显示温度
  472.                                      delay1ms(1);
  473.                                      lcd_pos(2,1);
  474.                                      delay1ms(1);
  475.                                      i=0;
  476.                                      while(t[ i]!='\0')
  477.                                                         {
  478.                                                         delay1ms(1);
  479.                                                         write_dat(t);
  480.                                                         delay1ms(2);
  481.                                                         i++;
  482.                                                         }
  483.                             }
  484. }
  485. void shuaxin(void)
  486.          {                 uint i;
  487.                  TimeDisplay(hour,min,sec);                                                                                         
  488.                                      lcd_pos(1,1);                         //时间
  489.                                      i=0;
  490.                                      while(b[ i]!='\0')
  491.                                                {
  492.                                                delay1ms(1);
  493.                                                write_dat(b);
  494.                                                delay1ms(1);
  495.                                                i++;
  496.                                                }
  497.                                      DateDisplay(year,month,date);        //显示日期                                                                                                                                                                    
  498.                                      delay1ms(1);
  499.                                      lcd_pos(0,0);
  500.                                      i=0;
  501.                                      while(a[ i]!='\0')
  502.                                                {
  503.                                                delay1ms(1);
  504.                                                write_dat(a);
  505.                                                delay1ms(1);
  506.                                                i++;
  507.                                                }
  508.          }
  509. void sotp(void)                                                                                                                 
  510. {
  511.          uinti;                     
  512. while(1)
  513.           {
  514.          duan1:                if(K1==0)
  515.                             {
  516.                             delay1ms(100);
  517.                             if(K1==0)
  518.                                      {
  519.                                      Readtime();
  520.                                      shuaxin();
  521.                                      i=0;
  522.                             gotoduan2;
  523.                                      }
  524.                             }
  525.                             else
  526.                             {gotoduan5;}
  527.          duan2:               if(K2==0)
  528.                             {
  529.                                      delay1ms(100);
  530.                                      if(K2==0)
  531.                                      {
  532.                                      i++;
  533.                                      if(i>6){i=0;}
  534.                                      shuaxin();
  535.                                      }        
  536.                             }
  537.                             switch(i)
  538.                              {
  539.                                      case 0:  if(K3==0){delay1ms(100);if(K3==0){year=year+1;}                 if(year>=100){year=0;}                                                             shuaxin();}break;
  540.                                       case 1:  if(K3==0){delay1ms(100);if(K3==0){month=month+1;}         if(month>=13){month=0;}                                                                shuaxin();}break;
  541.                                      case 2:  if(K3==0){delay1ms(100);if(K3==0){date=date+1;}                if(date>=32){date=0;}                                                              shuaxin();}break;
  542.                                      case 3:  if(K3==0){delay1ms(100);if(K3==0){hour=hour+1;}                if(hour>=25){hour=0;}                                                              shuaxin();}break;
  543.                                      case 4:  if(K3==0){delay1ms(100);if(K3==0){min=min+1;}                 if(min>=61){min=0;}                                                                        shuaxin();}break;
  544.                                      case 5:  if(K3==0){delay1ms(100);if(K3==0){sec=sec+1;}                   if(sec>=61){sec=0;}                                                                shuaxin();} break;
  545.                              }
  546.          duan4:               if(K4==0)
  547.                             {
  548.                             delay1ms(100);
  549.                             if(K4==0)
  550.                             {
  551.                             ModifyTime(year,month,date,hour,min,sec);
  552.                             gotoduan5;                                 ///////////////////*******************//////////
  553.                             }        
  554.                    }
  555.                           else
  556.                             {gotoduan2;}
  557. duan5:      Readtime();
  558.                     xianshi();
  559.                    }
  560.          }
  561. main()                                              /*主程序*/
  562. {
  563.          lcd_init();
  564.          delay1ms(5);
  565.          InitDS3231();
  566.          delay1ms(5);
  567.          delay1ms(5);
  568.          sotp();      
  569. }
复制代码
回复

使用道具 举报

6#
ID:145713 发表于 2017-10-2 21:16 | 只看该作者
剛好我也需要,抓來試用...
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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