本章讲一个跟小伙伴生活息息相关的技能——时钟! 原理大放送: 主角名叫DS3231,是一款低成本、高精度 I2C 实时时钟( RTC),具有集成的温补晶体振荡器( TCXO)和晶体。该器件包含电池输入端,断开主电源时仍可保持精确的计时。集成的晶体振荡器大大提高了器件的长期精确度。该时钟可以记录秒、分、时、星期、日期、月和年信息,少于 31 天的月份,将自动调整月末日期,包括闰年补偿。 芯片特性:
关于它的精度,通俗来讲就是:每天的计时误差在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,其他数据段写法类似。 附件: |