How to display time on stm32-discovery
Asked Answered
L

2

7

I've been experimenting with the STM32-DISCOVERY a lot lately, but I'm not sure how to get started with an application for this board.

I want to show the time of the RTC on the stm32's display.

How do I get started with this? I have already installed the libraries for the STM32.

Les answered 17/2, 2014 at 16:33 Comment(0)
S
8

I'm not sure what exactly you mean by 'display' (i.e., is it an LCD screen, a serial output-terminal, etc?).

In any case, the RTC is typically connected to the STM32 through an I2C bus, so you will need to initialize both controllers (RTC and I2C) before you can get/set the date and the time on the RTC.

Here is how you can initialize the RTC controller:

void rtc_init()
{
    RTC_InitTypeDef RTC_InitStructure;
    RTC_TimeTypeDef RTC_TimeStruct;

    /* Enable the PWR clock */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);

    /* Allow access to RTC */
    PWR_BackupAccessCmd(ENABLE);

    /* Reset RTC Domain */
    RCC_BackupResetCmd(ENABLE);
    RCC_BackupResetCmd(DISABLE);

    /* Enable the LSE OSC */
    RCC_LSEConfig(RCC_LSE_ON);

    /* Wait until LSE is ready */
    while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);

    /* Select the RTC Clock Source */
    RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

    /* Configure the RTC data register and RTC prescaler */
    RTC_InitStructure.RTC_AsynchPrediv = 0x7F;
    RTC_InitStructure.RTC_SynchPrediv  = 0xFF;
    RTC_InitStructure.RTC_HourFormat   = RTC_HourFormat_24;
    RTC_Init(&RTC_InitStructure);

    /* Set the time to 00h 00mn 00s AM */
    RTC_TimeStruct.RTC_H12     = RTC_H12_AM;
    RTC_TimeStruct.RTC_Hours   = 0x00;
    RTC_TimeStruct.RTC_Minutes = 0x00;
    RTC_TimeStruct.RTC_Seconds = 0x00;
    RTC_SetTime(RTC_Format_BCD,&RTC_TimeStruct);
}

And here is how you can get/set the date and the time on the RTC, excluding day-of-the-week:

In the header file:

typedef struct
{
    unsigned char second;
    unsigned char minute;
    unsigned char hour;
    unsigned char day;
    unsigned char month;
    unsigned char year;
}
rtc_data_t;

void rtc_get(rtc_data_t* rtc_data);
void rtc_set(rtc_data_t* rtc_data);

In the source file:

#define SENSOR_ADDRESS 0xD0 // or set this according to your HW configuration

#define HEX_2_DEC(val) (((val)/16)*10+((val)%16))
#define DEC_2_HEX(val) (((val)/10)*16+((val)%10))

typedef struct
{
    unsigned char second;
    unsigned char minute;
    unsigned char hour;
    unsigned char weekday;
    unsigned char day;
    unsigned char month;
    unsigned char year;
}
raw_data_t;

void rtc_get(rtc_data_t* rtc_data)
{
    raw_data_t raw_data;
    i2c_polling_read(SENSOR_ADDRESS,0x00,sizeof(raw_data),(char*)&raw_data);
    rtc_data->second = HEX_2_DEC(raw_data.second);
    rtc_data->minute = HEX_2_DEC(raw_data.minute);
    rtc_data->hour   = HEX_2_DEC(raw_data.hour  );
    rtc_data->day    = HEX_2_DEC(raw_data.day   );
    rtc_data->month  = HEX_2_DEC(raw_data.month );
    rtc_data->year   = HEX_2_DEC(raw_data.year  );
}

void rtc_set(rtc_data_t* rtc_data)
{
    raw_data_t raw_data;
    raw_data.second = DEC_2_HEX(rtc_data->second);
    raw_data.minute = DEC_2_HEX(rtc_data->minute);
    raw_data.hour   = DEC_2_HEX(rtc_data->hour  );
    raw_data.day    = DEC_2_HEX(rtc_data->day   );
    raw_data.month  = DEC_2_HEX(rtc_data->month );
    raw_data.year   = DEC_2_HEX(rtc_data->year  );
    raw_data.weekday = RTC_Weekday_Monday; // or calculate the exact day
    i2c_polling_write(SENSOR_ADDRESS,0x00,sizeof(raw_data),(char*)&raw_data);
}

In addition to the initialization of the I2C controller, you will also need to implement the read/write routines.

UPDATE:

Given rtc_data_t* rtc_data, here is a Segger-GUI code for displaying HH:MM:SS on the LCD:

char text[16] = {0};
sprintf(text,"%.2u:%.2u:%.2u",rtc_data->hour,rtc_data->minute,rtc_data->second);
GUI_RECT gui_rect = {0,0,SCREEN_WIDTH-1,SCREEN_HEIGHT-1};
GUI_DispStringInRect(text,&gui_rect,GUI_TA_HCENTER|GUI_TA_VCENTER);

Of course, you will have to initialize the LCD controller itself...

Slesvig answered 20/2, 2014 at 14:35 Comment(5)
I am sorry for not defining my question very clear, it is indeed a LCD diplay on my STM32 I'm referring to. Thank you very much for this clear answer, I'll definitely will do some experimenting with this! Thanks a lot!Les
Can also give you the code for the LCD, if it's an SSD1351 that you're using.Slesvig
Are you using SSD1351?Slesvig
I am currently not using the SSD1351, I'm just really curious how you managed do display it on an external LCD display. I would really like to analyze your code!Les
OK, added to the answer, but I don't see how it can help you much. It is based on Segger-GUI, so unless you've purchased it from Segger, this code will not be of much use to you. In addition, it does not include the initialization of the LCD controller itself. Good luck :)Slesvig
N
4

Look at the RTC library. It should be called something "stm32f2xx_rtc.h". You must first enable the RTC.

For example, we're using a 32 KHz low-speed external crystal to run the RTC. We're executing the following to configure the RTC (F2 series micro):

/*** Clock Enable ***/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); // PWR clock must be enabled to access RTC and RTC backup registers

/*** Unlock RTC Registers ***/
PWR_BackupAccessCmd(ENABLE);     // Enable access to backup domain (RTC registers, RTC backup data registers, and backup SRAM)
RTC_WriteProtectionCmd(DISABLE); // Disable RTC register write protection

/*** RTC Enable ***/
RCC_LSEConfig(RCC_LSE_ON);              // Enable LSE (32.768 kHz low speed external) crystal
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); // Select LSE as RTC source
RCC_RTCCLKCmd(ENABLE);                  // Enable RTC

/*** Enter RTC Initialization Mode ***/
if(RTC_EnterInitMode() == ERROR)
    THROW(EXCODE_RTC_ENTER_INIT_MODE_ERROR);

/*** RTC Configuration ***/
/* Internal Clock Frequency                       */ 
/* (F_RTCCLK) / ((PREDIV_A + 1) * (PREDIV_S + 1)) */
/* Example: 32768 Hz / (128 * 256) = 1 Hz         */
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
RTC_InitStructure.RTC_AsynchPrediv = 127;
RTC_InitStructure.RTC_SynchPrediv = 255;
if(RTC_Init(&RTC_InitStructure) == ERROR)
{
    /*** Lock RTC Registers ***/
    RTC_ExitInitMode();             // Exit RTC initialization mode
    RTC_WriteProtectionCmd(ENABLE); // Enable RTC register write protection
    PWR_BackupAccessCmd(DISABLE);   // Disable access to backup domain (RTC registers, RTC backup data registers, and backup SRAM)
    THROW(EXCODE_RTC_INIT_ERROR);
}
Nisbet answered 17/2, 2014 at 16:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.