H753_CPP_I2C_DS3231_RTC_01 1.0
STM32H753 DS3231 real-time clock over I2C, with an AT24C32 EEPROM marker that stops the clock being set twice, built on the STM32_DS3231 and STM32_AT24C32 libraries
Loading...
Searching...
No Matches
H753_CPP_I2C_DS3231_RTC_01 Documentation

This documentation covers a STM32 NUCLEO-H753ZI tutorial project that reads a DS3231 real-time clock over I2C1 and prints the date and time on USART1. The clock is set once from the time the firmware was compiled, and a small marker kept in the AT24C32 EEPROM on the same ZS-042 module remembers that it was set, so a reset or a power cycle never sets it back. It builds on two reusable plain-C STM32 HAL libraries: STM32_DS3231 (the clock) and STM32_AT24C32 (the EEPROM).

Project Overview

The firmware demonstrates:

  • Starting two I2C devices on one bus, each checked at start-up: ds3231Init() and at24c32Init()
  • Deciding at every start-up whether to set the clock, see startClock (the clock is set when the EEPROM holds no marker (first run on this board) or when FORCE_SET_TIME is 1)
  • Taking the time from the compiler's DATE and TIME, see parseBuildTime and setClockFromBuildTime, with SET_TIME_OFFSET_SECONDS to cover the delay between compiling and running
  • A marker that survives a power loss during its own write: a magic number followed by its bitwise inverse, read back and checked after writing, see readClockMarker and writeClockMarker
  • Reporting the DS3231 oscillator stop flag, see reportOscillator
  • Redrawing the clock in place on one terminal row once a second with the cursor hidden, showing the day and month names from two string arrays (dayNames and monthNames), see printTime
  • Halting through Error_Handler() when a bus transfer fails for good, after the libraries have retried the failures that a second attempt can fix

Project-Level Documentation

  • main.c – the start-up sequence and the helper functions above
  • DS3231.h – the clock driver: time get and set, epoch conversion, oscillator stop flag
  • AT24C32.h – the EEPROM driver: read, and page-aware write with acknowledge polling

Hardware

A ZS-042 DS3231 module (the AT24C32 EEPROM is on the same board and shares SCL and SDA) on I2C1 of the NUCLEO-H753ZI: SCL on PB8 (Arduino D15), SDA on PB9 (Arduino D14). The terminal is USART1 at 19200 baud.

Power the module from the Nucleo's 3.3 V, not 5 V. The ZS-042 has a charging path from VCC through a 200 ohm resistor and a diode to the battery pin: at 5 V it pushes current into a non-rechargeable CR2032, which can leak or swell, and at 3.3 V the diode stays reverse-biased. Its pull-ups also go to the module's VCC, so at 5 V the I2C lines idle at 5 V, which many MCU pins and other bus devices do not tolerate. Both chips work from 3.3 V.

Settings

The behaviour is controlled by a few macros at the top of main.c: FORCE_SET_TIME (set the clock again from the build time even though the EEPROM marker exists, then set it back to 0), SET_TIME_OFFSET_SECONDS (seconds added to the build time to cover the compile-and-flash delay), CLOCK_ROW (terminal row of the clock), ANSI_HIDE_CURSOR (escape sequence that hides the cursor) and the three marker constants CLOCK_MARKER_ADDRESS, CLOCK_MARKER_MAGIC and CLOCK_MARKER_SIZE. Each is documented with its value in the file reference of main.c.

Setting the clock

  1. First run on a board: nothing to do. The EEPROM holds no marker, so the clock is set to the build time and the marker is written.
  2. Every later run, with FORCE_SET_TIME at 0: the marker is found and the clock is left alone.
  3. To set the clock again: set FORCE_SET_TIME to 1, build, run once, then set it back to 0 and rebuild, or every reset sets the clock back to that build time.

The chip holds the local time of the computer that compiled the project; there is no time-zone conversion. Do not flash an unchanged build with FORCE_SET_TIME at 1 later: the build time is the time main.c was compiled, so it would set a stale time.