Ingresar información a un PC por el PS/2.
Usando un pic se puede ingresar información por el PS/2 de un PC. El timming
de dicho protocolo es:

Podríamos decir que según la norma del dicho protocolo PS/2, cada ancho de
pulso mide ente 30 a 50 useg. Teniendo esta información se puede realizar un
primer proyecto que consiste en transmitir la letra "a" con un enter
respectivo... Veamos ya las posibilidades de dicho proyecto, esta información
puede ser observada en todas las herramientas de Offices... sin tomar en cuenta
que se a Linux o Windows. Las características del conector es:


Teniendo esta información podemos conseguir un teclado usado,
cortar el conector PS/2 y realizar la transmisión a la PC... Uno de los punto
que quiero tocar es que la comunicación no depende del número de equipos
conectados ya que es casi igual a la comunicación I2C por lo que se necesita dos
resistencia Pull up de 10K a Vcc (5 Volt) y el equipo se encargará de llevar a
corto (0 Volt) dicha línea de DATA... La PC estará "escuchando" cada equipo que
se comunique de dicha forma... ¿Ahora bien? ¿Qué ocurre si muchos hablan a la
vez?... Afortunadamente el protocolo depende de un bit de paridad que va después
de los 8 bits de datos y antes de BIT de STOP; si muchos equipos hablan a la
vez... este BIT no coincidirá con la DATA recibida en el PC... No siendo
capturado dicho dato por la PC... Claro pero no hay que confiarse, por que
algunos casos (cosa que no pasa mucho) pudiese coincidir el dato con la
parida... y recibir la información el PC, generando un carácter erróneo...
Vemos en la siguiente figura la manera de como conectar el cableado al PC con
algún microprocesador, en este caso PIC16F84.
¿Qué es la paridad de un byte?
Es fácil de calcular, tome 8 BIT de 1 byte, cuente el número
de unos que existe en dicho byte si resulta que es IMPAR entonces el BIT de
paridad es cero, de manera contraria si es número de unos es PAR el BIT de
paridad es 1. Veamos el siguiente ejemplito: (A1)hex es: 1010 0001, por lo que
el número de unos es de 3 y tres es IMPAR entonces se le asigna a este byte el
bit 0 de paridad.
¿Que datos vamos a transmitir?
Lamentablemente (No se por qué) los códigos de cada tecla no
coinciden con los valores ASCCI por lo que poseen el siguiente código:


Con esto de los codigos de rastreo se produce una cosa
curiosa:
Si por ejemplo queremos que nos transmita la letra "G", en mayúsculas, la
secuencia debe ser: Presionar la tecla "Shift", presionar la tecla "G", soltar
la tecla "G" y soltar la tecla "Shift". Los Scan Codes entonces serán los
correspondientes a las pulsaciones y "sueltas" de estas dos teclas : Pulsar
Shift -> 12h, Pulsar "G" -> 34h, Soltar "G" -> F0h 34h y soltar Shift -> F0h 12h
por lo que la secuencia completa nos llegará como: 12h, 34h, F0h, 34h, F0h, 12h.
( Casi ná )
El proyecto...
Puerto usándose del PIC16f84, RB0 como CLOCK y RB1 como
DATA.
Programa en CCS...
#include <16f877a.h> // Definiciones del PIC 16F876A
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT // Los Fuses de siempre
#use delay(clock=4000000) // Oscilador a 4 Mhz
#define clock PIN_B0
#define data PIN_B1
void main()
{
delay_ms(500);
do{
output_high(clock);
output_high(data);
delay_us(40);
output_high(clock);
output_low(data);
delay_us(40);
output_low(clock);
output_low(data);
delay_us(40);
output_high(clock); ////// 0
output_low(data);
delay_us(40);
output_low(clock);
output_low(data);
delay_us(40);
output_high(clock); ////// 1
output_low(data);
delay_us(40);
output_low(clock);
output_low(data);
delay_us(40);
output_high(clock); ////// 2
output_high(data);
delay_us(40);
output_low(clock);
output_high(data);
delay_us(40);
output_high(clock); ////// 3
output_high(data);
delay_us(40);
output_low(clock);
output_high(data);
delay_us(40);
output_high(clock); ////// 4
output_high(data);
delay_us(40);
output_low(clock);
output_high(data);
delay_us(40);
output_high(clock); ////// 5
output_low(data);
delay_us(40);
output_low(clock);
output_low(data);
delay_us(40);
output_high(clock); ////// 6
output_low(data);
delay_us(40);
output_low(clock);
output_low(data);
delay_us(40);
output_high(clock); ////// 7
output_low(data);
delay_us(40);
output_low(clock);
output_low(data);
delay_us(40);
output_high(clock); ////// P
output_low(data);
delay_us(40);
output_low(clock);
output_low(data);
delay_us(40);
output_high(clock); ////// STOP
output_high(data);
delay_us(40);
output_low(clock);
output_high(data);
delay_us(40);
output_high(clock); ////// FIN
output_high(data);
delay_ms(1000);
}while(true);
}