aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xmain.c138
-rwxr-xr-xmain.h2
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