#define F_CPU 16000000UL // 16 MHz extern Oscillator #include #include #include #include #define LCD_RS 0 #define LCD_RW 1 #define LCD_E 7 #define EEPROMread(address)\ eeprom_read_byte((uint8_t*)address) #define EEPROMwrite(address, data)\ eeprom_write_byte((uint8_t*)address, data) //klockvariabler int sec0 = 0; int sec1 = 0; int min0 = 0; int min1 = 0; int hour0 = 0; int hour1 = 0; //knappvariabel int kn = 16; //0 = avlarmad, 1 = larmad, 2 = inloggad int state = 0; //passwords int rootPW = 1234; int pw; //larmlogg int logg[10][6]; int larmlogg = 0; int PINAstatus = 0; //globala timers int timeout = 0; int timeLarm[6]; int timeSiren = 0; //interrupt som aktiverar klockan vid over flow ISR(TIMER1_OVF_vect) { TCNT1H = 0x85; TCNT1L = 0xEE; clockTime(); } int main(void) { //initieringssekvens init(); //huvudprogrammets loop while(1) { kn = keyIn(); if(kn == 10 && state != 2) { PORTA &= 0xBF; angeKod(); } if(((PINA & 0x3F) != PINAstatus) && state == 1) { larmar(); } if((PINA & 0x3F) == 0 && state == 0 && larmlogg == 0) { PORTA = 0x40; }else{ PORTA &= 0xBF; } if(timeSiren != 0) { PORTC |= 0x40; } else { PORTC &= 0xBF; } } } void init(void) { DDRA = 0xC0; DDRB = 0xF0; DDRC = 0xFF; DDRD = 0xFF; //initierar password pw = 0; int k; for(k = 1; k < 5; k++) { pw = pw * 10 + eeprom_read_byte((uint8_t*)k); } int d; //initierar varje sektions timer for(d = 0; d < 6; d++) { timeLarm[d] = 0; } //initierar larmloggen int i; int j; for(i = 0; i < 10; i++) { for(j = 0; j < 6; j++) { logg[i][j] = 40; } } //initierar klockans interrupt TCCR1A = 0; TCCR1B = _BV(CS12); TCNT1H = 0x85; TCNT1L = 0xEE; TIMSK = _BV(TOIE1); sei(); //initierar displayen LCD_init(); } //separat inloggningssubrutin void angeKod(void) { int tmpPW = 0; kn = 16; int fyra = 0; timeout = 30; LCD_wait(); LCD_command(0x01); LCD_wait(); LCD_write("Ange kod + OK"); LCD_wait(); LCD_command(0x80 | 0x46); LCD_wait(); LCD_command(0x0E); while(timeout > 0) { if(((PINA & 0x3F) != PINAstatus) && state == 1) { larmar(); } kn = keyIn(); if(fyra < 4 && kn < 10) { tmpPW = tmpPW * 10 + kn; LCD_wait(); LCD_putchar(kn + 48); fyra++; timeout = 30; } if(fyra > 0 && kn == 15) { tmpPW = tmpPW / 10; fyra--; LCD_wait(); LCD_command((0x80 | 0x46) + fyra); LCD_wait(); LCD_putchar(' '); LCD_wait(); LCD_command((0x80 | 0x46) + fyra); timeout = 30; } if(fyra == 4 && kn == 10) { if(tmpPW == pw || tmpPW == rootPW) { if(state == 1) { detAllON(); } PORTC &= 0xBF; inloggad(); }else{ LCD_wait(); LCD_command(0x0C); LCD_wait(); LCD_command(0x01); LCD_wait(); LCD_write("Fel kod"); timeout = 3; while(timeout > 0){} } } if(kn == 11) { timeout = 0; } } LCD_wait(); LCD_command(0x0C); LCD_wait(); LCD_command(0x01); } //menysubrutin void inloggad(void) { state = 2; timeout = 30; LCD_wait(); LCD_command(0x0C); LCD_wait(); LCD_command(0x01); int meny = 11; int i = 0; while(timeout > 0) { switch(meny) { //huvudmeny, varje menybild motsvaras av ett case case 11: LCD_wait(); LCD_command(0x01); LCD_wait(); LCD_write("Huvudmeny"); LCD_wait(); LCD_command(0x80 | 0x0F); LCD_wait(); LCD_putchar(0x5E); LCD_wait(); LCD_command(0x80 | 0x40); LCD_wait(); LCD_write("1. Larm till?"); LCD_wait(); LCD_command(0x80 | 0x4F); LCD_wait(); LCD_putchar(0x76); i = 1; while(timeout > 0 && i == 1){ kn = keyIn(); switch(kn){ case 10: LCD_wait(); LCD_command(0x01); LCD_wait(); LCD_write("Larm aktiverat"); timeout = 32; while(timeout > 30){} timeout = 0; i = 2; break; case 11: LCD_wait(); LCD_command(0x01); timeout = 0; i = 0; break; case 12: meny = 15; timeout = 30; i = 0; break; case 13: meny = 12; timeout = 30; i = 0; break; } } break; case 12: LCD_wait(); LCD_command(0x01); LCD_wait(); LCD_write("Huvudmeny"); LCD_wait(); LCD_command(0x80 | 0x0F); LCD_wait(); LCD_putchar(0x5E); LCD_wait(); LCD_command(0x80 | 0x40); LCD_wait(); LCD_write("2. Byt kod?"); LCD_wait(); LCD_command(0x80 | 0x4F); LCD_wait(); LCD_putchar(0x76); i = 1; while(timeout > 0 && i == 1){ kn = keyIn(); switch(kn){ case 10: meny = 21; timeout = 30; i = 0; break; case 11: timeout = 0; i = 0; break; case 12: meny = 11; timeout = 30; i = 0; break; case 13: meny = 13; timeout = 30; i = 0; break; } } break; case 13: LCD_wait(); LCD_command(0x01); LCD_wait(); LCD_write("Huvudmeny"); LCD_wait(); LCD_command(0x80 | 0x0F); LCD_wait(); LCD_putchar(0x5E); LCD_wait(); LCD_command(0x80 | 0x40); LCD_wait(); LCD_write("3. Larmlista?"); LCD_wait(); LCD_command(0x80 | 0x4F); LCD_wait(); LCD_putchar(0x76); i = 1; while(timeout > 0 && i == 1){ kn = keyIn(); switch(kn){ case 10: meny = 31; timeout = 30; i = 0; break; case 11: timeout = 0; i = 0; break; case 12: meny = 12; timeout = 30; i = 0; break; case 13: meny = 14; timeout = 30; i = 0; break; } } break; case 14: LCD_wait(); LCD_command(0x01); LCD_wait(); LCD_write("Huvudmeny"); LCD_wait(); LCD_command(0x80 | 0x0F); LCD_wait(); LCD_putchar(0x5E); LCD_wait(); LCD_command(0x80 | 0x40); LCD_wait(); LCD_write("4. Sektion?"); LCD_wait(); LCD_command(0x80 | 0x4F); LCD_wait(); LCD_putchar(0x76); i = 1; while(timeout > 0 && i == 1){ kn = keyIn(); switch(kn){ case 10: meny = 41; timeout = 30; i = 0; break; case 11: timeout = 0; i = 0; break; case 12: meny = 13; timeout = 30; i = 0; break; case 13: meny = 15; timeout = 30; i = 0; break; } } break; case 15: LCD_wait(); LCD_command(0x01); LCD_wait(); LCD_write("Huvudmeny"); LCD_wait(); LCD_command(0x80 | 0x0F); LCD_wait(); LCD_putchar(0x5E); LCD_wait(); LCD_command(0x80 | 0x40); LCD_wait(); LCD_write("5. Byt tid?"); LCD_wait(); LCD_command(0x80 | 0x4F); LCD_wait(); LCD_putchar(0x76); i = 1; while(timeout > 0 && i == 1){ kn = keyIn(); switch(kn){ case 10: meny = 51; timeout = 30; i = 0; break; case 11: timeout = 0; i = 0; break; case 12: meny = 14; timeout = 30; i = 0; break; case 13: meny = 11; timeout = 30; i = 0; break; } } break; //byt kod case 21: LCD_wait(); LCD_command(0x01); LCD_wait(); LCD_write("Ange gammal kod:"); int tmpPW = 0; tmpPW = skrivkod(); if((tmpPW != pw) && (tmpPW != rootPW)){ LCD_wait(); LCD_command(0x01); LCD_wait(); LCD_write("Fel kod"); timeout = 32; while(timeout > 30){} }else{ LCD_wait(); LCD_command(0x01); LCD_wait(); LCD_write("Ange ny kod:"); tmpPW = skrivkod(); LCD_wait(); LCD_command(0x01); LCD_wait(); LCD_write("Samma kod igen:"); if(tmpPW != skrivkod()){ LCD_wait(); LCD_command(0x01); LCD_wait(); LCD_write("Fel kod"); timeout = 32; while(timeout > 30){} }else{ pw = tmpPW; LCD_wait(); LCD_command(0x01); LCD_wait(); LCD_write("Uppdaterat kod"); //skriver den nya koden till eeprom i fall av elavbrott int k; for(k = 1; k < 5; k++){ int l; int m = 10000; for(l = 0 ; l < k; l++){ m = m / 10; } eeprom_write_byte((uint8_t*) k, ((pw / m) % 10)); } timeout = 32; while(timeout > 30){} } } meny = 11; break; //larmlista case 31: LCD_wait(); LCD_command(0x01); larmlista(); meny = 11; break; //deakrivera sektion case 41: LCD_wait(); LCD_command(0x01); LCD_wait(); LCD_write("Deaktivera"); int sek = 0; LCD_wait(); LCD_command(0x80 | 0x40); LCD_wait(); LCD_write("sektion: "); LCD_wait(); LCD_command(0x0E); while(timeout > 0){ kn = keyIn(); if(kn > 0 && kn < 7){ sek = kn; LCD_wait(); LCD_putchar(48 + kn); LCD_wait(); LCD_command(0x80 | 0x49); timeout = 30; } if(kn == 10 && sek > 0){ detOFF(sek); timeout = 0; } if(kn == 11){ timeout = 0; } } LCD_wait(); LCD_command(0x0C); meny = 11; timeout = 30; break; //byt tid case 51: LCD_wait(); LCD_command(0x01); LCD_wait(); LCD_write("Ange tid (HH:MM)"); skrivtid(); meny = 11; timeout = 30; break; } } //anger om larmets status efter utloggning if(i == 2){state = 1;}else{state = 0;} timeout = 0; LCD_wait(); LCD_command(0x01); } //menysubrutin vid kodbyte, returnerar angiven kod int skrivkod(void) { int fyra = 0; int kod = 0; LCD_wait(); LCD_command(0x80 | 0x46); LCD_wait(); LCD_command(0x0E); while(timeout > 0) { kn = keyIn(); if(fyra < 4 && kn < 10) { kod = kod * 10 + kn; LCD_wait(); LCD_putchar(kn + 48); fyra++; timeout = 30; } if(fyra > 0 && kn == 15) { kod = kod / 10; fyra--; LCD_wait(); LCD_command((0x80 | 0x46) + fyra); LCD_wait(); LCD_putchar(' '); LCD_wait(); LCD_command((0x80 | 0x46) + fyra); timeout = 30; } if(fyra == 4 && kn == 10) { timeout = 30; LCD_wait(); LCD_command(0x0C); return kod; } if(kn == 11) { timeout = 0; return 11111; } } } //menysubrutin vid tidbyte, uppdaterar klockan void skrivtid(void) { int fem = 0; int h1 = 0; int h0 = 0; int m1 = 0; int m0 = 0; LCD_wait(); LCD_command(0x80 | 0x48); LCD_wait(); LCD_putchar(':'); LCD_wait(); LCD_command(0x80 | 0x46); LCD_wait(); LCD_command(0x0E); timeout = 30; while(timeout > 0) { kn = keyIn(); if(fem == 0 && kn < 3) { h1 = kn; LCD_wait(); LCD_putchar(kn + 48); fem++; timeout = 30; } else if(fem == 1 && ((h1 < 2 && kn < 10) || (h1 == 2 && kn < 4))) { h0 = kn; LCD_wait(); LCD_putchar(kn + 48); LCD_wait(); LCD_putchar(':'); fem += 2; timeout = 30; } else if(fem == 3 && kn < 6) { m1 = kn; LCD_wait(); LCD_putchar(kn + 48); fem++; timeout = 30; } else if(fem == 4 && kn < 10) { m0 = kn; LCD_wait(); LCD_putchar(kn + 48); fem++; timeout = 30; } else if(fem > 0 && kn == 15) { if(fem == 3){fem -= 2;}else{fem--;} LCD_wait(); LCD_command((0x80 | 0x46) + fem); timeout = 30; } else if(fem == 5 && kn == 10) { hour1 = h1; hour0 = h0; min1 = m1; min0 = m0; sec1 = 0; sec0 = 0; LCD_wait(); LCD_command(0x0C); timeout = 0; } else if(kn == 11) { timeout = 0; } } } //larmloggmeny, kvittering av larm void larmlista(void) { int i = 0; int j = 0; int d; timeout = 30; while(timeout > 0) { LCD_wait(); LCD_command(0x01); LCD_wait(); LCD_write("Sektion"); LCD_wait(); LCD_putchar((char) (logg[i][0] + 48)); LCD_wait(); LCD_putchar(' '); LCD_wait(); LCD_putchar((char) (logg[i][1] + 48)); LCD_wait(); LCD_putchar((char) (logg[i][2] + 48)); LCD_wait(); LCD_putchar(':'); LCD_wait(); LCD_putchar((char) (logg[i][3] + 48)); LCD_wait(); LCD_putchar((char) (logg[i][4] + 48)); LCD_wait(); LCD_putchar(' '); LCD_wait(); LCD_putchar(0x5E); //okvitterade larm ligger kvar if(logg[i][5] == 1) { LCD_wait(); LCD_command(0x80 | 0x40); LCD_wait(); LCD_write("Kvittera? (OK)"); } LCD_wait(); LCD_command(0x80 | 0x4F); LCD_wait(); LCD_putchar(0x76); j = 1; while(timeout > 0 && j == 1) { kn = keyIn(); switch(kn) { case 10: logg[i][5] = 0; timeout = 30; j = 0; larmlogg = 0; for(d = 0; d < 10; d++){ if(logg[d][5] == 1){ larmlogg = 1; } } if(larmlogg == 0){ PORTA = 0x00; } break; case 11: timeout = 0; break; case 12: if(i == 0){ i = 9; }else{ i--; } timeout = 30; j = 0; break; case 13: if(i == 9){ i = 0; }else{ i++; } timeout = 30; j = 0; break; } } } timeout = 30; } //subrutin som kontrollerar sektionerna om larmet aktiverats void larmar(void) { int d; int i; int j; for(d = 0; d < 6; d++) { if(((PINA & 0x3F & ~PINAstatus) == (1<