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

参考

  1. Arduino使用TM1637四位数码管

DS3231

在这里插入图片描述

模块参数:

  1. 尺寸:38mm(长)*22mm(宽)*14mm(高)
  2. 重量:8g
  3. 工作电压:3.3–5.5V
  4. 时钟芯片:高精度时钟芯片DS3231
  5. 时钟精度:0-40℃范围内,精度2ppm,年误差约1分钟
  6. 带2个日历闹钟
  7. 可编程方波输出
  8. 实时时钟产生秒、分、时、星期、日期、月和年计时,并提供有效期到2100年的闰年补偿
  9. 芯片内部自带温度传感器,精度为±3℃
  10. 存储芯片:AT24C32(存储容量32K)
  11. IIC总线接口,最高传输速度400KHz(工作电压为5V时)
  12. 可级联其它IIC设备,24C32地址可通过短路A0/A1/A2修改,默认地址为0x57
  13. 带电池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());
}

说明


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部