本文中所使用庫文件
- TM1637庫:https://github.com/bremme/arduino-tm1637
- DS3231庫:https://github.com/adafruit/RTClib
- LiquidCrystal-I2C庫:https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library
- 一個很簡單的TM1637庫:https://github.com/AKJ7/TM1637
參考
DS3231
模塊參數:
- 尺寸:38mm(長)*22mm(寬)*14mm(高)
- 重量:8g
- 工作電壓:3.3–5.5V
- 時鐘芯片:高精度時鐘芯片DS3231
- 時鐘精度:0-40℃範圍內,精度2ppm,年誤差約1分鐘
- 帶2個日曆鬧鐘
- 可編程方波輸出
- 實時時鐘產生秒、分、時、星期、日期、月和年計時,並提供有效期到2100年的閏年補償
- 芯片內部自帶溫度傳感器,精度爲±3℃
- 存儲芯片:AT24C32(存儲容量32K)
- IIC總線接口,最高傳輸速度400KHz(工作電壓爲5V時)
- 可級聯其它IIC設備,24C32地址可通過短路A0/A1/A2修改,默認地址爲0x57
- 帶電池CR2032,保證系統斷電後,時鐘任然正常走動
接線說明(以Arduino uno r3爲例):
- SCL→A5
- SDA→A4
- VCC→5V
- GND→GND
庫文件函數
完整代碼
準備
1. 修改SevenSegmentExtended
庫文件
在bremme/arduino-tm1637的SevenSegmentExtended
庫中添加了一個功能
void SevenSegmentExtended::changeColonStatus(uint8_t hour,bool status) {
uint8_t cmd[2];
bool colonWasOn = getColonOn();
setColonOn(status);
cmd[0] = TM1637_COM_SET_ADR | 1;
cmd[1]= encode(int16_t(hour % 10));
cmd[1]|=(_colonOn)?TM1637_COLON_BIT:0;
command(cmd, 2);
// setColonOn(colonWasOn);
};
此函數的功能是爲了設置colon的顯示狀態。此函數應該繼續改進,可參考https://github.com/AKJ7/TM1637庫中相應功能
代碼
#include "Wire.h"
#include "LiquidCrystal_I2C.h" //lcd顯示庫
#include "RTClib.h" //DS3231產生時間並保持時鐘與世界時間同步。
#include "SevenSegmentTM1637.h" //數碼管的庫
#include "SevenSegmentExtended.h"
#define INTERVAL_TIME 1000000;
#define BAUD 115200 //串口波特率
#define BOARD_LED_PIN 13 //板載led接口
#define TM_CLK 4
#define TM_DIO 5
LiquidCrystal_I2C lcd(0x3f, 16, 2); //我用的1602顯示屏I2C地址是0x3f
RTC_DS3231 rtc; //默認地址爲0x57
SevenSegmentExtended tm1637(TM_CLK, TM_DIO);
unsigned long prevTime = 0;
unsigned long intervalTime = 1000000; //1000ms
char daysOfTheWeek[7][4] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; //二維數組,
//int8_t timeDisplay[4] = {0, 0, 0, 0};
bool clockPoint = true;
unsigned char secondOfRtc;
unsigned char minuteOfRtc;
unsigned char hourOfRtc;
unsigned char dayOfRtc;
unsigned char monthOfRtc;
unsigned int yearOfRtc;
unsigned char weekOfRtc;
float temperatureOfRtc = 0;
unsigned long updateDayInterval = 0;
unsigned char updateMinuteInterval = 0;
String dateStr;
String temperatureStr;
void alertBlink(unsigned int t, unsigned long deltms); //讓13口led閃爍,
void (*resetFunc)(void) = 0; //控制主控板自動重啓
void setup()
{
//#ifndef ESP8266
// while (!Serial)
; //for Leonardo/Micro/Zero
// #endif
Serial.begin(BAUD);
// delay(3000);
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)) + TimeSpan(0, 0, 0, 10));
if (rtc.lostPower()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)) + TimeSpan(0, 0, 0, 10)); //設置rtc芯片的初始時間
}
pinMode(BOARD_LED_PIN, OUTPUT);
lcd.begin();
lcd.backlight();
lcd.print("Hello!");
updateDateTime();
lcdDisplay();
tm1637.begin();
tm1637.setBacklight(100);
tm1637.printTime(hourOfRtc, minuteOfRtc, true);
prevTime = micros();
}
void loop()
{
//這裏要注意此等式的寫法不能寫成micros()>= prevTime + intervalTime
// 具體分析參考:https://blog.csdn.net/acktomas/article/details/88365305
if (micros() - prevTime >= intervalTime) {
updateDayInterval++;
updateMinuteInterval++;
prevTime = micros();
updateDateTime();
if (updateDayInterval > 86400) { //一天86400秒
updateDayInterval = 1;
lcdDisplay();
}
if (updateMinuteInterval > 60) {
updateMinuteInterval = 1;
tm1637.printTime(hourOfRtc, minuteOfRtc, false);
}
clockPoint = !clockPoint;
tm1637.changeColonStatus(hourOfRtc, clockPoint);
// timeDisplay();
// tm1637.printTime(hourOfRtc, minuteOfRtc, false);
Serial.println(clockPoint);
}
}
/**
功能:讓板載led以一定的時間間隔閃爍
t:閃爍次數,當t=0時,不閃爍,一直亮。
deltms:閃爍間隔的毫秒數。
*/
void alertBlink(unsigned int t, unsigned long deltms)
{
if (t == 0)
digitalWrite(BOARD_LED_PIN, HIGH);
for (int i = 0; i < t; i++)
{
digitalWrite(BOARD_LED_PIN, HIGH);
delay(deltms);
digitalWrite(BOARD_LED_PIN, LOW);
delay(deltms);
}
}
void updateDateTime() {
DateTime now = rtc.now();
yearOfRtc = now.year();
monthOfRtc = now.month();
dayOfRtc = now.day();
hourOfRtc = now.hour();
minuteOfRtc = now.minute();
secondOfRtc = now.second();
temperatureOfRtc = rtc.getTemperature();
weekOfRtc = now.dayOfTheWeek();
}
String getDateString() {
return String("") + yearOfRtc + "-" + monthOfRtc + "-" + dayOfRtc + " " + daysOfTheWeek[weekOfRtc];
}
String getTemperatureString() {
return String("Temp:") + temperatureOfRtc + " C";
}
void timeDisplay() {
tm1637.changeColonStatus(hourOfRtc, clockPoint);
tm1637.printTime(hourOfRtc, minuteOfRtc, false);
}
void lcdDisplay() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(getDateString());
lcd.setCursor(0, 1);
lcd.print(getTemperatureString());
}