#include "conf.h" //Configuration settings #include "main.h" //Declarations for main //Initialize variables #ifdef ADC // Initialize variable for LDR unsigned int ldr = 0; #endif // Initialize variable for VFD brightness level unsigned int brtlvl_chg = 0; // Boolean if external interrupt occurs unsigned int update = 0; // Boolean for setting time manually with user input unsigned int edit_datetime = 0; // Initialize variables for date time and alarms 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 year = 00; unsigned int century = 20; // Initialize variables for temperature unsigned int temperature_lsb = 0; int temperature_msb = 0; unsigned char temp_sign = ' '; void main(void) { TRISA0 = 0x01; // RA is input (ADC) TRISBbits.TRISB2 = 1; TRISBbits.TRISB4 = 1; TRISBbits.TRISB5 = 1; GIE = 0; //Disable interrupts until set up OPTION_REGbits.nRBPU = 0; // PORTB pull-ups are enabled by individual port latch values INTE = 1; // Enable RB0 as external interrupt GIE = 1; // Enable all interrupts from now on 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 13, column 24 UART_send_string(GREEN); // Set Green UART_send_string("I2C Module Initialized and active\r\n"); UART_send_string(CLRATTR); // No color #endif #ifdef ADC Adc_Init(); // Init I2C Master with 100KHz Clock #ifdef DEBUG UART_send_string(CURSOR(14, 24)); // Set cursor at line 14, column 24 UART_send_string(GREEN); // Set Green UART_send_string("ADC Module Initialized and active\r\n"); UART_send_string(CLRATTR); // No color #endif #endif Lcd_Init(); #ifdef DEBUG UART_send_string(CURSOR(15, 24)); // Set cursor at line 15, column 24 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(); //Set_Date(); //Set_DayOfWeek(Get_DayOfWeek(year, month, date)); 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 (update) { Lcd_Set_Cursor(1, 3); Lcd_Write_Char(':'); Lcd_Set_Cursor(1, 6); Lcd_Write_Char(':'); Update_Current_Date_Time(); Read_Alarms_Temp(); Get_Alarm_Status(); format_Temperature(); update_Display(); update = 0; __delay_ms(500); } else { Lcd_Set_Cursor(1, 3); Lcd_Write_Char(' '); Lcd_Set_Cursor(1, 6); Lcd_Write_Char(' '); } // Edit time when Set button is pressed if (!SETB) { __delay_ms(250); edit_Date_Time(); } #ifdef ADC // Get current LDR reading and calculate for brightness levels 0 - 3 ldr = Adc_Read(0); if (brtlvl_chg != brtlvl) { Vfd_Set_Brightness(brtlvl); brtlvl_chg = brtlvl; } #endif #ifdef DEBUG UART_send_string(CURSOR(19, 1)); sprintf(buf, "%sTIME:%s\t%02d:%02d:%02d\t%sDATE:%s\t%02d/%02d/%02d\r\n", YELLOW, CLRATTR, hour, min, sec, YELLOW, CLRATTR, date, month, year); 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, day, YELLOW, CLRATTR, Get_WeekDay(day)); UART_send_string(buf); sprintf(buf, "%sTEMP:\t%s%c%c%c.%c%cC%s\t\t%sLDR:%s\t\%04d %d\r\n", YELLOW, CLRATTR, temp_sign, temp_2, temp_1, temp_0, 0xB0, CLRATTR, YELLOW, CLRATTR, ldr, brtlvl); UART_send_string(buf); sprintf(buf, "%sISR:\t%s%d", YELLOW, CLRATTR, update); UART_send_string(buf); #endif } } // 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'; } } // Determine month name from month value // 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_Digit(unsigned int data) { Lcd_Write_Char(MSB(data)); Lcd_Write_Char(LSB(data)); } 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"); __delay_ms(1000); //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/CCYY "); __delay_ms(1000); } void update_Display() { // Display Hours Lcd_Set_Cursor(1, 1); display_Digit(hour); // Display minutes Lcd_Set_Cursor(1, 4); display_Digit(min); // Display seconds Lcd_Set_Cursor(1, 7); display_Digit(sec); // Display day Lcd_Set_Cursor(2, 6); display_Digit(date); // Display month Lcd_Set_Cursor(2, 9); display_Digit(month); // Display century Lcd_Set_Cursor(2, 12); display_Digit(century); // Display year Lcd_Set_Cursor(2, 14); display_Digit(year); // Display day of week Lcd_Set_Cursor(2, 2); Lcd_Write_String(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(temp_0); if (min == 00 && sec == 00) { alarm(2); } if (min == 30 && sec == 00) { alarm(1); } } void edit_Date_Time(void) { Lcd_Set_Cursor(2, 16); Lcd_Write_Char('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(':'); switch (edit_datetime) { case 1: //Hours Lcd_Set_Cursor(2, 16); Lcd_Write_Char('h'); if (!DECR) { __delay_ms(250); if (hour == 0) { hour = 23; } else { hour -= 1; } Lcd_Set_Cursor(1, 1); display_Digit(hour); } else if (!INCR) { __delay_ms(250); if (hour + 1 > 23) { hour = 0; } else { hour += 1; } Lcd_Set_Cursor(1, 1); display_Digit(hour); } break; case 2: //Minutes Lcd_Set_Cursor(2, 16); Lcd_Write_Char('m'); if (!DECR) { __delay_ms(250); if (min == 0) { min = 59; } else { min -= 1; } Lcd_Set_Cursor(1, 4); display_Digit(min); } else if (!INCR) { __delay_ms(250); if (min + 1 > 59) { min = 0; } else { min += 1; } Lcd_Set_Cursor(1, 4); display_Digit(min); } break; case 3: //Seconds Lcd_Set_Cursor(2, 16); Lcd_Write_Char('s'); if (!DECR) { __delay_ms(250); if (sec == 0) { sec = 59; } else { sec -= 1; } Lcd_Set_Cursor(1, 7); display_Digit(sec); } else if (!INCR) { __delay_ms(250); if (sec + 1 > 59) { sec = 0; } else { sec += 1; } Lcd_Set_Cursor(1, 7); display_Digit(sec); } break; case 6: //Date Lcd_Set_Cursor(2, 16); Lcd_Write_Char('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); } 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); } break; case 5: //Month Lcd_Set_Cursor(2, 16); Lcd_Write_Char('M'); if (!DECR) { __delay_ms(250); if (month - 1 == 0) { month = 12; } else { month -= 1; } Lcd_Set_Cursor(2, 9); display_Digit(month); } else if (!INCR) { __delay_ms(250); if (month + 1 > 12) { month = 1; } else { month += 1; } Lcd_Set_Cursor(2, 9); display_Digit(month); } break; case 4: //Year Lcd_Set_Cursor(2, 16); Lcd_Write_Char('Y'); if (!DECR) { __delay_ms(250); if (year == 0) { year = 99; } else { year -= 1; } Lcd_Set_Cursor(2, 14); display_Digit(year); } else if (!INCR) { __delay_ms(250); if (year + 1 > 99) { year = 0; } else { year += 1; } Lcd_Set_Cursor(2, 14); display_Digit(year); } //TODO Maybe add century break; default: break; } if (!SETB) { __delay_ms(250); edit_datetime++; } } if (edit_datetime > 6) { Set_Time(); Set_DayOfWeek(Get_DayOfWeek(year, month, date)); Set_Date(); edit_datetime = 0; Lcd_Set_Cursor(2, 16); Lcd_Write_String(" "); } } void __interrupt() isr(void) { if (INTF == 1) { // External interrupt detected update = 1; INTF = 0; } }