DS3231实时时钟芯片

2019-07-25 13:46发布

大家谁用过DS3231实时时钟芯片,提供一下程序,谢谢了~!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
4条回答
xyz549040622
2019-07-25 21:37
  1. /***************************************************************************/
  2. /* DEMO3231.C                                                              */
  3. /***************************************************************************/
  4. #include        <stdio.h>               /* Prototypes for I/O functions */
  5. #include        <DS5000.h>              /* Register declarations for DS5000 */
  6. /************************* bit definitions ****************************/
  7. sbit    scl = P0^0;             /* I2C pin definitions */
  8. sbit    sda = P0^1;
  9. sbit    E = P1^0;               /* DCM LCD module control signal definitions */
  10. sbit    RS = P1^1;
  11. sbit    RW = P1^2;
  12. sbit    CLK = P2^5;             /* DS1267 control signal definitions */
  13. sbit    RSTb = P2^6;
  14. sbit    DQ = P2^7;
  15. sbit    int0 = P3^2;
  16. /**************************** defines *******************************/
  17. #define ADDRTC  0xd0    /* DS3231 slave address (write) */
  18. #define ACK     0
  19. #define NACK    1
  20. /*********************** Function Prototypes **************************/
  21. void    start();
  22. void    stop();
  23. uchar   i2cwrite(uchar d);
  24. uchar   i2cread(char);
  25. void    wr_dsp_dat(uchar);
  26. void    wr_dsp_ins(uchar);
  27. uchar   rd_dsp_ins();
  28. void    hex2asc(uchar);
  29. void    dsp_adj(uchar pos);
  30. void    init_dsp();
  31. void    writebyte();
  32. void    initialize_DS3231();
  33. void    disp_regs();
  34. void    rd_temp();
  35. void    frq_out_tog();
  36. void    init_alrm();
  37. void    comm_init();
  38. /************************* Global Variables ***************************/
  39. xdata   uchar   sec, min, hr, dy, dt, mn, yr;
  40. /**************************** functions ******************************/
  41. void start()            /* --------- Initiate start condition ---------- */
  42. {
  43.         sda = 1;  scl = 1;
  44.         sda = 0;
  45. }
  46. void stop()             /* ---------- Initiate stop condition ----------- */
  47. {
  48.         sda = 0;  sda = 0;
  49.         scl = 1;  scl = 1;  sda = 1;
  50. }
  51. uchar i2cwrite(uchar d)         /* ----------------------------- */
  52. {
  53. uchar i;

  54.         scl = 0;
  55.         for (i = 0;i < 8; i++)
  56.         {
  57.                 if (d & 0x80)
  58.                         sda = 1; /* Send the msbits first */
  59.                 else
  60.                         sda = 0;
  61.                 scl = 0;
  62.                 scl = 1;
  63.                 d = d << 1;     /* do shift here to increase scl high time */
  64.                 scl = 0;
  65.         }
  66.         sda = 1;        /* Release the sda line */
  67.         scl = 0;
  68.         scl = 1;
  69.         i = sda;
  70.         if (i) printf("Ack bit missing  %02X ",(unsigned int)d);
  71.         scl = 0;
  72.         return(i);
  73. }
  74. uchar i2cread(char b)   /* ----------------------------------- */
  75. {
  76. uchar i, d;

  77.         d = 0;
  78.         sda = 1;             /* Let go of sda line */
  79.         scl = 0;
  80.         for (i = 0; i < 8; i++) /* read the msb first */
  81.         {
  82.                 scl = 1;
  83.                 d = d << 1;
  84.                 d = d | (unsigned char)sda;
  85.                 scl = 0;
  86.         }
  87.         sda = b;          /* low for ack, high for nack */
  88.         scl = 1;
  89.         scl = 0;

  90.         sda = 1;          /* Release the sda line */
  91.         return d;
  92. }
  93. void    wr_dsp_dat(uchar dat)   /* -------- write one byte to the display --------- */
  94. {
  95.         P0 = dat;
  96.         RS = 1; /* data register */
  97.         RW = 0; /* write */
  98.         E = 1;
  99.         E = 0;          /* latch data in */
  100. }
  101. void    wr_dsp_ins(uchar dat)   /* ---- write one byte to the display instruction ----- */
  102. {
  103.         P0 = dat;
  104.         RS = 0; /* instruction register */
  105.         RW = 0; /* write */
  106.         E = 1;
  107.         E = 0;          /* latch data in */
  108. }
  109. uchar   rd_dsp_ins()    /* ---- read one byte from the instruction registers ----- */
  110. {
  111. uchar   dat;
  112.         P0 = 0xff;      /* set up for read */
  113.         RS = 0; /* instruction register */
  114.         RW = 1; /* read */
  115.         E = 1;
  116.         dat = P0;
  117.         E = 0;
  118.         return(dat);
  119. }
  120. void    init_dsp()      /* -------- initialize DMC-16207 LCD display ------- */
  121. {
  122.         while((rd_dsp_ins() & 0x80));   /* wait for display */

  123.         wr_dsp_ins(0x38);       /* Set 8-bit data, 2-line display, 5X7 font */
  124.         while((rd_dsp_ins() & 0x80));
  125.         wr_dsp_ins(0x0c);       /* Display on, cursor off, blink off */
  126.         while((rd_dsp_ins() & 0x80));
  127.         wr_dsp_ins(0x06);       /* Entry mode set: increment, no display shift */
  128.         while((rd_dsp_ins() & 0x80));
  129.         wr_dsp_ins(0x01);       /* clear display */
  130.         while((rd_dsp_ins() & 0x80));
  131.         wr_dsp_ins(0x80);       /* move to start of line 1 */
  132.         while((rd_dsp_ins() & 0x80));

  133.         wr_dsp_ins(0x50);       /* Set CG RAM address */
  134.         while((rd_dsp_ins() & 0x80));
  135.         wr_dsp_dat(0x07);       /* write 1st line of custom char to CG RAM */
  136.         while((rd_dsp_ins() & 0x80));
  137.         wr_dsp_dat(0x05);       /* write 2nd line */
  138.         while((rd_dsp_ins() & 0x80));
  139.         wr_dsp_dat(0x07);       /* write 3rd line */
  140.         while((rd_dsp_ins() & 0x80));
  141.         wr_dsp_dat(0x00);       /* write 4th line */
  142.         while((rd_dsp_ins() & 0x80));
  143.         wr_dsp_dat(0x00);       /* write 5th line */
  144.         while((rd_dsp_ins() & 0x80));
  145.         wr_dsp_dat(0x00);       /* write 6th line */
  146.         while((rd_dsp_ins() & 0x80));
  147.         wr_dsp_dat(0x00);       /* write 7th line */
  148.         while((rd_dsp_ins() & 0x80));
  149. }
  150. void    hex2asc(uchar hex)      /* -- convert the upper and lower nibbles to 2 ascii characters -- */
  151. {
  152.         if( ( (hex & 0xf0) >> 4) < 0x0a)
  153.                 wr_dsp_dat( ( (hex & 0xf0) >> 4) + 48 );        /* prints 0-9 */
  154.         else
  155.                 wr_dsp_dat( ( (hex & 0xf0) >> 4) + 55 );        /* prints A-F */
  156.         while((rd_dsp_ins() & 0x80));

  157.         if( (hex & 0x0f) < 0x0a)
  158.                 wr_dsp_dat( (hex & 0x0f) + 48 );
  159.         else
  160.                 wr_dsp_dat( (hex & 0x0f) + 55 );
  161.         while((rd_dsp_ins() & 0x80));
  162. }
  163. void    dsp_adj(uchar pos)      /* ------ adjust contrast on LCD display ------- */
  164. {
  165. char    inc;

  166.         RSTb = CLK = 0;                 /* initialize for 1st pass */
  167.         RSTb = 1;                               /* enable DS1267 */
  168.         DQ = 0;                         /* write stack select bit */
  169.         CLK = 1;                                /* toggle clk with data valid */
  170.         CLK = 0;

  171.         for (inc = 7; inc >= 0; inc--)  /* write wiper 0 */
  172.         {
  173.                 DQ = ((pos >> inc) & 0x01);     /* shift x bits left */
  174.                 CLK = 0;                        /* toggle clk with data valid */
  175.                 CLK = 1;
  176.         }
  177.         for (inc = 7; inc >= 0; inc--)  /* write wiper 1 */
  178.         {
  179.                 DQ = ((pos >> inc) & 0x01);     /* shift x bits left */
  180.                 CLK = 0;                        /* toggle clk with data valid */
  181.                 CLK = 1;
  182.         }
  183.         RSTb = 0;                               /* reset the 1267 (/RST & CLK low) */
  184.         CLK = 0;
  185. }
  186. void writebyte()        /* ----------------------------------------------- */
  187. {
  188. uchar Add, Data;

  189.         printf(" ADDRESS (hex):");             /* Get Address & Data */
  190.         scanf("%bx", &Add);
  191.         printf("DATA (hex):");
  192.         scanf("%bx", &Data);

  193.         start();
  194.         i2cwrite(ADDRTC);
  195.         i2cwrite(Add);
  196.         i2cwrite(Data);
  197.         stop();
  198. }
  199. void    initialize_DS3231()     /* ----- set time & date; user data entry ------ */
  200. /* Note: NO error checking is done on the user entries! */
  201. {
  202.         printf(" Enter the year (0-99): ");
  203.         scanf("%bx", &yr);
  204.         printf("Enter the month (1-12): ");
  205.         scanf("%bx", &mn);
  206.         printf("Enter the date (1-31): ");
  207.         scanf("%bx", &dt);
  208.         printf("Enter the day (1-7): ");
  209.         scanf("%bx", &dy);
  210.         printf("Enter the hour (1-23): ");
  211.         scanf("%bx", &hr);
  212.         /* hr = hr & 0x3f;      /* force clock to 24 hour mode */
  213.         printf("Enter the minute (0-59): ");
  214.         scanf("%bx", &min);
  215.         printf("Enter the second (0-59): ");
  216.         scanf("%bx", &sec);

  217.         start();
  218.         i2cwrite(ADDRTC);       /* write slave address, write 1339 */
  219.         i2cwrite(0x00); /* write register address, 1st clock register */
  220.         i2cwrite(sec);
  221.         i2cwrite(min);
  222.         i2cwrite(hr);
  223.         i2cwrite(dy);
  224.         i2cwrite(dt);
  225.         i2cwrite(mn);
  226.         i2cwrite(yr);
  227.         i2cwrite(0x10); /* enable sqw, 1hz output */
  228.         stop();
  229. }
  230. void    disp_regs()     /* --- display date/time on LCD display --- */
  231. {
  232. uchar   age, prv_sec=99;

  233.         while(!RI)      /* Read & Display Clock Registers */
  234.         {
  235.                 while(int0);    /* loop until int pin goes low */
  236.                 start();
  237.                 i2cwrite(ADDRTC);
  238.                 i2cwrite(0x0f);
  239.                 i2cwrite(0);            /* clear alarm flags */
  240.                 stop();

  241.                 start();
  242.                 i2cwrite(ADDRTC);
  243.                 i2cwrite(0);
  244.                 start();
  245.                 i2cwrite(ADDRTC | 1);
  246.                 sec = i2cread(ACK);
  247.                 min = i2cread(ACK);
  248.                 hr = i2cread(ACK);
  249.                 dy = i2cread(ACK);
  250.                 dt = i2cread(ACK);
  251.                 mn = i2cread(ACK);
  252.                 yr = i2cread(NACK);
  253.                 stop();

  254.                 wr_dsp_ins(0x80);       /* move to start of line 1 */
  255.                 while((rd_dsp_ins() & 0x80));
  256.                 hex2asc(yr);
  257.                 wr_dsp_dat('/');
  258.                 while((rd_dsp_ins() & 0x80));
  259.                 hex2asc(mn);
  260.                 wr_dsp_dat('/');
  261.                 while((rd_dsp_ins() & 0x80));
  262.                 hex2asc(dt);
  263.                 wr_dsp_dat(' ');
  264.                 while((rd_dsp_ins() & 0x80));
  265.                 hex2asc(dy);
  266.                 wr_dsp_dat(' ');
  267.                 while((rd_dsp_ins() & 0x80));

  268.                 start();
  269.                 i2cwrite(ADDRTC);
  270.                 i2cwrite(0x10);
  271.                 start();
  272.                 i2cwrite(ADDRTC | 1);
  273.                 age = i2cread(NACK);
  274.                 stop();

  275.                 wr_dsp_dat(' ');
  276.                 while((rd_dsp_ins() & 0x80));
  277.                 hex2asc(age);

  278.                 wr_dsp_ins(0xc0);       /* move to start of line 2 */
  279.                 while((rd_dsp_ins() & 0x80));
  280.                 hex2asc(hr);
  281.                 wr_dsp_dat(':');
  282.                 while((rd_dsp_ins() & 0x80));
  283.                 hex2asc(min);
  284.                 wr_dsp_dat(':');
  285.                 while((rd_dsp_ins() & 0x80));
  286.                 hex2asc(sec);

  287.                 rd_temp();
  288.         }
  289.         RI = 0;  /* Swallow keypress to exit loop */
  290. }
  291. void    rd_temp()       /* -------- display temperature -------- */
  292. {
  293. char    str[8];
  294. int     itemp;
  295. float   ftemp;

  296.         do
  297.         {
  298.                 start();
  299.                 i2cwrite(ADDRTC);
  300.                 i2cwrite(0x0e);         /* address of control register */
  301.                 start();
  302.                 i2cwrite(ADDRTC + 1);   /* send the device address for read */
  303.                 itemp = i2cread(NACK);  /* get the control register value */
  304.                 stop();
  305.         }       while(itemp & 0x20);            /* wait until CNVT bit goes inactive */

  306.         start();
  307.         i2cwrite(ADDRTC);
  308.         i2cwrite(0x11);                 /* address of temperature MSB */
  309.         start();
  310.         i2cwrite(ADDRTC + 1);           /* send the device address for read */
  311.         itemp = ( (int) i2cread(ACK) << 5 );
  312.         itemp += ( i2cread(NACK) >> 3);
  313.         stop();
  314.         if(itemp & 0x1000)      itemp += 0xe000;        /* if sign bit set, make 16 bit 2's comp */

  315.         ftemp = 0.03125 * (float) itemp;        /* convert to degrees C */
  316.         /* ftemp = ftemp * 9 / 5 + 32;  /* skip this if you don't want degrees F */

  317.         sprintf(str, "%5.2f", ftemp);

  318.         wr_dsp_ins(0xc9);                       /* go to line 2, column 10 */
  319.         while((rd_dsp_ins() & 0x80));
  320.         wr_dsp_dat(str[0]);
  321.         while((rd_dsp_ins() & 0x80));
  322.         wr_dsp_dat(str[1]);
  323.         while((rd_dsp_ins() & 0x80));
  324.         wr_dsp_dat(str[2]);
  325.         while((rd_dsp_ins() & 0x80));
  326.         wr_dsp_dat(str[3]);
  327.         while((rd_dsp_ins() & 0x80));

  328.         wr_dsp_dat(0x02);       /* display programed 3rd char in CG RAM */
  329.         while((rd_dsp_ins() & 0x80));
  330. }
  331. void    frq_out_tog()   /* --- toggle en32khz bit to enable/disable sqw --- */
  332. {
  333. uchar   val;

  334.         start();
  335.         i2cwrite(ADDRTC);
  336.         i2cwrite(0x0f);                 /* control/status reg address */
  337.         start();
  338.         i2cwrite(ADDRTC + 1);           /* send the device address for read */
  339.         val = i2cread(NACK);
  340.         stop();
  341.         val ^= 0x08;    /* toggle en32khz bit */
  342.         start();
  343.         i2cwrite(ADDRTC);
  344.         i2cwrite(0x0f);                 /* control/status reg address */
  345.         i2cwrite(val);
  346.         stop();
  347. }
  348. void    init_alrm()     /* --- enable alarm 1 for once-per-second --- */
  349. {
  350.         start();
  351.         i2cwrite(ADDRTC);
  352.         i2cwrite(7);            /* 1st alarm 1 reg address */
  353.         i2cwrite(0x80); /* mask alarm register */
  354.         i2cwrite(0x80);
  355.         i2cwrite(0x80);
  356.         i2cwrite(0x80);
  357.         stop();

  358.         start();
  359.         i2cwrite(ADDRTC);
  360.         i2cwrite(0x0e); /* control/status reg address */
  361.         i2cwrite(0x05); /* enable interrupts, alarm 1 output */
  362. }
  363. void    comm_init()     /* ------ reset DS3231 comm interface ------ */
  364. {
  365.         do      /* because the DS3231 I2C interface is active for both supplies */
  366.         {       /*  after a micro reset, we must get the comm into a known state */
  367.                 sda = 1;        /* make sure master has released SDA */
  368.                 scl = 1;
  369.                 if(sda) /* if sda is high, generate a start */
  370.                 {
  371.                         sda = 0;        /* The DS3231 will recognize a valid start */
  372.                         sda = 1;        /*  condition anywhere in a I2C data transfer */
  373.                 }
  374.                 scl = 0;
  375.         }       while(sda == 0);        /* if the DS3231 is holding sda low, try again */
  376. }
  377. void    main    (void)  /* ------------------------------------------------ */
  378. {
  379. uchar i, M, M1;

  380.         dsp_adj(0x10);  /* adjust contrast on LCD display */
  381.         init_dsp();             /* initialize LCD display */
  382.         comm_init();
  383.         init_alrm();            /* enable alarm */
  384.         disp_regs();

  385.         while(1)
  386.         {
  387.                 printf(" DS3231 build date: %s ", __DATE__);
  388.                 printf("I Init DS3231 S Show temp ");
  389.                 printf("R Read Time   W Write Byte ");
  390.                 printf("F Frq out     D Display adj ");
  391.                 printf("Enter Menu Selection: ");

  392.                 M = _getkey();

  393.                 switch(M)
  394.                 {
  395.                         case 'D':
  396.                         case 'd':       printf("val: ");        scanf("%bx", &M1);
  397.                                         dsp_adj(M1);    break;

  398.                         case 'F':
  399.                         case 'f':       frq_out_tog();  break;

  400.                         case 'I':
  401.                         case 'i':       initialize_DS3231();    break;

  402.                         case 'R':
  403.                         case 'r':       disp_regs();    break;

  404.                         case 'S':
  405.                         case 's':       rd_temp();      break;

  406.                         case 'W':
  407.                         case 'w':       writebyte();    break;
  408.                 }
  409.         }
复制代码
美信官网找的例程

一周热门 更多>