In this hands-on tutorial, learn how to interface the DS3231 RTC (Real-Time Clock) module with an STM32 microcontroller using STM32CubeIDE and display the time and date on an I²C LCD. Perfect for embedded systems and real-time clock projects!
🔗 Download the example code here: [https://controllerstech.com/ds3231-rtc-module-with-stm32/]
00:12Few months ago, I made a video about using internal RTC in STM32.
00:18Although, everything was pretty okay with that, there was the problem of storing time.
00:24Whenever the controller lost power, the RTC used to reset itself.
00:29Today, in this video, we are going to interface DS3231RTC module with STM32.
00:38As mentioned in the datasheet, you can use 2.3 to 5.5 volts to power the module.
00:50We can also use I2C in fast mode, or the standard mode to read, or write data.
00:58And then we have these registers, that we are going to write to, and read the time from.
01:08So, let's start with the cube IDE.
01:15Create a new project.
01:28I am using STM32F103C8 controller.
01:34Give a name to the project and click next.
01:53Just want to show you the firmware version at the time of making this video.
01:58Click finish and the cube MX will open.
02:05So, first things first.
02:06I am enabling the clock from the external crystal.
02:11Next, enable the I2C, and clock and data pins will be selected.
02:24This is how the connection will be.
02:27DS3231 is connected to the controller via I2C1.
02:33And PCF8574 is also connected to the same I2C bus, and then to the LCD.
02:40I want to run the clock at maximum.
02:43So, just type in 72, and hit enter.
02:51Go to sys, debug, and select serial wire.
02:56Click save, and the project will be generated.
03:09Here is the main .c file.
03:12First of all, we need to include the LCD library, because I want to display the time and date
03:18on the LCD.
03:20Copy the c file in the source, and header file in the include folders.
03:25You can get these files after you download the project from the link in the description.
03:31This address is defined for PCF8574, if you are using any other I2C extender, you have to change this.
03:52Let's include the header file in our project.
04:07If you look at the datasheet of the DS3231, you can find the I2C address.
04:13This is the address defined for the write cycle.
04:17In SDM32, the address should be 8 bit long.
04:21Which includes, 7 bits of the address, and 1 bit for the write.
04:26This makes up the address of the DS3231 as, 0 cross D0.
04:36Let's define that address.
04:41These are the functions to convert from BCD format to decimal format, and vice versa.
04:48The data written to the DS3231 must be in the binary coded decimal format, and that's why we need these functions.
05:01I am defining a structure to save the time and date, that we are going to read from the module.
05:18Now, let's write a function to set the time.
05:24The parameters are seconds, minutes, hour, day of week, day of month, month, and year.
05:32I am defining an array, to store 7 bytes of data.
05:44The data written to the module must be in this order.
05:47First time, then day of week, and at last, date.
06:02Basically, we have to write these 7 registers.
06:06First we need to convert these values to the BCD format using decimal to BCD converter.
06:12The array that I created, is going to store these BCD values for the respective register.
06:19Now we are going to write these values to the registers.
06:25We can do that by taking advantage of the fact that the address of the registers in the module will automatically increment with every write operation.
06:36So we just have to write 7 bytes to this first register.
06:41And the first 7 registers will be automatically written.
06:45I am using memory write function of how to write the data to the specific location in the memory.
06:52Device address, address of the register, size of address is 1 byte, the data that we want to write, size of data is 7 bytes, and timeout.
07:07Next, we need a function to read the time from the RTC.
07:11Again creating an array, to store the BCD values that we are going to receive from the RTC.
07:18I am using heli2cmem read to read the data from the memory.
07:23Device address, address of the memory.
07:29Size of address is 1 byte, where we want to store this data, how many bytes to read, and timeout.
07:45Address of the registers auto increments, and we get the reading from the first 7 registers.
07:52Next, we need to convert these values to the decimal format, and then store in the time structure.
08:05I am creating this buffer to store the equivalent characters, so that we can display the result on the LCD.
08:12In the main function, initialize the LCD.
08:16Then, inside the while loop, first we have to read the time, and then convert the numbers to the characters using sprintf function.
08:25Now, I am using this to import the slider, and we want to be able to write the redact number.
08:38Then, I want to show you some more useful in the graphics list.
08:42Here, everything will be done and we want to show you how we are done.
08:45First and if we want to show you some more useful.
08:49I am using that the right of the right of screen and it is using the right of the right.
08:53Put the cursor at 0,0, and display the time.
09:02Next, convert the date in the character format.
09:23Put the cursor in the next line, and display the date.
09:32I am giving 500 milliseconds delay between each refresh.
09:37We have to set the time first.
09:40I am setting it 20 seconds late than the actual time.
09:48Let's build this code.
09:50There seems to be some problem with sprintf.
10:00We have to include the sddio.h.
10:13I have to change the time again.
10:16Let's flash the code.
10:19Select sdm32.h.application.
10:25Run it for a little amount of time.
10:43Now we need to again flash the code, without the time setting line.
10:52So if we reset the controller in future, the time will not set to the same value again.
10:57Now it's time to see the actual working.
11:10The time and date is working as it should.
11:14Even if I try to reset the controller, the time continues to work properly.
11:18So I have disconnected them from the supply.
11:31The time is stored in the RTC now, and we can access it anytime we want.
11:37As you can see, it is around 9 seconds more than the last one.
11:46You need to have a battery, if you want to store the time.
11:50So, we saw how can we set, and read the time from the DS3231.
11:56Next, we are going to read the temperature from this module.
12:01As mentioned in the datasheet, addresses 11H, and 12H stores the temperature.
12:1811H stores the MSB of the temperature data, and 12H stores the LSB.
12:34GetTemp function is being used, to read the temperature.
12:37Basically, I am going to use Halmemory, to read 2 bytes of data from 11H address.
12:44Then we need to combine the MSB, and LSB.
12:57LSB must be shifted 6 places to the right.
13:01The result must be divided by 4 because the resolution is 0.25 degree Celsius per bit.
13:14There is one important piece of information before we read the temperature.
13:26The BSY bit in the status register.
13:30This bit goes to 1, when the conversion signal is given.
13:33Other than this, we have convert temperature bit, in the control register.
13:54Setting this bit to 1 will force the conversion.
13:57If we don't force the conversion, the temperature conversion would take place every 64 seconds
14:03by default.
14:10This is the function to force the conversion.
14:28This is the function to force the conversion.
14:32Here, first I am reading the status register.
14:49If the BSY bit is not set, read the control register.
15:17And write the modified value with the conversion bit as 1.
15:24I am going to force the conversion.
15:43Read the temperature, and store the value in temp variable.
15:47We need to again use sprintf to convert this value to the characters.
15:58To convert the float type numbers, we need to change the setup a bit.
16:12Go to project setting, C++ build, settings, tool setting.
16:25And enable the Uprintf float feature.
16:38Now send the buffer to the LCD.
16:45Now send the buffer to the LCD.
16:49Let's run the code now.
16:56So here we have the time, date, and temperature from the DS3231RTC module.
17:06If I hold the device, you can see the rise in temperature.
17:13Again, if I disconnect, the things would still be working fine.
17:38This is it guys.
17:41DS3231 still have few more features left to be covered.
17:47For example, it have two alarms, oscillator output, square wave output, etc.
17:53I will cover those in the next video.
17:57Real time was the important part, and so we have covered that today.
18:03I hope you understood the video.
18:06You can download the code from the link in the description.