立即注册 找回密码

微雪课堂

搜索
微雪课堂 外围模块 Accessory Shield 查看内容

Accessory Shield学习7:高精度实时时钟(DS3231)

2015-5-7 15:38| 发布者: yanwl| 查看: 4020| 评论: 0

摘要: 本章讲一个跟小伙伴生活息息相关的技能——时钟!原理大放送: 主角名叫DS3231,是一款低成本、高精度 I2C 实时时钟( RTC),具有集成的温补晶体振荡器( TCXO)和晶体。该器件包含电池输入端,断开主电源时仍可保 ...
本章讲一个跟小伙伴生活息息相关的技能——时钟!

原理大放送:
主角名叫DS3231,是一款低成本、高精度 I2C 实时时钟( RTC),具有集成的温补晶体振荡器( TCXO和晶体。该器件包含电池输入端,断开主电源时仍可保持精确的计时。集成的晶体振荡器大大提高了器件的长期精确度。该时钟可以记录秒、分、时、星期、日期、月和年信息,少于 31 天的月份,将自动调整月末日期,包括闰年补偿。
芯片特性:
  • 工作电压:2.3V -- 5.5V
  • 工作温度范围:0℃ - 70℃(商用级),-40℃ - 85℃(工业级)
  • 0℃ - 40℃精度为±2ppm
  • -40℃ - 85℃精度为±3.5ppm 
关于它的精度,通俗来讲就是:每天的计时误差在0.3秒以内,一年不超过2分钟!

应用电路非常简单,只需要一个电源滤波电容即可,编程时注意硬件地址


代码示例:

#include "Wire.h"
#include "ds3231.h"

#define BUFF_MAX 128
#define CMD_BUFF 20

uint8_t time[8];
unsigned long prev, interval = 1000;
struct ts t;

char cmd_buff[CMD_BUFF];
unsigned char count = 0, time_tick;
unsigned char cmd_flag = 0;
unsigned char u8_temp, i;
unsigned short u16_temp;

void setup()
{
    Serial.begin(9600);
    Wire.begin();
    DS3231_init(DS3231_INTCN);                                          //interrupt enable
}

void loop()
{
    char in;
    char buff[BUFF_MAX];
    unsigned long now = millis();

    // show time once in a while
    if ((now - prev) > interval) 
    {
        DS3231_get(&t);
        
        snprintf(buff, BUFF_MAX, "%d.%02d.%02d %02d:%02d:%02d", t.year,
             t.mon, t.mday, t.hour, t.min, t.sec);
             
        Serial.println(buff);
        prev = now;
        
        time_tick++;
    }
    
    /*
    error process
    */
    if((time_tick >= 2) && (cmd_flag == 1))
    {
      cmd_flag = 0;
      count = 0;
    }
        
    /*
    if conf time and date
    */
    if(Serial.available())
    {
      if(cmd_flag == 0)
      {
        in = Serial.read();
        if(in == '0')
        {
          cmd_flag = 1;
          time_tick = 0;
        }
      }
      else
      {
        cmd_buff[count++] = Serial.read();
        if(count >= 14)                                    //decode and set time 
        {
          cmd_flag = 0;
          count = 0;
          
          for(i = 0; i < 14; i++)
          {
            cmd_buff[i] -= '0';
          }
          /*
          year
          */
          u16_temp = 0;
          u16_temp += cmd_buff[0] * 1000;
          u16_temp += cmd_buff[1] * 100;
          u16_temp += cmd_buff[2] * 10;
          u16_temp += cmd_buff[3];
          t.year = u16_temp;
          
          /*
          month
          */
          u8_temp = 0;
          u8_temp += cmd_buff[4] * 10;
          u8_temp += cmd_buff[5];
          t.mon = u8_temp;
          
          /*
          day
          */
          u8_temp = 0;
          u8_temp += cmd_buff[6] * 10;
          u8_temp += cmd_buff[7];
          t.mday = u8_temp;
          
          /*
          hour
          */
          u8_temp = 0;
          u8_temp += cmd_buff[8] * 10;
          u8_temp += cmd_buff[9];
          t.hour = u8_temp;
          
          /*
          minute
          */
          u8_temp = 0;
          u8_temp += cmd_buff[10] * 10;
          u8_temp += cmd_buff[11];
          t.min = u8_temp;
          
          /*
          second
          */
          u8_temp = 0;
          u8_temp += cmd_buff[12] * 10;
          u8_temp += cmd_buff[13];
          t.sec = u8_temp;
          
          DS3231_set(t);
        }
      }
    }
}

下载程序后打开串口调试助手,这个程序的功能比较腻害!提供两个功能:通过串口显示当前的时间;可以通过串口设置新的时间!重点讲下设置时间方式:

1 号箭头位置是待设置的新时间: 020150207143000,第 1 个字符为 0,后面跟年(2015)、月 (02)、日 (07)、时(14)、分(30)、秒(00)15 个字符, 输入完毕后,点击 2 号箭头发送,会看到新的时间已经写入。 注意:时间格式为 24 小时制;数据长度必须为 15 个字符,例如 2 月需要写成 02,其他数据段写法类似。


附件:

ds3231.zip


185

顶一下

刚表态过的朋友 (185 人)

相关阅读

最新评论

微雪官网|产品资料|手机版|小黑屋|微雪课堂. ( 粤ICP备05067009号 )

GMT+8, 2024-3-29 00:48 , Processed in 0.026352 second(s), 21 queries .

返回顶部