#include #include #include #include #include "uart.h" /* Button matrix between PB3-PB4, PC0-PC3 * PC0-PC3 are inputs, default pull-up * PB3-PB4 are pulled to ground (alternating) while the above are read */ void print_nibble(uint8_t nibble) { nibble += 0x30; if (nibble > 0x39) nibble += 7; uart_putc(nibble); } void print_int8hex(uint8_t val) { print_nibble(val >> 4); print_nibble(val & 0x0F); } uint8_t getButtonState() { uint8_t val = 0; // Pull upper button line (PB4) down PORTB |= (1 << PB3); PORTB &= ~(1 << PB4); _delay_ms(1); val = ((~PINC) << 4); // Pull lower button line (PB3) down PORTB &= ~(1 << PB3); PORTB |= (1 << PB4); _delay_ms(1); val |= (~PINC) & 0x0F; return val; } uint8_t getrelay(uint8_t n) { uint8_t v = 0; switch(n) { case 0: v = (PIND >> PD2); break; case 1: v = (PIND >> PD3); break; case 2: v = (PIND >> PD4); break; case 3: v = (PIND >> PD5); break; case 4: v = (PIND >> PD6); break; case 5: v = (PIND >> PD7); break; case 6: v = (PINB >> PB0); break; case 7: v = (PINB >> PB1); break; } return(~v & 1); } void setrelay(uint8_t n, uint8_t s) { if (s) { switch(n) { case 0: PORTD &= ~(1 << PD2); break; case 1: PORTD &= ~(1 << PD3); break; case 2: PORTD &= ~(1 << PD4); break; case 3: PORTD &= ~(1 << PD5); break; case 4: PORTD &= ~(1 << PD6); break; case 5: PORTD &= ~(1 << PD7); break; case 6: PORTB &= ~(1 << PB0); break; case 7: PORTB &= ~(1 << PB1); break; } } else { switch(n) { case 0: PORTD |= (1 << PD2); break; case 1: PORTD |= (1 << PD3); break; case 2: PORTD |= (1 << PD4); break; case 3: PORTD |= (1 << PD5); break; case 4: PORTD |= (1 << PD6); break; case 5: PORTD |= (1 << PD7); break; case 6: PORTB |= (1 << PB0); break; case 7: PORTB |= (1 << PB1); break; } } } int main() { DDRC &= ~(0b1111); // This sets PC0 to PC3 to input PORTC |= 0b1111; // This makes dito pull-up per default DDRB |= (1 << PB3) | (1 << PB4); // Keybad rows DDRD |= 0b11111100; // PD2 to PD7 for relay DDRB |= 0b00000011; // PB0 and PB1 for relay // Same with PORT, so relays stay off PORTD |= 0b11111100; PORTB |= 0b00000011; sei(); uint8_t c,p,d,i; p = 0; while (1) { c = getButtonState(); d = c ^ p; p = c; for (i = 0; i<8; i++) { if (d & c & 0x80) { setrelay(i, 1 - getrelay(i)); print_nibble(i); uart_putc('\r'); uart_putc('\n'); } d = d << 1; c = c << 1; } }; }