PicManía by RedRaven
 

Búsqueda personalizada

 

PROYECTOS : EMULACIÓN TECLADO PS/2

 

 

 

KBDEMUL : Emulación Teclado PS/2 con un 18F1320

 
Descripción
 
  •  La finalidad de este proyecto es la simétrica a la del Proyecto Teclado PS/2 de esta misma Web. En aquel leíamos un teclado PS/2 y trasmitíamos lo leído a través del canal RS232. En este vamos a leer el canal  RS232 y vamos a transmitir emulación teclado PS/2: vamos a darle gato por liebre a nuestro PC.

  • Si embargo este proyecto pretende ir un paso mas allá. También deseo ampliar su funcionalidad intentando darle un valor añadido, que no se quede en un mero experimento, y para ello lo que vamos a implementar es un circuito by-pass entre el PC y el Teclado, y que sea nuestro PIC quien intervenga en dicho circuito cuando nos parezca oportuno e inyecte su emulación PS/2 en paralelo al teclado real. Que se convierta nuestro PIC en un teclado virtual conectado al mismo tiempo que el real a nuestro PC.
  • La finalidad real va  a consistir en tener una conexión PC <-> PIC <-> Keyboard PS/2 en la que normalmente se establecerá la correspondiente comunicación PC <-> Keyboard PS/2 salvo cuando el PIC necesite escribir algo en dicho canal que lo conmutará para convertirlo en PC <-> PIC, tras lo cual volverá a dejarlo tal como estaba antes.
  • Las aplicaciones de esto son infinitas. Yo ya he usado algunas de ellas como por ejemplo conectarle al PIC un Lector de Tarjetas de Proximidad y poder inyectar los códigos leídos en el PC para rellenar las fichas correspondientes en el software de gestión utilitario que se esté usando. El resto solo dependerá de vuestra imaginación.
Elementos activos utilizados:
  • Primero: El PIC. Para este proyecto me he decidido por el mas pequeño de la serie 18F con solo 9 pines por banda, no corta el mar sino vuela .... el PIC 18F1320. (da.pdfeet PDF 5.4 Mbytes)
     

  • Una razón : porque es el mas pequeño que he encontrado con tres interrupciones externas, que para las aplicaciones Data/Clock son magnificas.


 


 

  • Segundo: El Conmutador. Para realizar la conmutación de los canales Data y Clock del PS/2 entre el PC <-> Keyboard y el PIC <-> Keyboard voy a utilizar el  CD4053 (Datasheet 115 Kbytes)
     

  • Este conmutador dispone de tres canales seleccionables mediante los pines A, B y C conmutando cada uno de ellos X, Y y Z entre ax y ay, bx y by y cx y cy (En realidad solo necesitamos dos canales, pero como tenía este de tres en existencias ...)


 


 

Conexionado eléctrico:
 
  • El teclado PS/2 se conecta mediante cuatro hilos. Dos de ellos son para alimentación Vcc a 5V y GND, y otros dos para las señales Data y Clock. El pinout de los conectores Mini-DIN PS/2 tanto hembra, los del PC, como machos, los del Teclado, es tal como se muestra en la imagen inferior:


 

  • La alimentación del circuito la vamos a tomar de este mismo conector PS/2 proporcionándonos los voltios necesarios el PC al que va conectado.
  • La idea para conectar nuestro circuito con el PC y el Keyboard es utilizar un cable de los que venden para alargar la conexión entre ambos y cortándolo insertar nuestro circuito entre ellos. El extremo que va al PC debe de ir a las entradas del CD4053 y cada una de las salidas alternativas de éste conectadas al PIC y al Keyboard, para sean éste o aquel quienes dialoguen con el PC.

 
Protocolo de comunicación PS/2:
 
  •  El teclado PS/2 se comunica mediante un Protocolo Serie Síncrono. Utiliza, por lo tanto, una señal de Clock que índica cuando están disponibles los correspondientes bits en la señal de Data.
  • En reposo la señal de Clock está a nivel alto; a cada pulso a nivel bajo corresponde un pulso a nivel alto o bajo en la señal de Data, que se traducen respectivamente como bits 0 ó 1  del dato a transmitir.

  • La trama completa se compone de 11 bits. Siendo el primero un bit de Start, a continuación los 8 bits del Dato a transmitir enviándose primero el LSB (ó bit menos significativo), el décimo es el de paridad (usa la Impar, u Odd en Inglés) y por último un bit de ACK o Stop.
  • Abajo puede verse un cronograma de esta trama de comunicación PS/2 Teclado (Keyboard) -> PC (host):


 

  • Este protocolo de comunicación es bidireccional. El teclado PS/2 admite también comandos enviados desde el PC con el mismo formato que estamos estudiando, tal como adelantamos en el primer apartado de este proyecto.

  • Para poder habilitar la comunicación inversa, del PC (host) al Teclado PS/2 (Keyboard) debemos primero indicárselo así al Teclado mediante la señal de Clock. Para ello debemos poner a nivel bajo el Clock durante unos 160 uS, y la señal de Data a bajo unos 35 uS después de haber lanzado la del Clock. A partir de ahí debemos esperar la señal del Clock generada por el Teclado. Esto nos indicará que el teclado está dispuesto para recibir nuestro comando. Detectamos dicha señal como primer pulso de Clock, y a partir del siguiente podemos comenzar a enviarle nuestro byte.
  • Le enviaremos entonces los ocho bits de nuestro comando, cada uno de ellos cuando el correspondiente pulso en bajo del Clock del teclado así nos lo indique, empezando por el LSB, a continuación el bit de paridad impar (El numero de unos en los datos mas el de paridad deber ser impar o sea 1 si el numero de unos es par y cero si el total de unos es impar)

  • Y entonces debemos esperar el ACK del teclado, que debe venir tras dos pulsos de reloj, en nivel bajo, indicándonos de este modo que el teclado ha recibido correctamente nuestro comando. en caso contrario debemos volver a repetir nuestra secuencia de envío.

  • Mas abajo se muestra un cronograma de la transmisión PC (host) -> Teclado PS/2 (Keyboard)
 
Y con esto creo que ya estamos en disposición de implementar la escritura de nuestro teclado PS/2 con el PIC.
 
Implementación
 

 

 

Fotografías
 
  • El PCB recién salido de la cubeta de atacado de ácido:


 

  • La KBDEMUL al recibir "la primera luz" como los telescopios, y recién reconocido el 18F1320 por el GTP-USB+:


 

  • Y como toda placa recién montada la KBDEMUL debe probar su buen funcionamiento leyendo y escribiendo la USART:


 

 
 
Software
 
 
 
 
emulando_teclado_ps2.c
 
 
  // Original de Nostrico del foro Todopic
// adaptado al 18f1320 por redpic
//

#include <18f1320.h>
#fuses HS,MCLR,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP,NOCPD,NODEBUG,NOWRT
#use delay(OUT_CLOCK=20000000)
#use rs232(baud=9600, xmit=PIN_B1, rcv=PIN_B4)

#define CONTROL_A PIN_A0
#define CONTROL_B PIN_A1
#define CONTROL_C PIN_A2
#define CONTROL_INH PIN_A4

#define OUT_CLOCK PIN_B3
#define OUT_DATA PIN_B5

unsigned int8 rec_char;

unsigned char convert_ascci_to_scancode(unsigned char c){

  unsigned char scancode;

       if (c == 'a' || c == 'A') {scancode = 0x1c;}
  else if (c == 'b' || c == 'B') {scancode = 0x32;}
  else if (c == 'c' || c == 'C') {scancode = 0x21;}
  else if (c == 'd' || c == 'D') {scancode = 0x23;}
  else if (c == 'e' || c == 'E') {scancode = 0x24;}
  else if (c == 'f' || c == 'F') {scancode = 0x2b;}
  else if (c == 'g' || c == 'G') {scancode = 0x34;}
  else if (c == 'h' || c == 'H') {scancode = 0x33;}
  else if (c == 'i' || c == 'I') {scancode = 0x43;}
  else if (c == 'j' || c == 'J') {scancode = 0x3b;}
  else if (c == 'k' || c == 'K') {scancode = 0x42;}
  else if (c == 'l' || c == 'L') {scancode = 0x4b;}
  else if (c == 'm' || c == 'M') {scancode = 0x3a;}
  else if (c == 'n' || c == 'N') {scancode = 0x31;}
  else if (c == 'o' || c == 'O') {scancode = 0x44;}
  else if (c == 'p' || c == 'P') {scancode = 0x4d;}
  else if (c == 'q' || c == 'Q') {scancode = 0x15;}
  else if (c == 'r' || c == 'R') {scancode = 0x2d;}
  else if (c == 's' || c == 'S') {scancode = 0x1b;}
  else if (c == 't' || c == 't') {scancode = 0x2c;}
  else if (c == 'u' || c == 'U') {scancode = 0x3c;}
  else if (c == 'v' || c == 'V') {scancode = 0x2a;}
  else if (c == 'w' || c == 'W') {scancode = 0x1d;}
  else if (c == 'x' || c == 'X') {scancode = 0x22;}
  else if (c == 'y' || c == 'Y') {scancode = 0x35;}
  else if (c == 'z' || c == 'Z') {scancode = 0x1a;}

  else if (c == '0') {scancode = 0x45;}
  else if (c == '1') {scancode = 0x16;}
  else if (c == '2') {scancode = 0x1e;}
  else if (c == '3') {scancode = 0x26;}
  else if (c == '4') {scancode = 0x25;}
  else if (c == '5') {scancode = 0x2e;}
  else if (c == '6') {scancode = 0x36;}
  else if (c == '7') {scancode = 0x3d;}
  else if (c == '8') {scancode = 0x3e;}
  else if (c == '9') {scancode = 0x46;}

  else if (c == '/') {scancode = 0x5a;} // ENTER
  else if (c == ' ') {scancode = 0x29;} // ESPACIO
  else if (c == '>') {scancode = 0x0d;} // TABULADOR
  else if (c == '<') {scancode = 0x66;} // BORRADOR
  else if (c == '$') {scancode = 0x58;} // TAG DE MAYUSCULA $m$yuscula
  else if (c == '-') {scancode = 0x4a;} // -_

  else {scancode = 0x29;} // Cualquier otra cosa ESPACIO

  return scancode;
}


void output_scancode_ps2(unsigned char scancode){

  int contador;
  int salida, unos=1;
  boolean paridad=true;

  output_high(OUT_CLOCK); // START -------------------------------
  output_high(OUT_DATA);
  delay_us(40);

  output_high(OUT_CLOCK);
  output_low(OUT_DATA);
  delay_us(40);

  output_low(OUT_CLOCK);
  output_low(OUT_DATA);
  delay_us(40);

  salida =1;

  do{
    output_high(OUT_CLOCK);
    output_bit(OUT_DATA, scancode&0x01);
    delay_us(40);
    output_low(OUT_CLOCK);
    output_bit(OUT_DATA, scancode&0x01);
    delay_us(40);

    if ((scancode & 0x01) == 0x01) {unos++;}

    scancode = scancode>>1;
    salida++;

  }while(salida < 9);

  output_high(OUT_CLOCK); // PARITY ------------------------------
  output_bit(OUT_DATA, unos&0x01);
  delay_us(40);
  output_low(OUT_CLOCK);
  output_bit(OUT_DATA, unos&0x01);
  delay_us(40);

  output_high(OUT_CLOCK); // STOP --------------------------------
  output_high(OUT_DATA);
  delay_us(40);
  output_low(OUT_CLOCK);
  output_high(OUT_DATA);
  delay_us(40);

  output_high(OUT_CLOCK); // FIN ---------------------------------
  output_high(OUT_DATA);

  delay_ms(175);
}


void main(){

  delay_ms(300);
  printf("\r\nKBDEMUL with a 18F1320\r\nInject signal for PS/2\r\n\n");
  delay_ms(500);

  output_high(CONTROL_A); // Conmuta CD4053 a salida PIC->PC
  output_high(CONTROL_B);
  output_high(CONTROL_C);

  do{
    rec_char=getch();
    putc(rec_char;);
    output_scancode_ps2(convert_ascci_to_scancode(valor));
  }while(true);

}
   
 
 

 

 
Conclusión:
 
  • La primera prueba ha consistido en montar la KBDEMUL recibiendo códigos ASCII desde la RS-232 y convirtiéndolos a PS/2, y después enviándoselos a la RRBOARD2 programada con el software del Proyecto Teclado PS/2, que a su vez lee PS/2 y convierte a la inversa en ASCII y lo transmite a otro canal serie

    O sea: PC Serie COM3 -> PS/2 en KBDEMUL -> PS/2 en RRBOARD2 -> PC Serie COM1

     

Y por último la conexión real entre el PC, la KBDEMUL y el Keyboard PS/2:
 

 Recursos:
En Español  Ratón PS/2 controlado por un dsPIC por Nocturno.
En Español  .pdf Teclado AT-PS2 Interfaz y funciones v1.2 (PDF)
En Inglés  TECHNICAL SPECIFICATION FOR G83-6000 (PDF)
En Inglés  AT Keyboard Interface V1.04
En Inglés  The PS/2 Keyboard Interface
En Inglés  DIY hardware keylogger
En Inglés  As to connect pic to the connector mini din (ps/2) in CCS C Forum

 

 

Esta página se modificó el 27/12/2008


Esta página usa la letra Ñ

Nota pública importante sobre las consultas al Webmaster de PicManía.


Sugerencias a Picmanía... (que serán leídas pero seguramente no podrán ser contestadas)

Esta página pertenece al grupo de páginas de Diego RedRaven

 

 



Nota: Esta página Web esta repleta de imágenes, textos, logotipos y demás material extraídos de los mas variados medios de los que no soy ni autor ni depositario de los correspondientes derechos de autor, uso y/o reproducción. Si Ud. es depositario de dichos derechos y desea que el material correspondiente sea eliminado de esta Web no dude en ponerse en contacto conmigo mediante e-mail y será inmediatamente retirado. Gracias.
 
Visitas
Totales : 21540 Hoy: 1 Activas: 1 Vistas: 21540

Esta página fue modificada el 07-08-2010 15:42:20

           
 DmSoft WAMP Escribir Unreal