diff --git a/GccApplication3.cproj b/GccApplication3.cproj index e5280cf..f37922e 100644 --- a/GccApplication3.cproj +++ b/GccApplication3.cproj @@ -96,10 +96,13 @@ - + compile - + + compile + + compile diff --git a/app.c b/app.c deleted file mode 100644 index 095a5f9..0000000 --- a/app.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * core.c - * - * Created: 13.04.2023 14:28:40 - * Author: mrnek - */ -#include -#include -#include "app.h" - -#define MASK_PIND 0b11110000 - -void check_physical_keys_state(struct key *keys) { - uint8_t row1; - PORTC &= ~(1 << 3); - row1 = PIND & MASK_PIND; - if (row1 & (1 << 4)) keys[0].is_physical_pressed = false; else keys[0].is_physical_pressed = true; - if (row1 & (1 << 5)) keys[1].is_physical_pressed = false; else keys[1].is_physical_pressed = true; - if (row1 & (1 << 6)) keys[2].is_physical_pressed = false; else keys[2].is_physical_pressed = true; - if (row1 & (1 << 7)) keys[3].is_physical_pressed = false; else keys[3].is_physical_pressed = true; - PORTC |= (1 << 3); - - PORTC &= ~(1 << 2); - row1 = PIND & MASK_PIND; - if (row1 & (1 << 4)) keys[4].is_physical_pressed = false; else keys[4].is_physical_pressed = true; - if (row1 & (1 << 5)) keys[5].is_physical_pressed = false; else keys[5].is_physical_pressed = true; - if (row1 & (1 << 6)) keys[6].is_physical_pressed = false; else keys[6].is_physical_pressed = true; - if (row1 & (1 << 7)) keys[7].is_physical_pressed = false; else keys[7].is_physical_pressed = true; - PORTC |= (1 << 2); - - PORTC &= ~(1 << 1); - row1 = PIND & MASK_PIND; - if (row1 & (1 << 4)) keys[8].is_physical_pressed = false; else keys[8].is_physical_pressed = true; - if (row1 & (1 << 5)) keys[9].is_physical_pressed = false; else keys[9].is_physical_pressed = true; - if (row1 & (1 << 6)) keys[10].is_physical_pressed = false; else keys[10].is_physical_pressed = true; - if (row1 & (1 << 7)) keys[11].is_physical_pressed = false; else keys[11].is_physical_pressed = true; - PORTC |= (1 << 1); - - PORTC &= ~(1 << 0); - row1 = PIND & MASK_PIND; - if (row1 & (1 << 4)) keys[12].is_physical_pressed = false; else keys[12].is_physical_pressed = true; - if (row1 & (1 << 5)) keys[13].is_physical_pressed = false; else keys[13].is_physical_pressed = true; - if (row1 & (1 << 6)) keys[14].is_physical_pressed = false; else keys[14].is_physical_pressed = true; - if (row1 & (1 << 7)) keys[15].is_physical_pressed = false; else keys[15].is_physical_pressed = true; - PORTC |= (1 << 0); -} - -void debounce(struct key *undebounce_keys) { - -} diff --git a/app.h b/app.h deleted file mode 100644 index d9ccc99..0000000 --- a/app.h +++ /dev/null @@ -1,17 +0,0 @@ -#include -/* - * core.h - * - * Created: 13.04.2023 14:23:22 - * Author: mrnek - */ -#define KEYS_AMOUNT 16 - - -struct key { - unsigned long pressed_time; - bool is_physical_pressed; - bool is_logical_pressed; -}; - -void check_physical_keys_state(struct key *keys); \ No newline at end of file diff --git a/calculator.c b/calculator.c new file mode 100644 index 0000000..c1dee62 --- /dev/null +++ b/calculator.c @@ -0,0 +1,187 @@ +#include +#include + +enum calculator_state { + NUMBER_FIRST, + NUMBER_SECOND, + RESULT +}; +enum calculator_op { + NO_OP, + ADD, + SUB, + DIV, + MUL +}; +struct calculator { + // 1 число + int num1; + // 2 число + int num2; + // 3 операция + enum calculator_op operation; + // 4 результат + int result; + // 5 состояние атомата + enum calculator_state state; +}; + + + +int main() { + struct calculator calc; + calc.state = NUMBER_FIRST; + calc.operation = NO_OP; + calc.num1 = 0; + calc.num2 = 0; + calc.result = 0; + int input; + while (1) { + scanf("%d", &input); + switch (calc.state) { + case NUMBER_FIRST: + switch (input) { + case 0: + calc.num1 = (calc.num1 * 10) + 7; + break; + case 1: + calc.num1 = (calc.num1 * 10) + 8; + break; + case 2: + calc.num1 = (calc.num1 * 10) + 9; + break; + case 3: + calc.operation = DIV; + calc.state = NUMBER_SECOND; + break; + case 4: + calc.num1 = (calc.num1 * 10) + 4; + break; + case 5: + calc.num1 = (calc.num1 * 10) + 5; + break; + case 6: + calc.num1 = (calc.num1 * 10) + 6; + break; + case 7: + calc.operation = MUL; + calc.state = NUMBER_SECOND; + break; + case 8: + calc.num1 = (calc.num1 * 10) + 1; + break; + case 9: + calc.num1 = (calc.num1 * 10) + 2; + case 10: + calc.num1 = (calc.num1 * 10) + 3; + break; + case 11: + calc.operation = SUB; + calc.state = NUMBER_SECOND; + break; + case 12: + calc.num1 = 0; + break; + case 13: + calc.state = NUMBER_FIRST; + calc.operation = NO_OP; + calc.num1 = 0; + calc.num2 = 0; + calc.result = 0; + break; + case 14: + break; + case 15: + calc.operation = ADD; + calc.state = NUMBER_SECOND; + break; + } + printf("num1: %d | num2: %d | result: %d | operation: %d | state: %d", calc.num1, calc.num2, calc.result, calc.operation, calc.state); + break; + + case NUMBER_SECOND: + switch (input) { + case 0: + calc.num2 = (calc.num2 * 10) + 7; + break; + case 1: + calc.num2 = (calc.num2 * 10) + 8; + break; + case 2: + calc.num2 = (calc.num2 * 10) + 9; + break; + case 3: + break; + case 4: + calc.num2 = (calc.num2 * 10) + 4; + break; + case 5: + calc.num2 = (calc.num2 * 10) + 5; + break; + case 6: + calc.num2 = (calc.num2 * 10) + 6; + break; + case 7: + break; + case 8: + calc.num2 = (calc.num2 * 10) + 1; + break; + case 9: + calc.num2 = (calc.num2 * 10) + 2; + case 10: + calc.num2 = (calc.num2 * 10) + 3; + break; + case 11: + break; + case 12: + calc.num2 = 0; + break; + case 13: + calc.state = NUMBER_FIRST; + calc.operation = NO_OP; + calc.num1 = 0; + calc.num2 = 0; + calc.result = 0; + break; + case 14: + switch (calc.operation) { + case ADD: + calc.result = calc.num1 + calc.num2; + calc.state = RESULT; + break; + case SUB: + calc.result = calc.num1 - calc.num2; + calc.state = RESULT; + break; + case MUL: + calc.result = calc.num1 * calc.num2; + calc.state = RESULT; + break; + case DIV: + calc.result = calc.num1 / calc.num2; + calc.state = RESULT; + break; + + } + break; + case 15: + break; + } + printf("num1: %d | num2: %d | result: %d | operation: %d | state: %d", calc.num1, calc.num2, calc.result, calc.operation, calc.state); + break; + case RESULT: + switch (input) { + case 14: + calc.state = NUMBER_FIRST; + calc.operation = NO_OP; + calc.num1 = 0; + calc.num2 = 0; + calc.result = 0; + printf("num1: %d | num2: %d | result: %d | operation: %d | state: %d", calc.num1, calc.num2, calc.result, calc.operation, calc.state); + break; + } + break; + + } + } +} \ No newline at end of file diff --git a/keyboard.c b/keyboard.c new file mode 100644 index 0000000..4ef1cdb --- /dev/null +++ b/keyboard.c @@ -0,0 +1,68 @@ +/* +* core.c +* +* Created: 13.04.2023 14:28:40 +* Author: mrnek +*/ +#include +#include +#include +#include "keyboard.h" +#include "timer.h" + +#define MASK_PIND 0b11110000 + +static void set_key_event(struct key *button); + +void get_physical_keys(struct key *keys) { + uint8_t row; + for (int i = 0; i < KEYS_AMOUNT / 4; i++) { + PORTC &= ~(1 << i); + for(volatile long i = 0; i < 1000; i++){}; + row = PIND & MASK_PIND; + if (row & (1 << 4)) keys[i * 4].physical = false; else keys[i * 4].physical = true; + if (row & (1 << 5)) keys[i * 4 + 1].physical = false; else keys[i * 4 + 1].physical = true; + if (row & (1 << 6)) keys[i * 4 + 2].physical = false; else keys[i * 4 + 2].physical = true; + if (row & (1 << 7)) keys[i * 4 + 3].physical = false; else keys[i * 4 + 3].physical = true; + PORTC |= (1 << i); + } +} + +void get_logical_keys(struct key *undc_keys) { + unsigned long timestamp = get_millis(); + for(int i = 0; i < KEYS_AMOUNT; i++) { + if (undc_keys[i].physical != undc_keys[i].logical) { + if (timestamp - undc_keys[i].time >= DEBOUNCE_MS_THRESHOLD) { + undc_keys[i].logical = undc_keys[i].physical; + set_key_event(&undc_keys[i]); + } + } else { + undc_keys[i].time = timestamp; + + } + } +} + +void fill_buttons_names(struct key *buttons) { + for (int i = 0; i < KEYS_AMOUNT; i++) { + buttons[i].button = i; + } +} + +/************************************************************************/ +/* */ +/************************************************************************/ +static void set_key_event(struct key *button) { + if (button->logical == true) { + button->on_down = true; + } else { + button->on_up = true; + } +} + +void get_event(struct key *button, bool *up, bool *down) { + *up = button->on_up; + *down = button->on_down; + button->on_up = false; + button->on_down = false; +} \ No newline at end of file diff --git a/keyboard.h b/keyboard.h new file mode 100644 index 0000000..450e3db --- /dev/null +++ b/keyboard.h @@ -0,0 +1,27 @@ +#include +/* + * core.h + * + * Created: 13.04.2023 14:23:22 + * Author: mrnek + */ +#define KEYS_AMOUNT 16 +#define DEBOUNCE_MS_THRESHOLD 20 + +struct key { + char button; + unsigned long time; + bool physical; + bool logical; + bool on_down; + bool on_up; +}; + + +void get_physical_keys(struct key *keys); + +void get_logical_keys(struct key *undc_keys); + +void fill_buttons_names(struct key *buttons); + +void get_event(struct key *button, bool *up, bool *down); \ No newline at end of file diff --git a/main.c b/main.c index ba8669c..a62a143 100644 --- a/main.c +++ b/main.c @@ -3,68 +3,105 @@ #include #include #include "timer.h" -#include "app.h" +#include "keyboard.h" #include "uart.h" -void setup() { - USART_Init(MYUBRR); - - DDRD = 0b00001111; - PORTD = 0b11110000; +void setup_registers() { + MCUCR &= ~(1 << 4); // PUD + MCUCR &= ~(1 << 5); + MCUCR &= ~(1 << 6); + MCUCR &= ~(1 << 7); + DDRD &= 0x0F; + PORTD |= 0xF0; DDRC = 0b111111; PORTC = 0b001111; } - -void countKeysPressedTime(char *keys) { - - for (int i = 0; i < 16; i++) { - keyTimeMap[i].key = i; - if (keys[i] == 0) { - keyTimeMap[i].time += 5; - } else { - keyTimeMap[i].time = 0; - } - } +void setup() { + USART_Init(MYUBRR); + setup_timer(); + setup_registers(); } -//void debounce(char *keys) { - //if (ms % 5 != 0) return; - //isDebounced = 0; - //checkKeysState(newKeysState); -// - //for (int i = 0; i < 16; i++) { - //if (newKeysState[i] != keys[i]) { - //confidenceLevel = 0; - //} - //} -// - //if (confidenceLevel < 6) confidenceLevel++; - //if (confidenceLevel == 5) { - //for (int i = 0; i < 16; i++) { - //debouncedKeys[i] = keys[i]; - //} - //isDebounced = 1; - //confidenceLevel = 0; - //} -//} - -void loop() { - -} +int up_amoumt = 0; +int down_amount = 0; +int diff = 0; +int diff_prev = 0; int main(void) { - setup(); + puts("Hello\r\n"); + struct key keys[KEYS_AMOUNT]; + fill_buttons_names(keys); while(1) { + get_physical_keys(keys); + get_logical_keys(keys); - USART_Transmit(0x6F); - //for(volatile long i = 0; i < 100000; i++){}; - loop(); + for (int i = 0; i < KEYS_AMOUNT; i++) { + bool up, down; + get_event(&keys[i], &up, &down); + if (down) + { + printf("%d", keys[i].button); + } + } + + //down_amount = 0; + //up_amoumt = 0; + // + //for (int i = 0; i < KEYS_AMOUNT; i++) { + //if (keys[i].logical == false) { + //down_amount++; + //} else { + //up_amoumt++; + //} + ////bool up; + ////bool down; + ////get_event(&keys[i], &up, &down); + ////if (down) { + ////down_amount++; + ////} + ////else { + ////up_amoumt++; + ////} + //} + //diff = up_amoumt; + ////if (diff != diff_prev) { + //for (int i = 0; i < KEYS_AMOUNT; i++) { + //bool up, down; + //get_event(&keys[i], &up, &down); + ////if (keys[i].logical == true) { + ////printf("%d", keys[i].button); + ////} + //if (down) { + ////printf("%s\r\n", i); + //printf("%d", keys[i].button); + //} + //} + ////} + //diff_prev = diff; } } -int fputc(int ch, FILE *stream){ - USART_Transmit(ch); +int puts(const char * __str){ + int len = strlen(__str); + for(size_t i = 0; i < len; i++){ + while (!(UCSR0A & (1< +#include "timer.h" +/* + * timer.c + * + * Created: 13.04.2023 14:13:50 + * Author: mrnek + */ + +static unsigned long millis = 0; + +void setup_timer() { + TCCR1B |= (1 << WGM12); // настраиваем режим CTC (Clear Timer on Compare Match) + OCR1A = 250; // задаем значение, при котором будет срабатывать прерывание (в данном случае 15999, так как Atmega328p работает на частоте 16 МГц и нужно получить прерывание раз в 1 мс) + TIMSK1 |= (1 << OCIE1A); // включаем прерывание по совпадению со значением регистра OCR1A + sei(); // разрешаем глобальные прерывания + TCCR1B |= (1 << CS11) | (1 << CS10); // запускаем таймер с предделителем 64 (16000000/64=250000) +} + +unsigned long get_millis() { + return millis; +} + +ISR(TIMER1_COMPA_vect) { + ++millis; +} \ No newline at end of file diff --git a/timer.h b/timer.h new file mode 100644 index 0000000..90696ac --- /dev/null +++ b/timer.h @@ -0,0 +1,10 @@ +/* + * timer.h + * + * Created: 13.04.2023 14:12:16 + * Author: mrnek + */ + +void setup_timer(); + +unsigned long get_millis(); \ No newline at end of file diff --git a/uart.c b/uart.c new file mode 100644 index 0000000..f095235 --- /dev/null +++ b/uart.c @@ -0,0 +1,28 @@ +/* + * uart.c + * + * Created: 13.04.2023 15:32:02 + * Author: mrnek + */ +#include +#include "uart.h" + +void USART_Init(unsigned int ubrr) { + /*Set baud rate */ + UBRR0H = (unsigned char)(ubrr>>8); + UBRR0L = (unsigned char)ubrr; + UBRR0H = 0; + UBRR0L = 8; + /* Set frame format: 8data, 2stop bit */ + UCSR0C = (1<