2025-02-16 03:44 PM
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:
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:
Solved! Go to Solution.
2025-02-18 03:58 PM
I got it to work but changed the command address from 0x00 to 0x01 for the set time and get time function.
2025-02-16 07:53 PM
> 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.
2025-02-16 10:22 PM
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.
2025-02-17 04:46 AM
OP is using an external 3rd-party RTC - the DS3231 !
2025-02-18 03:58 PM
I got it to work but changed the command address from 0x00 to 0x01 for the set time and get time function.