Arduino:利用DS3231RTC芯片、TM1637数码管、LCD1602 制作时钟

本文中所使用库文件

参考

  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 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());
}

说明

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蔚蓝慕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值