Home | Projects | Notes > MCU Peripheral Drivers > Application: Real-Time Clock on LCD (rtc_on_lcd.c)
rtc_on_lcd.c)
rtc_on_lcd.cxxxxxxxxxx3411/*******************************************************************************2 * Filename : rtc_on_lcd.c3 * Description : Application to read time and date information from DS1207 RTC4 * chip and display it on the 16x2 Character LCD5 * Author : Kyungjae Lee6 * History : Jun 25, 2023 - Created file7 ******************************************************************************/8
91011/* strlen() */12/* printf() */1314
1516
17/* SysTick timer registers */181920
21/* SysTick Control and Status Register (SYST_CSR) bit fields */22/* Counter enabled */2324/* Processor clock */25
26/* Comment this out if LCD is not installed */27
28/* Function prototypes */29void DisplayPrologue(void);30char* TimeToString(RTC_Time_TypeDef *rtcTime);31char* DateToString(RTC_Date_TypeDef *rtcDate);32char* GetDay(uint8_t dayCode);33void NumToString(uint8_t num, char *buf);34void SysTickTimer_Init(uint32_t tickHz);35void DelayMs(uint32_t delayInMs);36
37
38int main(int argc, char *argv[])39{40 RTC_Time_TypeDef currTime;41 RTC_Date_TypeDef currDate;42 char *amPm;43
44 printf("Application running with LCD...\n");45
4647 printf("Application running without LCD...\n");4849 /* Initialize LCD module */50 LCD_Init();51
52 /* Display the project title and the name of the author */53 DisplayPrologue();5455
56 /* Initialize Tiny RTC module */57 if (DS1307_Init())58 {59 /* RTC initialization was unsuccessful */60 printf("RTC init failed\n");61
62 while (1);63 }64
65 /* Initialize the SysTick Timer so it generates 1 interrupt per second */66 SysTickTimer_Init(1);67
68 /* Configure initial date and time to set */69 currDate.day = FRIDAY;70 currDate.date = 14;71 currDate.month = 7;72 currDate.year = 23; /* Only the last two digits of the year */73
74 currTime.hours = 11;75 currTime.minutes = 59;76 currTime.seconds = 50;77 currTime.timeFormat = TIME_FORMAT_12HRS_PM;78
79 /* Set initial time and date */80 DS1307_SetCurrentDate(&currDate);81 DS1307_SetCurrentTime(&currTime);82
83 /* Get initial time and date */84 DS1307_GetCurrentDate(&currDate);85 DS1307_GetCurrentTime(&currTime);86
87 /* Print current time ----------------------------------------------------*/88
89 if (currTime.timeFormat != TIME_FORMAT_24HRS)90 {91 /* 12HRS format (e.g., 08:33:45 PM) */92 amPm = (currTime.timeFormat) ? "PM" : "AM";93
9495 printf("Current time = %s %s\n", TimeToString(&currTime), amPm);9697 LCD_SetCursor(2, 1);98 LCD_PrintString(TimeToString(&currTime));99 LCD_PrintString(" ");100 LCD_PrintString(amPm);101102 }103 else104 {105 /* 24HRS format (e.g., 20:33:45) */106
107108 printf("Current time = %s\n", TimeToString(&currTime));109110 LCD_PrintString(TimeToString(&currTime));111112 }113
114 /* Print current date in 'MM/DD/YY Day' format ---------------------------*/115
116117 printf("Current date = %s %s\n", DateToString(&currDate), GetDay(currDate.day));118119 LCD_SetCursor(1, 1);120 LCD_PrintString(DateToString(&currDate));121 LCD_PrintString(" ");122 LCD_PrintString(GetDay(currDate.day));123124
125 while (1);126
127 return 0;128} /* End of main */129
130/**131 * DisplayPrologue()132 * Desc. : Displays the project title and the author's name133 * Param. : None134 * Returns : None135 * Note : N/A136 */137void DisplayPrologue(void)138{139 /* Display the project title */140 LCD_PrintString("Real-time clock");141 LCD_SetCursor(2, 1);142 LCD_PrintString("on 16x2 LCD");143
144 /* Introduce inter-frame delay */145 DelayMs(3000);146
147 /* Clear display */148 LCD_ClearDisplay();149 LCD_ReturnHome();150
151 /* Display the author's name */152 LCD_PrintString("by");153 LCD_SetCursor(2, 1);154 LCD_PrintString("Kyungjae Lee");155
156 DelayMs(3000);157
158 /* Clear display */159 LCD_ClearDisplay();160 LCD_ReturnHome();161} /* End of DisplayPrologue */162
163/**164 * TimeToString()165 * Desc. : Converts the time represented by @rtcTime to a string166 * Param. : @rtcTime - pointer to RTC Time structure167 * Return : Time in string format (e.g., HH:MM:SS PM)168 * Note : N/A169 */170char* TimeToString(RTC_Time_TypeDef *rtcTime)171{172 static char buf[9]; /* Make it static not to return a dangling ptr */173
174 buf[2] = ':';175 buf[5] = ':';176
177 NumToString(rtcTime->hours, buf);178 NumToString(rtcTime->minutes, &buf[3]);179 NumToString(rtcTime->seconds, &buf[6]);180
181 buf[8] = '\0';182
183 return buf;184} /* End of TimeToString */185
186/**187 * DateToString()188 * Desc. : Converts the date represented by @rtcDate to a string189 * Param. : @rtcDate - pointer to RTC Date structure190 * Return : Date in string format (e.g., MM/DD/YY <Day>)191 * Note : N/A192 */193char* DateToString(RTC_Date_TypeDef *rtcDate)194{195 static char buf[9]; /* Make it static not to return a dangling ptr */196
197 buf[2] = '/';198 buf[5] = '/';199
200 NumToString(rtcDate->month, buf);201 NumToString(rtcDate->date, &buf[3]);202 NumToString(rtcDate->year, &buf[6]);203
204 buf[8] = '\0';205
206 return buf;207} /* End of DateToString */208
209/**210 * GetDay()211 * Desc. : Gets the day represented by @dayCode in string format212 * Param. : @dayCode - day macro213 * Return : Day in string format (e.g., Sunday)214 * Note : N/A215 */216char* GetDay(uint8_t dayCode)217{218 char *days[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};219
220 return days[dayCode];221} /* End of GetDay */222
223/**224 * NumToString()225 * Desc. : Converts the passed uint8_t number @num and store it into @buf226 * Param. : @num - a number to be converted into a string227 * @buf - pointer to a string buffer228 * Return : None229 * Note : N/A230 */231void NumToString(uint8_t num, char *buf)232{233 if (num < 10)234 {235 buf[0] = '0';236 buf[1] = num + '0';237 //buf[1] = num + 48;238 }239 else if (10 <= num && num < 99)240 {241 buf[0] = num / 10 + '0';242 buf[1] = num % 10 + '0';243 //buf[0] = num / 10 + 48;244 //buf[1] = num % 10 + 48;245 }246} /* End of NumToString */247
248/**249 * SysTickTimer_Init()250 * Desc. : Initializes the SysTick Timer251 * Param. : @tickHz - number of interrupts to be triggered per second252 * Return : None253 * Note : Counting down to zero asserts the SysTick exception request.254 */255void SysTickTimer_Init(uint32_t tickHz)256{257 /* Calculate reload value */258 uint32_t reloadVal = (SYSTICK_TIM_CLK / tickHz) - 1;259
260 /* Clear the least significant 24 bits in the SYST_RVR */261 SYST_RVR &= ~0x00FFFFFF;262
263 /* Load the counter start value into SYST_RVR */264 SYST_RVR |= reloadVal;265
266 /* Configure SYST_CSR */267 SYST_CSR |= (SYST_CSR_TICKINT | SYST_CSR_CLKSOURCE | SYST_CSR_ENABLE);268 /* TICKINT : Enable SysTick exception request */269 /* CLKSOURCE: Specify clock source; processor clock source */270 /* ENABLE : Enable counter */271} /* End of SysTickTimer_Init */272
273/**274 * SysTick_Handler()275 * Desc. : Handles the SysTick exception276 * Param. : None277 * Return : None278 * Note : N/A279 */280void SysTick_Handler(void)281{282 RTC_Time_TypeDef currTime;283 RTC_Date_TypeDef currDate;284 char *amPm;285
286 /* Print current time ----------------------------------------------------*/287
288 DS1307_GetCurrentTime(&currTime);289
290 if (currTime.timeFormat != TIME_FORMAT_24HRS)291 {292 /* 12HRS format (e.g., 08:33:45 PM) */293 amPm = (currTime.timeFormat) ? "PM" : "AM";294
295296 printf("Current time = %s %s\n", TimeToString(&currTime), amPm);297298 LCD_SetCursor(2, 1);299 LCD_PrintString(TimeToString(&currTime));300 LCD_PrintString(" ");301 LCD_PrintString(amPm);302303 }304 else305 {306 /* 24HRS format (e.g., 20:33:45) */307308 printf("Current time = %s\n", TimeToString(&currTime));309310 LCD_SetCursor(2, 1);311 LCD_PrintString(TimeToString(&currTime));312313 }314
315 /* Print current date in 'MM/DD/YY Day' format ---------------------------*/316
317 DS1307_GetCurrentDate(&currDate);318
319320 printf("Current date = %s <%s>\n", DateToString(&currDate), GetDay(currDate.day));321322 LCD_SetCursor(1, 1);323 LCD_PrintString(DateToString(&currDate));324 LCD_PrintString(" ");325 //LCD_PrintChar('<');326 LCD_PrintString(GetDay(currDate.day));327 //LCD_PrintChar('>');328329} /* End of SysTick_Handler */330
331/**332 * DelayMs()333 * Desc. : Spinlock delays for @delayInMs milliseconds334 * Param. : @delayInMs - time to delay in milliseconds335 * Returns : None336 * Note : N/A337 */338void DelayMs(uint32_t delayInMs)339{340 for (uint32_t i = 0; i < delayInMs * 1000; i++);341} /* End of DelayMs */