diff options
Diffstat (limited to 'main.c')
-rwxr-xr-x | main.c | 294 |
1 files changed, 104 insertions, 190 deletions
@@ -100,6 +100,7 @@ void main(void) { display_Intro();
display_Lcd_Layout();
+ __delay_ms(1000);
/*
* Set an initial date time via initial program variables
@@ -135,10 +136,7 @@ void main(void) { */
if (update) {
- Lcd_Set_Cursor(1, 3);
- Lcd_Write_Char(':');
- Lcd_Set_Cursor(1, 6);
- Lcd_Write_Char(':');
+ timeSeparatorOn();
Update_Current_Date_Time();
Read_Alarms_Temp();
Get_Alarm_Status();
@@ -147,10 +145,7 @@ void main(void) { update = 0;
__delay_ms(500);
} else {
- Lcd_Set_Cursor(1, 3);
- Lcd_Write_Char(' ');
- Lcd_Set_Cursor(1, 6);
- Lcd_Write_Char(' ');
+ timeSeparatorOff();
}
/*
@@ -240,81 +235,77 @@ void Get_Alarm_Status() { alarm2_status = (control_reg >> 1) & 0x01; // Read alarm2 A2F bit
}
+void display_Alpha(char y, char x, char c) {
+ Lcd_Set_Cursor(y, x);
+ Lcd_Write_Char(c);
+}
+
// Separate data into tens and ones units to display with character displays
-void display_Digit(unsigned int data) {
+void display_Digit(char y, char x, unsigned int data) {
+ Lcd_Set_Cursor(y, x);
Lcd_Write_Char(MSB(data));
Lcd_Write_Char(LSB(data));
}
+void display_Text(char y, char x, char* c) {
+ Lcd_Set_Cursor(y, x);
+ Lcd_Write_String(c);
+}
+
// Provides the user program info on startup
void display_Intro() {
// Give an intro message on the LCD
Lcd_Clear();
- Lcd_Set_Cursor(1, 4);
- Lcd_Write_String("Desk Clock");
- Lcd_Set_Cursor(2, 15);
- Lcd_Write_String("V1");
+ display_Text(1, 4, "Desk Clock");
+ display_Text(2, 15, "V1");
__delay_ms(1000); //display for 1sec
}
// Provides the user the current layout of time/date/temp for the display
void display_Lcd_Layout() {
- // Setup time date display format
+ // Setup time date display format. 0xDF is degree symbol
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/CCYY ");
-
- __delay_ms(1000);
+ display_Text(1, 1, "HH:mm:ss -PP.P");
+ display_Alpha(1, 15, 0xDF);
+ display_Alpha(1, 16, 'C');
+ // Civilian Vernacular US m/d/yyyy
+ display_Text(2, 1, " ddd MM/DD/CCYY ");
}
// Updates the display with values that change and not static info
void update_Display() {
// Display Hours
- Lcd_Set_Cursor(1, 1);
- display_Digit(hour);
+ display_Digit(1, 1, hour);
// Display minutes
- Lcd_Set_Cursor(1, 4);
- display_Digit(min);
+ display_Digit(1, 4, min);
// Display seconds
- Lcd_Set_Cursor(1, 7);
- display_Digit(sec);
+ display_Digit(1, 7, sec);
// Display day
- Lcd_Set_Cursor(2, 6);
- display_Digit(date);
+ display_Digit(2, 6, month);
// Display month
- Lcd_Set_Cursor(2, 9);
- display_Digit(month);
+ display_Digit(2, 9, date);
// Display century
- Lcd_Set_Cursor(2, 12);
- display_Digit(century);
+ display_Digit(2, 12, century);
// Display year
- Lcd_Set_Cursor(2, 14);
- display_Digit(year);
+ display_Digit(2, 14, year);
// Display day of week
- Lcd_Set_Cursor(2, 2);
- Lcd_Write_String(Get_WeekDay(day));
+ display_Text(2, 2, Get_WeekDay(day));
// Display temperature
- Lcd_Set_Cursor(1, 10);
- Lcd_Write_Char(temp_sign);
- display_Digit(temperature_msb);
- Lcd_Set_Cursor(1, 14);
- Lcd_Write_Char(MSB(temperature_lsb));
+ display_Alpha(1, 10, temp_sign);
+ display_Digit(1, 11, temperature_msb);
+ display_Alpha(1, 14, (MSB(temperature_lsb)));
// Chime at top of hour
if (min == 00 && sec == 00) {
@@ -330,13 +321,9 @@ void update_Display() { /*
* Called when set button is pressed and S is in lower right of display for
* set mode. Immediately goes into setting the hour. Each time SETB is pressed:
- * minutes then seconds then year then month then date then update RTC and
- * edit flag is cleared and clock continues as normal. Sets :'s to display for
- * time in case they were blanked.
- *
- * Change detection variables are set before values are changed and compared
- * as user goes through fields. If a change is detected then updateRTC flag is
- * enabled causing the RTC to be updated.
+ * minutes then seconds then hour then year then month then date then update
+ * RTC and edit flag is cleared and clock continues as normal. Sets time
+ * separator to display for time in case they were blanked.
*
* As month/date is selected, functions determine if year is leap or not,
* the max number of days in each month, and displays the day of the week.
@@ -348,10 +335,8 @@ void update_Display() { void edit_Date_Time(void) {
// Variable to determine if RTC is updated or not (date/time valus change)
- int updateRTC = 0;
- // Variables set to current edit value and if a mismatch from user input
- // then updateRTC is set to 1 and RTC will be updated
+ // Variables set to current rtc value
unsigned int hour_org = hour;
unsigned int min_org = min;
unsigned int sec_org = sec;
@@ -359,188 +344,90 @@ void edit_Date_Time(void) { unsigned int month_org = month;
unsigned int date_org = date;
- Lcd_Set_Cursor(2, 16);
- Lcd_Write_Char('S');
+ display_Alpha(2, 16, 'S');
edit_datetime++;
while (edit_datetime > 0 && edit_datetime < 7) {
// Set colons if not enabled when Set button is pressed
- Lcd_Set_Cursor(1, 3);
- Lcd_Write_Char(':');
- Lcd_Set_Cursor(1, 6);
- Lcd_Write_Char(':');
+ timeSeparatorOn();
switch (edit_datetime) {
case 1: //Hours
- Lcd_Set_Cursor(2, 16);
- Lcd_Write_Char('h');
+ display_Alpha(2, 16, 'h');
if (!DECR) {
- __delay_ms(250);
- if (hour == 0) {
- hour = 23;
- } else {
- hour -= 1;
- }
- Lcd_Set_Cursor(1, 1);
- display_Digit(hour);
+ decrementValue(&hour, 0, 23);
+ display_Digit(1, 1, hour);
} else if (!INCR) {
- __delay_ms(250);
- if (hour + 1 > 23) {
- hour = 0;
- } else {
- hour += 1;
- }
-
- Lcd_Set_Cursor(1, 1);
- display_Digit(hour);
+ incrementValue(&hour, 0, 23);
+ display_Digit(1, 1, hour);
}
break;
case 2: //Minutes
- Lcd_Set_Cursor(2, 16);
- Lcd_Write_Char('m');
+ display_Alpha(2, 16, 'm');
if (!DECR) {
- __delay_ms(250);
- if (min == 0) {
- min = 59;
- } else {
- min -= 1;
- }
- Lcd_Set_Cursor(1, 4);
- display_Digit(min);
+ decrementValue(&min, 0, 59);
+ display_Digit(1, 4, min);
} else if (!INCR) {
- __delay_ms(250);
- if (min + 1 > 59) {
- min = 0;
- } else {
- min += 1;
- }
-
- Lcd_Set_Cursor(1, 4);
- display_Digit(min);
+ incrementValue(&min, 0, 59);
+ display_Digit(1, 4, min);
}
break;
case 3: //Seconds
- Lcd_Set_Cursor(2, 16);
- Lcd_Write_Char('s');
+ display_Alpha(2, 16, 's');
if (!DECR) {
- __delay_ms(250);
- if (sec == 0) {
- sec = 59;
- } else {
- sec -= 1;
- }
- Lcd_Set_Cursor(1, 7);
- display_Digit(sec);
- if (sec_org != sec) {
- updateRTC = 1;
- }
+ decrementValue(&sec, 0, 59);
+ display_Digit(1, 7, sec);
} else if (!INCR) {
- __delay_ms(250);
- if (sec + 1 > 59) {
- sec = 0;
- } else {
- sec += 1;
- }
-
- Lcd_Set_Cursor(1, 7);
- display_Digit(sec);
- if (sec_org != sec) {
- updateRTC = 1;
- }
+ incrementValue(&sec, 0, 59);
+ display_Digit(1, 7, sec);
}
break;
case 6: //Date
- Lcd_Set_Cursor(2, 16);
- Lcd_Write_Char('D');
+ display_Alpha(2, 16, 'D');
if (!DECR) {
- __delay_ms(250);
- if (date - 1 == 0) {
- date = Get_Days_In_Month(year, month);
- } else {
- date -= 1;
- }
-
- Lcd_Set_Cursor(2, 2);
- Lcd_Write_String(Get_WeekDay(Get_DayOfWeek(year, month, date)));
- Lcd_Set_Cursor(2, 6);
- display_Digit(date);
+ decrementValue(&date, 1, Get_Days_In_Month(year, month));
+ display_Text(2, 2, Get_WeekDay(Get_DayOfWeek(year, month, date)));
+ display_Digit(2, 9, date);
} else if (!INCR) {
- __delay_ms(250);
- //TODO USE Formula to get days based on month year (and leap)
- if (date + 1 > Get_Days_In_Month(year, month)) {
- date = 1;
- } else {
- date += 1;
- }
-
- Lcd_Set_Cursor(2, 2);
- Lcd_Write_String(Get_WeekDay(Get_DayOfWeek(year, month, date)));
- Lcd_Set_Cursor(2, 6);
- display_Digit(date);
+ incrementValue(&date, 1, Get_Days_In_Month(year, month));
+ display_Text(2, 2, Get_WeekDay(Get_DayOfWeek(year, month, date)));
+ display_Digit(2, 9, date);
}
break;
case 5: //Month
- Lcd_Set_Cursor(2, 16);
- Lcd_Write_Char('M');
+ display_Alpha(2, 16, 'M');
if (!DECR) {
- __delay_ms(250);
- if (month - 1 == 0) {
- month = 12;
- } else {
- month -= 1;
- }
- Lcd_Set_Cursor(2, 9);
- display_Digit(month);
+ decrementValue(&month, 1, 12);
+ display_Digit(2, 6, month);
} else if (!INCR) {
- __delay_ms(250);
- if (month + 1 > 12) {
- month = 1;
- } else {
- month += 1;
- }
-
- Lcd_Set_Cursor(2, 9);
- display_Digit(month);
+ incrementValue(&month, 1, 12);
+ display_Digit(2, 6, month);
}
break;
case 4: //Year
- Lcd_Set_Cursor(2, 16);
- Lcd_Write_Char('Y');
+ display_Alpha(2, 16, 'Y');
if (!DECR) {
- __delay_ms(250);
- if (year == 0) {
- year = 99;
- } else {
- year -= 1;
- }
- Lcd_Set_Cursor(2, 14);
- display_Digit(year);
+ decrementValue(&year, 0, 99);
+ display_Digit(2, 14, year);
} else if (!INCR) {
- __delay_ms(250);
- if (year + 1 > 99) {
- year = 0;
- } else {
- year += 1;
- }
-
- Lcd_Set_Cursor(2, 14);
- display_Digit(year);
+ incrementValue(&year, 0, 99);
+ display_Digit(2, 14, year);
}
break;
@@ -568,14 +455,13 @@ void edit_Date_Time(void) { Lcd_Set_Cursor(2, 16);
Lcd_Write_String(" ");
edit_datetime = 0;
-
+
/*
* If any date/time field was changed, clear updateRTC field and
* update RTC.
- */
- if(hour_org != hour || min_org != min || sec_org != sec
+ */
+ if (hour_org != hour || min_org != min || sec_org != sec
|| year_org != year || month_org != month || date_org != date) {
- updateRTC = 0;
Set_Time();
Set_DayOfWeek(Get_DayOfWeek(year, month, date));
Set_Date();
@@ -583,6 +469,34 @@ void edit_Date_Time(void) { }
}
+void timeSeparatorOn(void) {
+ display_Alpha(1, 3, ':');
+ display_Alpha(1, 6, ':');
+}
+
+void timeSeparatorOff(void) {
+ display_Alpha(1, 3, ' ');
+ display_Alpha(1, 6, ' ');
+}
+
+void decrementValue(unsigned int *v, unsigned int threshold, unsigned int limit) {
+ __delay_ms(250);
+ if (*v == threshold) {
+ *v = limit;
+ } else {
+ *v -= 1;
+ }
+}
+
+void incrementValue(unsigned int *v, unsigned int lowerlimit, unsigned int upperlimit) {
+ __delay_ms(250);
+ if (*v + 1 > upperlimit) {
+ *v = lowerlimit;
+ } else {
+ *v += 1;
+ }
+}
+
/*
* interrupt service routine (isr) triggered by external interrupt pin RB0 by
* RTC (DS3231) SQW output at 1Hz. The update flag is set so that the display
@@ -594,4 +508,4 @@ void __interrupt() isr(void) { update = 1;
INTF = 0;
}
-}
\ No newline at end of file +}
|