อุปกรณ์
- PIC 18F4550
- 16×2 LCD Display
- DS1307 or DS3232
- 32.768 kHz Crystal
- 16 MHz Crystal
- 4.7K Resistor – 7
- 10K Resistor
- 10K Preset
- 22pF Capacitor – 2
- 100nF Capacitor
- 4×4 Keypad
- 680R Resistor
- LED – 1
- 3V CMOS Battery
- BC548
- 1N4148
- Relay (5V/12V)
code
#define MENU_KEY 'D' #define SAVE_EXIT '*' #define BELL_TIME 60 // LCD module connections sbit LCD_RS at RB7_bit; sbit LCD_EN at RB6_bit; sbit LCD_D4 at RB5_bit; sbit LCD_D5 at RB4_bit; sbit LCD_D6 at RB3_bit; sbit LCD_D7 at RB2_bit; sbit LCD_RS_Direction at TRISB7_bit; sbit LCD_EN_Direction at TRISB6_bit; sbit LCD_D4_Direction at TRISB5_bit; sbit LCD_D5_Direction at TRISB4_bit; sbit LCD_D6_Direction at TRISB3_bit; sbit LCD_D7_Direction at TRISB2_bit; // End LCD module connections // Keypad Connections sbit KEY_R1 at LATD0_bit; sbit KEY_R0 at LATD1_bit; sbit KEY_R3 at LATD6_bit; sbit KEY_R2 at LATD7_bit; sbit KEY_C0 at RD3_bit; sbit KEY_C1 at RD2_bit; sbit KEY_C2 at RD4_bit; sbit KEY_C3 at RD5_bit; sbit KEY_R1_Direction at TRISD0_bit; sbit KEY_R0_Direction at TRISD1_bit; sbit KEY_R3_Direction at TRISD6_bit; sbit KEY_R2_Direction at TRISD7_bit; sbit KEY_C0_Direction at TRISD3_bit; sbit KEY_C1_Direction at TRISD2_bit; sbit KEY_C2_Direction at TRISD4_bit; sbit KEY_C3_Direction at TRISD5_bit; // End Keypad Connections void keypadInit() { KEY_C0_Direction = 1; KEY_C1_Direction = 1; KEY_C2_Direction = 1; KEY_C3_Direction = 1; KEY_R0_Direction = 0; KEY_R1_Direction = 0; KEY_R2_Direction = 0; KEY_R3_Direction = 0; KEY_R0 = 1; KEY_R1 = 1; KEY_R2 = 1; KEY_R3 = 1; } unsigned readKeypad() { KEY_R0 = 0; Delay_ms(1); if(KEY_C0 == 0) { while(KEY_C0 == 0); return 1; } else if(KEY_C1 == 0) { while(KEY_C1 == 0); return 2; } else if(KEY_C2 == 0) { while(KEY_C2 == 0); return 3; } else if(KEY_C3 == 0) { while(KEY_C3 == 0); return 4; } KEY_R0 = 1; KEY_R1 = 0; Delay_ms(1); if(KEY_C0 == 0) { while(KEY_C0 == 0); return 5; } else if(KEY_C1 == 0) { while(KEY_C1 == 0); return 6; } else if(KEY_C2 == 0) { while(KEY_C2 == 0); return 7; } else if(KEY_C3 == 0) { while(KEY_C3 == 0); return 8; } KEY_R1 = 1; KEY_R2 = 0; Delay_ms(1); if(KEY_C0 == 0) { while(KEY_C0 == 0); return 9; } else if(KEY_C1 == 0) { while(KEY_C1 == 0); return 10; } else if(KEY_C2 == 0) { while(KEY_C2 == 0); return 11; } else if(KEY_C3 == 0) { while(KEY_C3 == 0); return 12; } KEY_R2 = 1; KEY_R3 = 0; Delay_ms(1); if(KEY_C0 == 0) { while(KEY_C0 == 0); return 13; } else if(KEY_C1 == 0) { while(KEY_C1 == 0); return 14; } else if(KEY_C2 == 0) { while(KEY_C2 == 0); return 15; } else if(KEY_C3 == 0) { while(KEY_C3 == 0); return 16; } KEY_R3 = 1; return 0; } unsigned readDS3231(unsigned address) { unsigned short r_data; I2C1_Start(); I2C1_Wr(0xD0); //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0 I2C1_Wr(address); I2C1_Repeated_Start(); I2C1_Wr(0xD1); //0x68 followed by 1 --> 0xD1 r_data=I2C1_Rd(0); I2C1_Stop(); return(r_data); } void writeDS3231(unsigned address,unsigned w_data) { I2C1_Start(); // issue I2C start signal //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0 I2C1_Wr(0xD0); // send byte via I2C (device address + W) I2C1_Wr(address); // send byte (address of DS1307 location) I2C1_Wr(w_data); // send data (data to be written) I2C1_Stop(); // issue I2C stop signal } char BCD2UpperCh(unsigned bcd) { return ((char)((bcd >> 4) + '0')); } char BCD2LowerCh(unsigned bcd) { return ((char)((bcd & 0x0F) + '0')); } unsigned Binary2BCD(unsigned a) { int t1, t2; t1 = a%10; t1 = t1 & 0x0F; a = a/10; t2 = a%10; t2 = 0x0F & t2; t2 = t2 << 4; t2 = 0xF0 & t2; t1 = t1 | t2; return t1; } unsigned BCD2Binary(unsigned a) { unsigned r,t; t = a & 0x0F; r = t; a = 0xF0 & a; t = a >> 4; t = 0x0F & t; r = t*10 + r; return r; } char* getDay(unsigned d) { static char day[10]; switch(d) { case 0 : strcpy(day, "Set Time "); break; case 1 : strcpy(day, "Sunday "); break; case 2 : strcpy(day, "Monday "); break; case 3 : strcpy(day, "Tuesday "); break; case 4 : strcpy(day, "Wednesday"); break; case 5 : strcpy(day, "Thursday "); break; case 6 : strcpy(day, "Friday "); break; case 7 : strcpy(day, "Saturday "); break; default : strcpy(day, "INVALID "); break; } return day; } char decodeKeys(unsigned key) { switch(key) { case 1 : return '6'; case 2 : return '='; case 3 : return '3'; case 4 : return '9'; //Not Available in 4x3 Keypad case 5 : return '*'; case 6 : return '+'; case 7 : return '-'; case 8 : return '/'; //Not Available in 4x3 Keypad case 9 : return '5'; case 10 : return '0'; case 11 : return '2'; case 12 : return '8'; //Not Available in 4x3 Keypad case 13 : return '4'; case 14 : return 'N'; case 15 : return '1'; case 16 : return '7'; //Not Availabale in 4x3 Keypad default : return 0; } } void main() { unsigned second, minute, hour, hr, day, dday, month, year, bellHour, bellMinute, hourB, minuteB, ls, bt, btLatch; unsigned menu = 0, mode = 0, mt, temp, temp2, normalBC, examBC, flag, ah = 0, am = 0, maxBell = 0, bs = 0, bc = 0, bellActive = 0, bellCnt = 0; char kp; char time[] = "00:00:00 "; char date[] = "00-00-00 "; ADCON1 = 0x0F; TRISA.F0 = 0; LATA.F0 = 0; I2C1_Init(90000); //DS1307 I2C is running at 50KHz keypadInit(); Lcd_Init(); // Initialize LCD Lcd_Cmd(_LCD_CLEAR); // Clear display Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off Lcd_Cmd(_LCD_CLEAR); // Clear display Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off // Lcd_Cmd(_LCD_BLINK_CURSOR_ON); Lcd_out(1,1,"Time:"); //Lcd_out(2,1,"Date:"); if(EEPROM_Read(0) == 0xAA) { normalBC = EEPROM_Read(1); examBC = EEPROM_Read(128); } else { normalBC = 0; examBC = 0; EEPROM_Write(1, 0); EEPROM_Write(128, 0); EEPROM_Write(0, 0xAA); } bt = 0; while(1) { second = readDS3231(0); minute = readDS3231(1); hour = readDS3231(2); hr = hour & 0b00111111; dday = readDS3231(3); day = readDS3231(4); month = readDS3231(5); year = readDS3231(6); hourB = BCD2Binary(hour); minuteB = BCD2Binary(minute); time[0] = BCD2UpperCh(hr); time[1] = BCD2LowerCh(hr); time[3] = BCD2UpperCh(minute); time[4] = BCD2LowerCh(minute); time[6] = BCD2UpperCh(second); time[7] = BCD2LowerCh(second); date[0] = BCD2UpperCh(day); date[1] = BCD2LowerCh(day); date[3] = BCD2UpperCh(month); date[4] = BCD2LowerCh(month); date[6] = BCD2UpperCh(year); date[7] = BCD2LowerCh(year); if(bs == 0) { if(mode == 0) //Normal Mode { if(dday != 6) //If Not Friday { bt = EEPROM_Read(bc*3 + 2); if(bt == 0xAA) bt = 2; else bt = 1; bellHour = EEPROM_Read(bc*3 + 3); bellMinute = EEPROM_Read(bc*3 + 4); } else //If Friday { bt = EEPROM_Read(bc*3 + 65); if(bt == 0xAA) bt = 2; else bt = 1; bellHour = EEPROM_Read(bc*3 + 66); bellMinute = EEPROM_Read(bc*3 + 67); } maxBell = normalBC; } else if(mode == 1) { if(dday != 6) //If Not Friday { bt = EEPROM_Read(129 + bc*3); if(bt == 0xAA) bt = 2; else bt = 1; bellHour = EEPROM_Read(130 + bc*3); bellMinute = EEPROM_Read(131 + bc*3); } else //If Friday { bt = EEPROM_Read(191 + bc*3); if(bt == 0xAA) bt = 2; else bt = 1; bellHour = EEPROM_Read(192 + bc*3); bellMinute = EEPROM_Read(193 + bc*3); } maxBell = examBC; } if(bellHour < hourB) bc++; else if(bellMinute <= minuteB) bc++; else { bs = 1; bc++; } if(bc > maxBell) bc = 0; } else { if(hourB >= bellHour) { if(minuteB >= bellMinute) { bellActive = 1; btLatch = bt; bs = 0; } } } if(bellActive == 1) { LATA.F0 = 1; bellCnt++; Delay_ms(2); if(bellCnt > (BELL_TIME * btLatch)) { bellActive = 0; bellCnt = 0; } } else { LATA.F0 = 0; bellCnt = 0; } kp = decodeKeys(readKeypad()); //Read Keypad if(kp == MENU_KEY) //Menu Selection via * button { menu++; mt = 0; if(menu > 5) menu = 0; } else if(isdigit(kp)) //If numberic value press { if(menu) { mt++; flag = 1; } } else if(kp == SAVE_EXIT) //Exit or Change Mode when # Pressed { if(menu) menu = 0; //Exit settings else mode = !mode; //Change Mode mt = 0; } if(menu == 0) { Lcd_out(1,1,"Time:"); Lcd_out(1, 6, time); if(mode == 0) Lcd_out(2, 1, "NORMAL:"); else Lcd_out(2, 1, "EXAM :"); Lcd_out(2, 8, getDay(dday)); } else if(menu == 1) //Set Time { Lcd_Out(1, 1, "Set Time "); Lcd_Out(2, 1, "Time: "); Lcd_Out(2, 7, time); if(mt && kp) { if(mt == 1 && kp < '3') { Lcd_Out(1,1,0); hour = 0x3F & BCD2Binary(hr); temp = hour % 10; hour = (kp - 48)*10 + temp; if(hour > 23) hour = 23; hour = Binary2BCD(hour); hour = hour & 0x3F; writeDS3231(2, hour); } else if(mt == 2) { hour = 0x3F & BCD2Binary(hr); hour = hour/10; hour = hour*10 + (kp - 48); hour = hour & 0x3F; if(hour < 24) { hour = Binary2BCD(hour); writeDS3231(2, hour); } } else if(mt == 3 && kp < '6') { minute = BCD2Binary(minute); temp = minute % 10; minute = (kp - 48)*10 + temp; minute = Binary2BCD(minute); writeDS3231(1, minute); } else if(mt == 4) { minute = BCD2Binary(minute); minute = minute/10; minute = minute*10 + (kp - 48); if(minute < 60) { minute = Binary2BCD(minute); writeDS3231(1, minute); } } else if(mt == 5) { second = 0; writeDS3231(0, second); menu = 0; mt = 0; } } } else if(menu == 2) // Set Date { Lcd_Out(1, 1, "Set Date "); Lcd_Out(2, 1, "Date: "); Lcd_Out(2, 7, date); if(mt && kp) { if(mt == 1 && kp < '4') { day = BCD2Binary(day); temp = day % 10; day = (kp - 48)*10 + temp; day = Binary2BCD(day); writeDS3231(4, day); } else if(mt == 2) { day = BCD2Binary(day); day = day/10; day = day*10 + (kp - 48); if(day < 32 && day > 0) { day = Binary2BCD(day); writeDS3231(4, day); } } else if(mt == 3 && kp < '2') { month = BCD2Binary(month); temp = month % 10; month = (kp - 48)*10 + temp; month = Binary2BCD(month); writeDS3231(5, month); } else if(mt == 4) { month = BCD2Binary(month); month = month/10; month = month*10 + (kp - 48); if(month < 13 && month > 0) { month = Binary2BCD(month); writeDS3231(5, month); } } else if(mt == 5) { year = BCD2Binary(year); temp = year % 10; year = (kp - 48)*10 + temp; year = Binary2BCD(year); writeDS3231(6, year); } else if(mt == 6) { year = BCD2Binary(year); year = year/10; year = year*10 + (kp - 48); year = Binary2BCD(year); writeDS3231(6, year); menu = 0; mt = 0; } } } else if(menu == 3) // Set Day { Lcd_Out(1, 1, "Set Day, SUN 1~7"); Lcd_Out(2, 1, "Day : "); Lcd_out(2, 7, getDay(dday)); if(mt <= 1) { if(flag == 1) { if(kp > '0' && kp < '8') writeDS3231(3, (unsigned short)((kp - 48))); bs = 0; bc = 0; } } else { mt = 0; menu = 0; } } else if(menu == 4) //Normal Bell { Lcd_Out(1, 1, "Set Normal Bell "); if(mt < 3) { Lcd_Out(2, 1, "Total Bells: "); Lcd_Chr(2, 15, (char)(normalBC%10) + 48); Lcd_Chr(2, 14, (char)((normalBC/10)%10) + 48); if(mt == 1) { if(flag && kp < '2') { normalBC = ((kp - 48)*10) + normalBC%10; EEPROM_Write(1, normalBC); flag = 0; bs = 0; bc = 0; } } else if(mt == 2) { if(flag) { temp = ((normalBC/10)*10) + (kp - 48); if(temp < 17) { normalBC = temp; EEPROM_Write(1, normalBC); flag = 0; bs = 0; bc = 0; } } } } else if(mt <= (2 + normalBC*6)) //Normal Not Friday { temp = ((mt - 3)/6); temp2 = ((mt - 3)%6); if(temp <= normalBC) { if(temp2 == 0) { if(flag) { ls = EEPROM_Read(temp*3 + 2); ah = EEPROM_Read(temp*3 + 3); am = EEPROM_Read(temp*3 + 4); flag = 0; } } else if(temp2 == 1) { if(flag) { if(kp == '1') ls = 0xAA; else ls = 0x00; EEPROM_Write((temp*3 + 2), ls); flag = 0; bs = 0; bc = 0; } } else if(temp2 == 2) { if(flag) { ah = ((kp - 48)*10) + ah%10; flag = 0; EEPROM_Write(((temp*3) + 3), ah); bs = 0; bc = 0; } } else if(temp2 == 3) { if(flag) { ah = ((ah/10)*10) + (kp - 48); flag = 0; EEPROM_Write(((temp*3) + 3), ah); bs = 0; bc = 0; } } else if(temp2 == 4) { if(flag) { am = ((kp - 48)*10) + am%10; flag = 0; EEPROM_Write(((temp*3) + 4), am); bs = 0; bc = 0; } } else if(temp2 == 5) { if(flag) { am = ((am/10)*10) + (kp - 48); flag = 0; EEPROM_Write(((temp*3) + 4), am); bs = 0; bc = 0; } } Lcd_Out(2, 1, "NDbell : - "); Lcd_Chr(2, 8, (temp%10) + 48); Lcd_Chr(2, 7, (temp/10) + 48); if(ls == 0xAA) Lcd_Chr(2, 10, 'L'); else Lcd_Chr(2, 10, 'S'); Lcd_Chr(2, 12, (ah/10) + 48); Lcd_Chr(2, 13, (ah%10) + 48); Lcd_Chr(2, 15, (am/10) + 48); Lcd_Chr(2, 16, (am%10) + 48); } else { mt = 0; menu = 0; } } else if(mt <= (2 + 2*normalBC*6)) //Normal Friday { temp = ((mt - 3 - normalBC*6)/6); temp2 = ((mt - 3)%6); if(temp <= normalBC) { if(temp2 == 0) { if(flag) { ls = EEPROM_Read(temp*3 + 65); ah = EEPROM_Read(temp*3 + 66); am = EEPROM_Read(temp*3 + 67); flag = 0; } } else if(temp2 == 1) { if(flag) { if(kp == '1') ls = 0xAA; else ls = 0x00; EEPROM_Write(temp*3 + 65, ls); flag = 0; bs = 0; bc = 0; } } else if(temp2 == 2) { if(flag) { ah = ((kp - 48)*10) + ah%10; flag = 0; EEPROM_Write(temp*3 + 66, ah); bs = 0; bc = 0; } } else if(temp2 == 3) { if(flag) { ah = ((ah/10)*10) + (kp - 48); flag = 0; EEPROM_Write(temp*3 + 66, ah); bs = 0; bc = 0; } } else if(temp2 == 4) { if(flag) { am = ((kp - 48)*10) + am%10; flag = 0; EEPROM_Write((temp*3 + 67), am); bs = 0; bc = 0; } } else if(temp2 == 5) { if(flag) { am = ((am/10)*10) + (kp - 48); flag = 0; EEPROM_Write((temp*3 + 67), am); bs = 0; bc = 0; } } else { mt = 0; menu = 0; } } Lcd_Out(2, 1, "FDbell : - "); Lcd_Chr(2, 8, (temp%10) + 48); Lcd_Chr(2, 7, (temp/10) + 48); if(ls == 0xAA) Lcd_Chr(2, 10, 'L'); else Lcd_Chr(2, 10, 'S'); Lcd_Chr(2, 12, (ah/10) + 48); Lcd_Chr(2, 13, (ah%10) + 48); Lcd_Chr(2, 15, (am/10) + 48); Lcd_Chr(2, 16, (am%10) + 48); } else { mt = 0; menu = 0; } } else if(menu == 5) //Exam Bell { Lcd_Out(1, 1, "Set Exam Bell "); if(mt < 3) { Lcd_Out(2, 1, "Total Bells: "); Lcd_Chr(2, 15, (char)(examBC%10) + 48); Lcd_Chr(2, 14, (char)((examBC/10)%10) + 48); if(mt == 1) { if(flag && kp < '2') { examBC = ((kp - 48)*10) + examBC%10; EEPROM_Write(128, examBC); flag = 0; bs = 0; bc = 0; } } else if(mt == 2) { if(flag) { temp = ((examBC/10)*10) + (kp - 48); if(temp < 17) { examBC = temp; EEPROM_Write(128, examBC); flag = 0; bs = 0; bc = 0; } } } } else if(mt <= (2 + examBC*6)) { temp = ((mt - 3)/6); temp2 = ((mt - 3)%6); if(temp <= examBC) { if(temp2 == 0) { if(flag) { ls = EEPROM_Read(129 + temp*3); ah = EEPROM_Read(130 + temp*3); am = EEPROM_Read(131 + temp*3); flag = 0; } } else if(temp2 == 1) { if(flag) { if(kp == '1') ls = 0xAA; else ls = 0x00; EEPROM_Write(temp*3 + 129, ls); flag = 0; bs = 0; bc = 0; } } else if(temp2 == 2) { if(flag) { ah = ((kp - 48)*10) + ah%10; flag = 0; EEPROM_Write((130 + temp*3), ah); bs = 0; bc = 0; } } else if(temp2 == 3) { if(flag) { ah = ((ah/10)*10) + (kp - 48); flag = 0; EEPROM_Write((130 + temp*3), ah); bs = 0; bc = 0; } } else if(temp2 == 4) { if(flag) { am = ((kp - 48)*10) + am%10; flag = 0; EEPROM_Write((131 + temp*3), am); bs = 0; bc = 0; } } else if(temp2 == 5) { if(flag) { am = ((am/10)*10) + (kp - 48); flag = 0; EEPROM_Write((131 + temp*3), am); bs = 0; bc = 0; } } Lcd_Out(2, 1, "NDbell : - "); Lcd_Chr(2, 8, (temp%10) + 48); Lcd_Chr(2, 7, (temp/10) + 48); if(ls == 0xAA) Lcd_Chr(2, 10, 'L'); else Lcd_Chr(2, 10, 'S'); Lcd_Chr(2, 12, (ah/10) + 48); Lcd_Chr(2, 13, (ah%10) + 48); Lcd_Chr(2, 15, (am/10) + 48); Lcd_Chr(2, 16, (am%10) + 48); } else { mt = 0; menu = 0; } } else if(mt <= (2 + 2*examBC*6)) { temp = ((mt - 3 - examBC*6)/6); temp2 = ((mt - 3)%6); if(temp <= examBC) { if(temp2 == 0) { if(flag) { ls = EEPROM_Read(191 + temp*3); ah = EEPROM_Read(192 + temp*3); am = EEPROM_Read(193 + temp*3); flag = 0; } } else if(temp2 == 1) { if(flag) { if(kp == '1') ls = 0xAA; else ls = 0x00; EEPROM_Write((191 + temp*3), ls); flag = 0; bs = 0; bc = 0; } } else if(temp2 == 2) { if(flag) { ah = ((kp - 48)*10) + ah%10; flag = 0; EEPROM_Write((192 + temp*3), ah); bs = 0; bc = 0; } } else if(temp2 == 3) { if(flag) { ah = ((ah/10)*10) + (kp - 48); flag = 0; EEPROM_Write((192 + temp*3), ah); bs = 0; bc = 0; } } else if(temp2 == 4) { if(flag) { am = ((kp - 48)*10) + am%10; flag = 0; EEPROM_Write((193 + temp*3), am); bs = 0; bc = 0; } } else if(temp2 == 5) { if(flag) { am = ((am/10)*10) + (kp - 48); flag = 0; EEPROM_Write((193 + temp*3), am); bs = 0; bc = 0; } } else { mt = 0; menu = 0; } } Lcd_Out(2, 1, "FDbell : - "); Lcd_Chr(2, 8, (temp%10) + 48); Lcd_Chr(2, 7, (temp/10) + 48); if(ls == 0xAA) Lcd_Chr(2, 10, 'L'); else Lcd_Chr(2, 10, 'S'); Lcd_Chr(2, 12, (ah/10) + 48); Lcd_Chr(2, 13, (ah%10) + 48); Lcd_Chr(2, 15, (am/10) + 48); Lcd_Chr(2, 16, (am%10) + 48); } else { mt = 0; menu = 0; } } Delay_ms(50); } }
อ้างอิง
ไม่มีความคิดเห็น:
แสดงความคิดเห็น