cancel
Showing results for 
Search instead for 
Did you mean: 

DS3231 RTC Time code not accurate

DRicc.2
Associate III

I've been recently trying to implement code to display the time in hours and minutes via the UART terminal. I've run into the issue where the time is inaccurate and increases by a minute every second and am not sure what is wrong with my code. 

I use the Nucleo L476RG and have PB6 as SCL, PB7 as SDA, PA2 as USART_TX, and PA3 as USART_RX.

 

Here is the clock configuration:

 

DRicc2_0-1739749129898.png

Here is the main code:

 

#include "main.h"
#include "uart.h"
#include <stdio.h>

#define DS3231_ADDRESS 0xD0

I2C_HandleTypeDef hi2c1;

UART_HandleTypeDef huart2;

char msg[100];

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
static void MX_USART2_UART_Init(void);

uint8_t decToBcd(int val)
{
  return (uint8_t)( (val/10*16) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
int bcdToDec(uint8_t val)
{
  return (int)( (val/16*10) + (val%16) );
}

typedef struct {
	uint8_t minutes;
	uint8_t hour;
} TIME;

TIME time;

// function to set time

void Set_Time (uint8_t min, uint8_t hour)
{
	uint8_t set_time[2];
	set_time[0] = decToBcd(min);
	set_time[1] = decToBcd(hour);
	HAL_I2C_Mem_Write(&hi2c1, DS3231_ADDRESS, 0x00, 1, set_time, 2, 1000);
}

void Get_Time (void)
{
	uint8_t get_time[2];
	HAL_I2C_Mem_Read(&hi2c1, DS3231_ADDRESS, 0x00, 1, get_time, 2, 1000);
	time.minutes = bcdToDec(get_time[0]);
	time.hour = bcdToDec(get_time[1]);

}


int main(void)
{


  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_USART2_UART_Init();

  //Set_Time(29, 06);

  while (1)
  {
	  Get_Time();
	  sprintf(msg, "%02d:%02d\r\n", time.hour, time.minutes);
	  uart_send_str(msg);
	  HAL_Delay(1000);

  }

}

 

 

The UART C file:

 

#include "main.h"
#include <stdio.h>
#include "uart.h"
#include <stdint.h>
#include <string.h>


void uart_send_str (const char* msg)
{
	HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
}

 

UART header file:

 

#define main_h
#ifndef uart_h
#define uart_h


void uart_send_str (const char* msg);

extern char msg[100];

extern UART_HandleTypeDef huart2;

#endif

 

Putty Output: 

DRicc2_1-1739749345910.png

 

1 ACCEPTED SOLUTION

Accepted Solutions

I got it to work but changed the command address from 0x00 to 0x01 for the set time and get time function.

View solution in original post

4 REPLIES 4
TDK
Guru

> I've run into the issue where the time is inaccurate and increases by a minute every second and am not sure what is wrong with my code.

Addresses 0 and 1 hold the seconds and minutes, not minutes and hours. The output shows the seconds increasing once per second. All is working correctly.

Hours are at address 0x02, which you don't read in the code, but you could if you read 3 bytes instead of 2.

TDK_0-1739764403635.png

 

If you feel a post has answered your question, please click "Accept as Solution".
mbarg.1
Senior

This is NOT an RTC problem as you did not enable RTC - nor did you choose an oscillator to drive RTC.

Enable RTC, select pre-scaler according to clock source, and will run OK.

OP is using an external 3rd-party RTC - the DS3231 !

I got it to work but changed the command address from 0x00 to 0x01 for the set time and get time function.