Arduino:利用DS3231RTC芯片、TM1637数码管、LCD1602 制作时钟
topic
- 本文中所使用库文件
- 参考
- DS3231
- 模块参数:
- 接线说明(以Arduino uno r3为例):
- 库文件函数
- 完整代码
- 准备
- 1. 修改`SevenSegmentExtended`库文件
- 代码
- 说明
本文中所使用库文件
- 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
参考
- Arduino使用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 5LiquidCrystal_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
// #endifSerial.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/88365305if (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());
}
说明
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
