sábado, 25 de fevereiro de 2012

Pseudo Código para leitura de teclado

Apesar de existirem algumas bibliotecas para leitura de teclado PS/2 disponíveis, nenhuma que achei me serviu basicamente se utilizam de interrupções para ler o teclado e pela conversão de códigos para valores ASCII usando tabelas de estados com e sem shift, etc. Outras razões são o não processamento da teclas PAUSE/BREAK que pretendo utilizar STOP, e o excesso de 'orientação ao sucesso', por desconsiderar timeouts, bits errados, caracteres inesperados, etc.


Eis o primeiro passo, o pseudo codigo para leitura de scan codes, que apesar de ser por polling, pode ser facilmente adaptado para rodar por interrupçoes.


// pseudo codigo para comunicação // com teclado ps/2
enum estados {STARTBIT, DATABITS, PARITYBIT, STOPBIT}; unsigned char estado, contador, paridade, dado, novodado, bit; // Waitclock boolean waitclock(void); // retorna falso se timeout // retorna true se detecdada borda de descida unsigned char getbit(void); // retorna 1 se o bit amostrado está no estado ativo // retorna 0 se o bit amostrado está no estado inativo // rotina de recepção novodado=0; estado=STARTBIT; do { if (!waitclock()) { // sempre que houver timeout estado=STARTBIT; // volta a esperar o startbit } else { bit=getbit(); switch (estado) { case STARTBIT: if (bit==0) { // Se o start bit for o valor correto contador=8; // contador de bits paridade=0; // contador para verificar paridade estado=DATABITS; } break; case DATABITS: dado <<=1; // insere bit amostrado dado |= bit; paridade +=bit; // incrementa contador de paridade contador--; // decrementa contador de bits if (contador==1) { // se recebeu ultimo bit de dados estado=PARITYBIT // vai aguardar bit de paridade } break; case PARITYBIT: paridade +=bit; // soma o bit de paridade. if (paridade & 1) { // se a paridade está correta o resultado é impar estado=STOPBIT } else { // se a paridade não for correta estado=STOPBIT; // vai aguardar novamente o bit de início } break; case STOPBIT: if (bit==1) { // se o stop bit for o valor correto novodado=1; // sinaliza novo dado recebido } break; } // switch } // else } while (!novodado); processa (dado);

Nenhum comentário: