1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
|
#include <stdio.h> // included for sprintf
#include "conf.h" //Configuration settings
#include "main.h" //Declarations for main
#include "lcd.h" //Declaratons for LCD
#include "i2c.h"
#include "ds3231.h" //Declarations for RTC
#include "beep.h" //Declarations for BEEP
#ifdef DEBUG
#include "uart.h" //Declarations for UART
#include "term.h" //Declarations for Escape codes
#endif
int main() {
TRISC = 0x00; // Set PORTC as outputs
PORTC = 0x00; // Set all PORTC pins LOW
TRISD = 0x00; // Set PORTD as outputs
PORTD = 0x00; // Set all PORTD pins LOW
#ifdef DEBUG
Initialize_UART(); //Initialize UART module
UART_send_string(CLS); // Clear screen
UART_send_string(CURSOR(12, 23)); // Set cursor at line 12, column 23
UART_send_string(GREEN); // Set Green
UART_send_string("UART Module Initialized and active\r\n");
UART_send_string(CLRATTR); // No color
#endif
I2C_Master_Init(100000); // Init I2C Master with 100KHz Clock
#ifdef DEBUG
UART_send_string(CURSOR(13, 24)); // Set cursor at line 12, column 23
UART_send_string(GREEN); // Set Green
UART_send_string("I2C Module Initialized and active\r\n");
UART_send_string(CLRATTR); // No color
#endif
Lcd_Init();
#ifdef DEBUG
UART_send_string(CURSOR(14, 24)); // Set cursor at line 12, column 23
UART_send_string(GREEN); // Set Green
UART_send_string("LCD Module Initialized and active\r\n");
UART_send_string(CLRATTR); // No color
#endif
#ifdef VFD
Vfd_Set_Brightness(0); //Max brightness 3 - minimum
#endif
display_Intro();
display_Lcd_Layout();
// Set an initial date time
//Set_Time_Date();
//Set_Time();
//Set_Date();
//Set_DayOfWeek();
// Write default alarm values
/*UART_send_string("Setting Alarm1 and Alarm2\r\n");
alarm1_min = 30;
alarm1_hour = 16;
alarm2_min = 40;
alarm2_hour = 16;
UART_send_string("Writing Alarms\r\n");
Write_Alarms();*/
#ifdef VFD
Vfd_Set_Brightness(3); //Max brightness 3 - minimum
#endif
while (1) {
// Set time and date variables from DS3231
#ifdef DEBUG
UART_send_string("Updating current date time from DS3231\r\n");
#endif
Update_Current_Date_Time();
// Read temp
#ifdef DEBUG
UART_send_string("Reading Alarms and Temperature");
#endif
Read_Alarms_Temp();
// Get Alarm Status
Get_Alarm_Status();
// Separate the int timedate variables into chars
#ifdef DEBUG
UART_send_string("Formatting chars");
#endif
format_DateTimeChars();
// Format temperature
#ifdef DEBUG
UART_send_string("Formating temperature");
#endif
format_Temperature();
// Determine day of the week
#ifdef DEBUG
UART_send_string("Determining day of week");
#endif
getWeekDay(dayOfWeek);
// Enter loop and update display if sec changes from DS3231
if (sec_chg != sec) {
update_Display();
// Set temp_sec to current sec from DS3231
sec_chg = sec;
#ifdef DEBUG
UART_send_string(CURSOR(19, 1));
sprintf(buf, "%sTIME:%s\t%02d:%02d:%02d\r\n", YELLOW, CLRATTR,
hour, min, sec);
UART_send_string(buf);
sprintf(buf, "%sAL1:%s\t%02d:%02d:%02d\t%sSTATUS:%s %d\r\n", YELLOW,
CLRATTR, alarm1_hour, alarm1_min, alarm1_sec, YELLOW,
CLRATTR, alarm1_status);
UART_send_string(buf);
sprintf(buf, "%sAL2:%s\t%02d:%02d\t\t%sSTATUS:%s %d\r\n", YELLOW,
CLRATTR, alarm2_hour, alarm2_min, YELLOW, CLRATTR,
alarm2_status);
UART_send_string(buf);
sprintf(buf, "%sWKDAY:%s\t%d\t\t%sDAY:%s\t%s\r\n", YELLOW, CLRATTR,
dayOfWeek, YELLOW, CLRATTR, weekday);
UART_send_string(buf);
sprintf(buf, "%sTEMP:\t%s%c%c%c.%c%cC%s", YELLOW, CLRATTR,
temp_sign, temp_2, temp_1, temp_0, 0xB0, CLRATTR);
UART_send_string(buf);
#endif
}
}
return 0;
}
// Format unsigned int to unsigned chars
void format_DateTimeChars() {
sec_0 = sec % 10 + '0';
sec_1 = sec / 10 + '0';
min_0 = min % 10 + '0';
min_1 = min / 10 + '0';
hour_0 = hour % 10 + '0';
hour_1 = hour / 10 + '0';
day_0 = date % 10 + '0';
day_1 = date / 10 + '0';
month_0 = month % 10 + '0';
month_1 = month / 10 + '0';
year_0 = year % 10 + '0';
year_1 = year / 10 + '0';
alarm1_sec_0 = alarm1_sec % 10 + '0';
alarm1_sec_1 = alarm1_sec / 10 + '0';
alarm1_min_0 = alarm1_min % 10 + '0';
alarm1_min_1 = alarm1_min / 10 + '0';
alarm1_hour_0 = alarm1_hour % 10 + '0';
alarm1_hour_1 = alarm1_hour / 10 + '0';
alarm2_min_0 = alarm2_min % 10 + '0';
alarm2_min_1 = alarm2_min / 10 + '0';
alarm2_hour_0 = alarm2_hour % 10 + '0';
alarm2_hour_1 = alarm2_hour / 10 + '0';
}
// Format msb and lsb for temperature display
void format_Temperature() {
if (temperature_msb < 0) {
temperature_msb *= -1;
temp_sign = '-';
} else {
temp_sign = '+';
}
//Shift fractional value 6 bits to the right so b7 & b6 are b1 & b0
temperature_lsb >>= 6;
//Fractional is increments of 0.25 degrees
temperature_lsb *= 25;
if (temperature_lsb == 0) {
temp_0 = '0';
}
if (temperature_lsb == 25) {
temp_0 = '2';
}
if (temperature_lsb == 50) {
temp_0 = '5';
}
if (temperature_lsb == 75) {
temp_0 = '7';
}
temp_1 = temperature_msb % 10 + '0';
temp_2 = temperature_msb / 10 + '0';
}
// Determine day of week from DS3231
void getWeekDay(unsigned int dayOfWeek) {
switch (dayOfWeek) {
case 1:
weekday = "Sun";
break;
case 2:
weekday = "Mon";
break;
case 3:
weekday = "Tue";
break;
case 4:
weekday = "Wed";
break;
case 5:
weekday = "Thu";
break;
case 6:
weekday = "Fri";
break;
case 7:
weekday = "Sat";
break;
}
}
// Determine Alarm status from control registers
void Get_Alarm_Status() {
alarm1_status = control_reg & 0x01; // Read alarm1 INT enable bit A1IE
alarm2_status = (control_reg >> 1) & 0x01; // Read alarm2 INT enable bit A2IE
}
void display_Intro() {
// Give an intro message on the LCD
Lcd_Clear();
Lcd_Set_Cursor(1, 1);
Lcd_Write_String("RTC/LCD with PIC");
Lcd_Set_Cursor(2, 1);
Lcd_Write_String(" Circuit Digest");
__delay_ms(2000); //display for 1sec
}
void display_Lcd_Layout() {
// Setup time date display format
Lcd_Clear();
Lcd_Set_Cursor(1, 1);
Lcd_Write_String("HH:mm:ss -PP.P");
Lcd_Write_Char(0xDF);
Lcd_Write_Char('C');
Lcd_Set_Cursor(2, 1);
Lcd_Write_String("ddd, DD/MM/YY ");
__delay_ms(2000);
}
void update_Display() {
// Display Hours
Lcd_Set_Cursor(1, 1);
Lcd_Write_Char(hour_1);
Lcd_Write_Char(hour_0);
// Display minutes
Lcd_Set_Cursor(1, 4);
Lcd_Write_Char(min_1);
Lcd_Write_Char(min_0);
// Display seconds
Lcd_Set_Cursor(1, 7);
Lcd_Write_Char(sec_1);
Lcd_Write_Char(sec_0);
// Display day
Lcd_Set_Cursor(2, 6);
Lcd_Write_Char(day_1);
Lcd_Write_Char(day_0);
// Display month
Lcd_Set_Cursor(2, 9);
Lcd_Write_Char(month_1);
Lcd_Write_Char(month_0);
// Display year
Lcd_Set_Cursor(2, 12);
Lcd_Write_Char(year_1);
Lcd_Write_Char(year_0);
// Display day of week
Lcd_Set_Cursor(2, 1);
Lcd_Write_String(weekday);
// Display temperature
Lcd_Set_Cursor(1, 10);
Lcd_Write_Char(temp_sign);
Lcd_Write_Char(temp_2);
Lcd_Write_Char(temp_1);
Lcd_Set_Cursor(1, 14);
Lcd_Write_Char(temp_0);
if (min == 00 && sec == 00) {
alarm(2);
}
if (min == 30 && sec == 00) {
alarm(1);
}
}
|