#define F_CPU 1000000UL #define LCD_dat PORTB #define rs PORTD1 // rs pin 1 #define en PORTD5 // en pin 5 #define buzzer PORTD0 #include #include #include #include char keypressed = 0; uint8_t keyPressCode; volatile char charData; volatile char arm[] = "Armering Kod:"; volatile char ratt[] = "Ratt kod"; volatile char fel[] = "Fel kod"; volatile char disarm[] = "Desarmering Kod:"; volatile char ratt_d[] = "Desarmerad"; char ange_ny_kod[] = "Ange ny kod: "; char alarm_toggle_bit = 0; char sensor_toggle_bit = 0; char ready_bit = 2; char pin_bit; volatile char saved_code[] = "1234"; volatile char input_code[5]; int codeCharCounter = 0; int counter; /* Delays */ void delay_1ms() { asm volatile ( " ldi r18, 2 \n" " ldi r19, 75 \n" "1: dec r19 \n" " brne 1b \n" " dec r18 \n" " brne 1b \n" " rjmp 1f \n" "1: \n" ); } void delay_10ms() { asm volatile ( " ldi r18, 13 \n" " ldi r19, 252 \n" "1: dec r19 \n" " brne 1b \n" " dec r18 \n" " brne 1b \n" " nop \n" ); } void delay_100ms() { asm volatile ( " ldi r18, 130 \n" " ldi r19, 222 \n" "1: dec r19 \n" " brne 1b \n" " dec r18 \n" " brne 1b \n" " nop \n" ); } /* Handles LCD functions */ void lcd_cmd(unsigned char ch) { LCD_dat = ch; PORTD &= 0b11111101;//(0 << rs); PORTD |= (1 << en); delay_1ms(); PORTD &= 0b11011111;//(0 << en); } /* Handles single character output to the LCD */ void lcd_data(unsigned char ch) { LCD_dat = ch; PORTD |= (1 << rs); PORTD |= (1 << en); PORTD &= 0b11011111;//(0 << en); // alla bitar = 0, finns risk att PD0 påverkas, se över //PORTD |= (0 << rs); } /* Initializes the LCD */ void lcd_init() { lcd_cmd(0x38); // (8 bitar, 1 rad, 5x8 punkter) delay_100ms(); lcd_cmd(0x0e); // (Display on, Cursor on, Cursor blink OFF) delay_100ms(); lcd_cmd(0x01); // (Clear display) delay_100ms(); } /* Assigns value to keyPressCode corresponding to the column and row hexadecimal identifiers */ void keypadscan() { DDRA = 0x0f; PORTA = 0xf0; if(PINA == 0b11110000) return delay_1ms(); keyPressCode = PINA; DDRA = 0b11110000; PORTA = 0b00001111; delay_1ms(); //x = PINA; // Använde dessa som korta delays innan, verkar behövas i metoden keyPressCode |= PINA; } /* Translates value of keyPressCode to assigned character and prints text to the display, and otherwise assigns tasks to buttons */ void key_read() { if(keyPressCode == 0x77) { lcd_data('1'); delay_100ms(); delay_100ms(); charData = '1'; } if(keyPressCode == 0xb7) { lcd_data('2'); delay_100ms(); delay_100ms(); charData = '2'; } if(keyPressCode == 0xe7) { lcd_data('3'); delay_100ms(); delay_100ms(); charData = '3'; } if(keyPressCode == 0xd7) { lcd_data('4'); delay_100ms(); delay_100ms(); charData = '4'; } if(keyPressCode == 0x7b) { lcd_data('5'); delay_100ms(); delay_100ms(); charData = '5'; } if(keyPressCode == 0xbb) { lcd_data('6'); delay_100ms(); delay_100ms(); charData = '6'; } if(keyPressCode == 0xeb) { lcd_data('7'); delay_100ms(); delay_100ms(); charData = '7'; } if(keyPressCode == 0xdb) { lcd_data('8'); delay_100ms(); delay_100ms(); charData = '8'; } if(keyPressCode == 0x7d) { lcd_data('9'); delay_100ms(); delay_100ms(); charData = '9'; } if(keyPressCode == 0xbd) { lcd_data('0'); delay_100ms(); delay_100ms(); charData = '0'; } if(keyPressCode == 0xde) { lcd_cmd(0x01); delay_100ms(); delay_100ms(); } if(keyPressCode == 0xdd) { charData = 'x'; } /* Arms the alarm */ if(keyPressCode == 0xee) { delay_100ms(); delay_100ms(); charData = 'a'; } /* Changes arming and disarming password */ if(keyPressCode == 0x7e) { lcd_cmd(0x01); delay_100ms(); for (int n = 0; n < strlen(ange_ny_kod); n++) // meddelandet skrivs ut { lcd_data(ange_ny_kod[n]); } int i = 0; delay_100ms(); keyPressCode = 0x00; while(i<4) { keypadscan(); if(keyPressCode != 0x00) { key_read(); saved_code[i] = charData; i++; delay_100ms(); } delay_100ms(); } lcd_cmd(0x01); delay_100ms(); } keyPressCode = 0x00; } /* Checks if user input matches working password and prints relevant text to LCD */ void code_check() { lcd_cmd(0x01); delay_100ms(); /* Notifies user of arming and disarming status when entering password */ if(sensor_toggle_bit == 1) { for (int n = 0; n < strlen(disarm); n++) // meddelandet skrivs ut { lcd_data(disarm[n]); } } else { for (int n = 0; n < strlen(arm); n++) // meddelandet skrivs ut { lcd_data(arm[n]); } } /* Automatically stores input password when input reaches original password length */ for(int n = 0; n < strlen(saved_code); n++) // kod matas in, sparas i string { while(1) { keypadscan(); if(keyPressCode != 0x00) { key_read(); input_code[n] = charData; break; } } } /* Compares input password to true password and prints match status */ for(int n = 0; n < strlen(saved_code); n++) { if(input_code[n] != saved_code[n]) { lcd_cmd(0x01); delay_100ms(); for (int n = 0; n < strlen(fel); n++) // "fel kod" skrivs ut { lcd_data(fel[n]); } } else if(n + 1 == strlen(saved_code) && input_code[n] == saved_code[n]) { lcd_cmd(0x01); delay_100ms(); for (int n = 0; n < strlen(ratt); n++) // rätt kod { lcd_data(ratt[n]); } if(sensor_toggle_bit == 1) { sensor_toggle_bit = 0; buzzer_toggle(); } else { sensor_toggle_bit = 1; ready_bit = 1; } delay_100ms(); } } pin_bit = PIND; delay_100ms(); } /* Switches the alarm buzzer on or off depending on previous state */ void buzzer_toggle() { if (alarm_toggle_bit == 1) { PORTD &= ~(1 << buzzer); alarm_toggle_bit = 0; delay_100ms(); } else { PORTD |= 0b00000001; alarm_toggle_bit = 1; delay_100ms(); } } void lcd_cmd(unsigned char ch); void lcd_data(unsigned char ch); int main(void) { DDRD = 0b11110111; DDRB = 0b11111111; PORTD = 0x00; DDRA = 0x0f; lcd_init(); while(1) { keypadscan(); if(keyPressCode != 0x00) { key_read(); if(charData == 'a') // armeringsknappen { code_check(); // kod matas in, jämförs med gammal kod } if(charData == 'x') { buzzer_toggle(); charData = 'z'; } } /* Allows the buzzer to activate when the device is armed */ if(ready_bit == 1 && sensor_toggle_bit == 1) { delay_10ms(); pin_bit = PIND; delay_10ms(); while(pin_bit == 0b00001010 || pin_bit == 0b00001011) { pin_bit = PIND; delay_10ms(); } while(pin_bit == 0b00000010 || pin_bit == 0b00001011) { pin_bit = PIND; delay_10ms(); } while(pin_bit == 0b00001010 || pin_bit == 0b00001011) { buzzer_toggle(); ready_bit = 0; break; } } } }