aboutsummaryrefslogtreecommitdiffstats
path: root/main.c
blob: 87a53d00177a1130ee767ad58f696ec82b22c68d (plain)
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);
    }
}