Home | Projects | Notes > MCU Peripheral Drivers > Application: Real-Time Clock on LCD (rtc_on_lcd.c
)
rtc_on_lcd.c
)
rtc_on_lcd.c
xxxxxxxxxx
3411/*******************************************************************************
2 * Filename : rtc_on_lcd.c
3 * Description : Application to read time and date information from DS1207 RTC
4 * chip and display it on the 16x2 Character LCD
5 * Author : Kyungjae Lee
6 * History : Jun 25, 2023 - Created file
7 ******************************************************************************/
8
9
10
11/* strlen() */
12/* printf() */
13
14
15
16
17/* SysTick timer registers */
18
19
20
21/* SysTick Control and Status Register (SYST_CSR) bit fields */
22/* Counter enabled */
23
24/* 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
46
47 printf("Application running without LCD...\n");
48
49 /* Initialize LCD module */
50 LCD_Init();
51
52 /* Display the project title and the name of the author */
53 DisplayPrologue();
54
55
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
94
95 printf("Current time = %s %s\n", TimeToString(&currTime), amPm);
96
97 LCD_SetCursor(2, 1);
98 LCD_PrintString(TimeToString(&currTime));
99 LCD_PrintString(" ");
100 LCD_PrintString(amPm);
101
102 }
103 else
104 {
105 /* 24HRS format (e.g., 20:33:45) */
106
107
108 printf("Current time = %s\n", TimeToString(&currTime));
109
110 LCD_PrintString(TimeToString(&currTime));
111
112 }
113
114 /* Print current date in 'MM/DD/YY Day' format ---------------------------*/
115
116
117 printf("Current date = %s %s\n", DateToString(&currDate), GetDay(currDate.day));
118
119 LCD_SetCursor(1, 1);
120 LCD_PrintString(DateToString(&currDate));
121 LCD_PrintString(" ");
122 LCD_PrintString(GetDay(currDate.day));
123
124
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 name
133 * Param. : None
134 * Returns : None
135 * Note : N/A
136 */
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 string
166 * Param. : @rtcTime - pointer to RTC Time structure
167 * Return : Time in string format (e.g., HH:MM:SS PM)
168 * Note : N/A
169 */
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 string
189 * Param. : @rtcDate - pointer to RTC Date structure
190 * Return : Date in string format (e.g., MM/DD/YY <Day>)
191 * Note : N/A
192 */
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 format
212 * Param. : @dayCode - day macro
213 * Return : Day in string format (e.g., Sunday)
214 * Note : N/A
215 */
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 @buf
226 * Param. : @num - a number to be converted into a string
227 * @buf - pointer to a string buffer
228 * Return : None
229 * Note : N/A
230 */
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 Timer
251 * Param. : @tickHz - number of interrupts to be triggered per second
252 * Return : None
253 * 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 exception
276 * Param. : None
277 * Return : None
278 * Note : N/A
279 */
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
295
296 printf("Current time = %s %s\n", TimeToString(&currTime), amPm);
297
298 LCD_SetCursor(2, 1);
299 LCD_PrintString(TimeToString(&currTime));
300 LCD_PrintString(" ");
301 LCD_PrintString(amPm);
302
303 }
304 else
305 {
306 /* 24HRS format (e.g., 20:33:45) */
307
308 printf("Current time = %s\n", TimeToString(&currTime));
309
310 LCD_SetCursor(2, 1);
311 LCD_PrintString(TimeToString(&currTime));
312
313 }
314
315 /* Print current date in 'MM/DD/YY Day' format ---------------------------*/
316
317 DS1307_GetCurrentDate(&currDate);
318
319
320 printf("Current date = %s <%s>\n", DateToString(&currDate), GetDay(currDate.day));
321
322 LCD_SetCursor(1, 1);
323 LCD_PrintString(DateToString(&currDate));
324 LCD_PrintString(" ");
325 //LCD_PrintChar('<');
326 LCD_PrintString(GetDay(currDate.day));
327 //LCD_PrintChar('>');
328
329} /* End of SysTick_Handler */
330
331/**
332 * DelayMs()
333 * Desc. : Spinlock delays for @delayInMs milliseconds
334 * Param. : @delayInMs - time to delay in milliseconds
335 * Returns : None
336 * Note : N/A
337 */
338void DelayMs(uint32_t delayInMs)
339{
340 for (uint32_t i = 0; i < delayInMs * 1000; i++);
341} /* End of DelayMs */