#include "aduc812.h" #include "driver_keyboard.h" #include "interrupt.h" #include "driver_io.h" #include "max.h" #include "driver_lcd.h" #include #include #include #include #define DELAY_BEFORE_SYMBOL_REPEAT 4000 #define SYMBOL_REPEAT 1000 COLUMNS columns = { 0, { 0x07, 0x0B, 0x0D, 0x0E } }; BUFFER chars_buffer = { 0, 0 }; POSITION position = { 1, 1 }; // позиция курсора на экране void init(unsigned char speed) { TH1 = 0xFD; //Скорость 9600 TH0 = 0x00; TMOD = 0x22; //Таймер 1 и 0 в режиме autoreload TCON = 0x50; //Запуск таймеров 0 и 1 SCON = 0x50; //8 bit UART, разрешение приема PCON &= 0x7F; //Отключение дублирования скорости, установленной в TH1 set_vector(0x200B, (void *) handler_timer0); set_vector(0x2023, (void *) handler_uart); write_string("Init()\n"); EA = 1; ET0 = 1; } void handler_timer0( void ) __interrupt ( 1 ) { scan_keyboard(columns.array[columns.pointer]); if (columns.pointer == COLUMNS_COUNT) { columns.pointer = 0; } } void scan_keyboard(int column_num) { static int error = 0; static int key_still_pressed_counter = 0; static int key_pressed_counter = 0; static int state = FSM_KEY_RELEASED; char next_char = ' '; char old_char = ' '; unsigned char scan_result = 0; write_max(0, column_num); scan_result = read_max(0); switch (scan_result) { // 1-я колонка case BTN_1: next_char = '1'; break; case BTN_4: next_char = '4'; break; case BTN_7: next_char = '7'; break; case BTN_ASTERISK: next_char = 'b'; break; // 2-я колонка case BTN_2: next_char = '2'; break; case BTN_5: next_char = '5'; break; case BTN_8: next_char = '8'; break; case BTN_0: next_char = '0'; break; // 3-я колонка case BTN_3: next_char = '3'; break; case BTN_6: next_char = '6'; break; case BTN_9: next_char = '9'; break; case BTN_HASH: next_char = '='; break; // 4-я колонка case BTN_A: next_char = '+'; break; case BTN_B: next_char = '-'; break; case BTN_C: next_char = '*'; break; case BTN_D: next_char = '/'; break; // клавиша не нажата или нажато несколько клавиш default: if ((scan_result >>= 4) != 0x0F) { write_max(7, 0xFF); error = 1; return; } if (key_pressed_counter > 0) { key_pressed_counter--; if (key_pressed_counter < KEY_RELEASED_COUNT && state == FSM_KEY_PRESSED) { state = FSM_KEY_RELEASED; } } columns.pointer++; return; } // переповтор if (state == FSM_KEY_PRESSED && key_still_pressed_counter == 0) { write_buffer(&next_char); key_still_pressed_counter = SYMBOL_REPEAT; return; } if (key_pressed_counter != KEY_PRESSED_COUNT) { key_pressed_counter++; } if (key_pressed_counter >= KEY_PRESSED_COUNT && state == FSM_KEY_RELEASED) { state = FSM_KEY_PRESSED; if (error == 0) { write_buffer(&next_char); } else { error = 0; } key_still_pressed_counter = DELAY_BEFORE_SYMBOL_REPEAT; } // уменьшаем счетчик повторов if (key_still_pressed_counter > 0) { key_still_pressed_counter--; } } /********************** функции обработки *****************************/ char * out; char a = 'a'; void run_calculator(BUFFER * in_chars, Expression * exp) { char next_char; static unsigned char is_set_first_operand = 0; static unsigned char is_set_operation = 0; static int timer = 1000000; static int timer1 = 1000000; static int x = 0; clear_lcd(); print_char_lcd(a); a++; for (timer = 4294967290; timer > 0; timer--); for (timer1 = 100000; timer1 > 0; timer1--); /* while (1) { clear_lcd(); while (timer-- > 0); timer = 10000; print_char_lcd('8'); goto_xy_lcd(x++, 0); }*/ /* if (read_buffer(&next_char)) { /* // допустимые символы? if ((next_char >= '0' && next_char <= '9') || (next_char == '+' || next_char == '-' || next_char == '*' || next_char == '/' || next_char == '=' || next_char == 'b')) { // обработка цифр, вывод в буфер и на экран if (next_char >= '0' && next_char <= '9') { in_chars->buffer[in_chars->w_pointer++] = next_char; goto_xy_lcd(position.x++, position.y); print_char_lcd(in_chars->buffer[in_chars->w_pointer - 1]); return; } // обработка сброса if (next_char == 'b') { clean(in_chars); // очистка промежуточного буфера clear_lcd(); // очистка дисплея is_set_first_operand = 0; // сброс флага is_set_operation = 0; position.x = position.y = 1; goto_xy_lcd(position.x, position.y); print_char_lcd('0'); return; } // обработка операций и начала вычисления if (next_char == '=') { set_operand(&exp->s_operand, in_chars->buffer); // установка второго операнда memset(in_chars->buffer, '\0', BUF_SIZE); switch (exp->operation) { case '+' : exp->result = exp->f_operand + exp->s_operand; break; case '-' : exp->result = exp->f_operand - exp->s_operand; break; case '*' : exp->result = exp->f_operand * exp->s_operand; break; case '/' : exp->result = exp->f_operand / exp->s_operand; break; default : break; } is_set_first_operand = 0; // сброс флага is_set_operation = 0; _itoa(exp->result, in_chars->buffer, 10); goto_xy_lcd(position.x++, position.y); print_char_lcd(next_char); goto_xy_lcd(position.x++, position.y); print_string_lcd(in_chars->buffer); // вывод результата на экран write_char('='); write_string(in_chars->buffer); write_char('\n'); clean(in_chars); return; } if (!is_set_operation) { exp->operation = next_char; // запоминаем операцию set_operand(&exp->f_operand, in_chars->buffer); // переводим первый операнд clean(in_chars); // чистим буфер is_set_first_operand = 1; // первый операнд установлен goto_xy_lcd(position.x++, position.y); // вывод на дисплей print_char_lcd(next_char); is_set_operation = 1; } else { clear_lcd(); print_string_lcd("Error"); } // //------------------// } else { is_set_operation = 0; write_string("\nError: enter digits, '+' or '=' symbols\n"); clean(in_chars); } } */ } void set_operand(int * operand, char * buf) { *operand = atoi(buf); _itoa(*operand, buf, 10); memset(buf, '\0', BUF_SIZE); } void run_echo() { char next_char; if (read_buffer(&next_char)) { if (next_char == 8) { write_char(next_char); write_char(32); write_char(next_char); } else { write_char(next_char); goto_xy_lcd(position.x++, position.y); print_char_lcd(next_char); } } } /***********************************************************************/ /********************** функции чтения / записи в буфер *****************************/ int read_buffer(char * next_char) { // читаем операнды из очереди if (chars_buffer.w_pointer == 0) { return 0; } (*next_char) = chars_buffer.buffer[chars_buffer.w_pointer - 1]; chars_buffer.w_pointer--; make_sound(); return 1; } void make_sound() { unsigned int sound = 0; int i; for (i = 0; i < 100; i++) { if (sound == 0x00) { sound = 0x10; } else { sound = 0x00; } write_max(4, sound); } } void write_buffer(char * next_char) { chars_buffer.buffer[chars_buffer.w_pointer++] = (*next_char); } /*************************************************************************************/ void set_vector(unsigned char xdata * Address, void * Vector) { *Address = 0x02; *(Address + 1) = (unsigned char) ((unsigned short) Vector >> 8); *(Address + 2) = (unsigned char) ((unsigned char) Vector); }