From 08ad02e8c2ea6510f165bfcb923407a9a498afc1 Mon Sep 17 00:00:00 2001 From: William Harrington Date: Thu, 8 Aug 2019 00:32:52 -0500 Subject: Tidy up and provide useful comments --- main.c | 138 ++++++++++++++++++++++++++++++++++++++++++++--------------------- main.h | 2 +- 2 files changed, 94 insertions(+), 46 deletions(-) diff --git a/main.c b/main.c index 76787e5..9ba7d72 100755 --- a/main.c +++ b/main.c @@ -21,8 +21,8 @@ unsigned int sec = 0; unsigned int min = 0; unsigned int hour = 0; unsigned int day = 1; -unsigned int date = 0; -unsigned int month = 0; +unsigned int date = 1; +unsigned int month = 1; unsigned int year = 00; unsigned int century = 20; unsigned int alarm1_sec = 0; @@ -101,27 +101,40 @@ void main(void) { display_Intro(); display_Lcd_Layout(); - // Set an initial date time + /* + * Set an initial date time via initial program variables + * Currently 00:00:00 1/1/00 and Sunday (day of week as 1) + */ + //Set_Time(); //Set_Date(); //Set_DayOfWeek(Get_DayOfWeek(year, month, date)); + + /* + * isr expects 1Hz clock from RTC. This will update clock each second + * While interrupted, clock is updating and set button will be ignored. + * Here we set Status register 0Eh bit4 and bit3 as 0b00 for 1Hz. + * 0x40 sets bit6 as high so BBSQW is enabled and 1Hz square wave results + * out the !INT/SQW pin of the device. + */ Set_Sqwe(0x40); //1Hz - // 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) { + + /* + * If 1Hz interrupt from RTC received, isr sets update to 1 + * Update time/date/alarm/temp/other variables from RTC + * Format temperature's tenth place + * Update digits on display device + * reset update boolean until next RTC 1Hz interrupt + * delay 500ms for a perception of ':'s blinking at 1/2 duty cycle + */ + if (update) { Lcd_Set_Cursor(1, 3); Lcd_Write_Char(':'); @@ -141,22 +154,32 @@ void main(void) { Lcd_Write_Char(' '); } - // Edit time when Set button is pressed + /* + * Edit time when Set button is pressed (Active low) + * set edit_Date_Time to 1 to enter edit date/time loop + */ + if (!SETB) { __delay_ms(250); edit_Date_Time(); } + /* + * If ADC is enabled then read from ADC channel into ldr + * If VFD available set brtlvl (ldr defaulted to 0) + * brtlvl is (ldr / 256) and brtlvl_chg is compared with brtlvl + * New brightness level is set when a difference occurs + */ + #ifdef ADC - #ifdef VFD // Get current LDR reading and calculate for brightness levels 0 - 3 ldr = Adc_Read(0); - +#ifdef VFD if (brtlvl_chg != brtlvl) { Vfd_Set_Brightness(brtlvl); brtlvl_chg = brtlvl; } - #endif +#endif #endif #ifdef DEBUG @@ -185,10 +208,18 @@ void main(void) { } } -// Format msb and lsb for temperature display +/* + * DS3231 11h has MSB of temp and 12h has LSB of temp + * MSB and LSB bits 7 have sign + * MSB bits 0-7 have DATA + * LSB bits 7 and 6 have DATA + * 10-bits with 0.25 resolution (this program drops hundredths place) + */ void format_Temperature() { + // If MSB negative then get 2's complement and sign for display to '-' + // otherwise MSB is positive and we set sign for display to '+' if (temperature_msb < 0) { temperature_msb *= -1; temp_sign = '-'; @@ -196,43 +227,26 @@ void format_Temperature() { temp_sign = '+'; } - //Shift fractional value 6 bits to the right so b7 & b6 are b1 & b0 + //Shift LSB fractional value 6 bits to the right so b7 & b6 are b1 & b0 temperature_lsb >>= 6; - //Fractional is increments of 0.25 degrees + //Fractional is 0b00, 0b01, 0b10, 0b11. Multiply by 25 for 00, 25, 50, 75 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'; - } } -// Determine month name from month value - -// Determine Alarm status from control registers - +// Determine Alarm status from control register 0Fh bits 0 (A1F) and 1 (A2F) 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 + alarm1_status = control_reg & 0x01; // Read alarm1 A1F bit + alarm2_status = (control_reg >> 1) & 0x01; // Read alarm2 A2F bit } +// Separate data into tens and ones units to display with character displays void display_Digit(unsigned int data) { Lcd_Write_Char(MSB(data)); Lcd_Write_Char(LSB(data)); } +// Provides the user program info on startup void display_Intro() { // Give an intro message on the LCD Lcd_Clear(); @@ -243,6 +257,8 @@ void display_Intro() { __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 Lcd_Clear(); @@ -256,6 +272,8 @@ void display_Lcd_Layout() { __delay_ms(1000); } +// Updates the display with values that change and not static info + void update_Display() { // Display Hours Lcd_Set_Cursor(1, 1); @@ -294,17 +312,34 @@ void update_Display() { Lcd_Write_Char(temp_sign); display_Digit(temperature_msb); Lcd_Set_Cursor(1, 14); - Lcd_Write_Char(temp_0); + Lcd_Write_Char(MSB(temperature_lsb)); + // Chime at top of hour if (min == 00 && sec == 00) { alarm(2); } + // Chime at half of hour if (min == 30 && sec == 00) { alarm(1); } } +/* + * 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. + * + * 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. + * ex: 29/02/2020 is Sat and leap year with max date to select in Feb as 29. + * + * Order to edit is hour -> min -> sec -> year -> month -> day + * Pressing Set after day results in RTC being updated with current edit values. + */ + void edit_Date_Time(void) { Lcd_Set_Cursor(2, 16); Lcd_Write_Char('S'); @@ -477,10 +512,10 @@ void edit_Date_Time(void) { Lcd_Set_Cursor(2, 14); display_Digit(year); } - - //TODO Maybe add century break; + //TODO Maybe add a case to edit century on display + default: break; } @@ -491,6 +526,13 @@ void edit_Date_Time(void) { } } + // TODO Edit alarms + + /* + * Set button pressed after Date selection then we set the values in RTC. + * Unset edit_datetime until next time set button is pressed and clear + * field text from lower right of display. + */ if (edit_datetime > 6) { Set_Time(); Set_DayOfWeek(Get_DayOfWeek(year, month, date)); @@ -501,6 +543,12 @@ void edit_Date_Time(void) { } } +/* + * interrupt service routine (isr) triggered by external interrupt ping RB0 by + * RTC (DS3231) SQW output at 1Hz. The update flag is set so that the display + * is updated with current RTC date/time/temp info and updates display + * brightness if enabled + */ void __interrupt() isr(void) { if (INTF == 1) { // External interrupt detected update = 1; diff --git a/main.h b/main.h index d65a1f4..84c1040 100755 --- a/main.h +++ b/main.h @@ -47,7 +47,7 @@ extern unsigned int temperature_lsb; extern int temperature_msb; unsigned char temp_sign; -// Define MSB / LSB +// Define MSB / LSB: Useful for separating into chars for tens and ones places #define LSB(x) ((x % 10) + '0') // x >> 4 #define MSB(x) ((x / 10) + '0') // x & 0x0F -- cgit v1.2.3-54-g00ecf