Follow along with the video below to see how to install our site as a web app on your home screen.
Nota: This feature currently requires accessing the site using the built-in Safari browser.
;********************************************************************
; "tecpc"
;Son un conjunto de subrutinas para comunicación con un teclado PC.
;Es necesaria la conexión del teclado y el entrenador a través de
;una placa de adaptación.
;Las señales a manejar son las siguientes:
; CONECTOR TECLADO CONECTOR MICRO
; Reloj <---------INVERSOR------------- RC1 (RELSAL)
; -----------------------------> RC2 (RELEN)
; Datos <------------------------------ RC7 (DATSAL)
; -----------------------------> RC0 (DATEN)
;Subrutinas disponibles para el teclado PC.
;rtecpc: Recibe un dato de teclado que se guarda en Rdato.
;captec: Capta en serie el dato del teclado y actualiza el error.
;rsend: Envía el código de reeenvío al teclado.
;manda: Envía al teclado el byte contenido en Rdato.
;obtpar: Obtiene el bit de paridad del dato entrante en serie.
;cheqpar: Comprueba que la paridad de Rdato (parobt) y la del bit entrante coinciden en impar.
;mandack: Envía al teclado el byte de Rdato y espera hasta recibir un código ACK de reconocimiento.
;cheqbat: comprueba que el chequeo del teclado ha sido correcto y programa el bit de error
;en consecuencia.
;veltec: Programa la velocidad de escrutación de teclas y el retardo
;entre pulsaciones. El byte de programación debe estar contenido en Rdato.
;progled: Activación o desactivación de los leds del teclado.
;modtec: Programación del modo en que el teclado envía una tecla.
;El MSB del registro Rest es el bit de paridad leído en el
;dato recibido en serie.
;
; Registro Rest
;
; Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
; parent - - biterr - - - parobt
;********************************************************************
CBLOCK 0x4A
Rdato, T1rtec, T2rtec, Tinter
Cgentec, Rest, TRdato, Mtrisc
Rtecla, Ccheqbat
ENDC
;Rdato:
#define RELSAL PORTC,1
#define DATSAL PORTC,7
#define DATEN PORTC,0
#define RELEN PORTC,2
#define biterr Rest,4
#define parobt Rest,0
#define parent Rest,7
;********************************************************************
; "rtecpc"
;Esta subrutina recibe un byte desde el teclado del PC, que estará
;disponible en el registro Rdato. Si en la recepción ocurriese algún
;error el registro Rest tendrá a 1 su quinto bit (biterr).
;********************************************************************
rtecpc: bsf STATUS,RP0 ;Selección de banco 1.
movf TRISC,W ;Guarda las direcciones de las líneas
bcf STATUS,RP0 ;del puerto C en el registro Mtrisc,
movwf Mtrisc ;del banco 0.
andlw b'01111101' ;Programa RC7 y RC1 como salidas, RC2
iorlw b'00000101' ;y RC0 como entradas. El resto no varía.
bsf STATUS,RP0 ;Selección de banco 1.
movwf TRISC ;Programación del registro TRISC.
bcf STATUS,RP0 ;Selección del banco 0.
bcf RELSAL ;Libera el reloj para el teclado.
movlw 0x40 ;Carga valores para intentos de lectura.
movwf T1rtec ; "
rtecpc1: movlw 0xFF ; "
movwf T2rtec ; "
rtecpc2: btfsc RELEN ;¿Reloj de entrada=0?
goto rtecpc3 ;No: sigue intentando leer 0.
btfsc DATEN ;Sí: ¿Teclado envía bit de START?
goto rtecpc3 ;No: sigue intentando bit de START.
call captec ;Sí: captura byte.
goto rtecpc4
rtecpc3: decfsz T2rtec,F ;Bucle de retardo.
goto rtecpc2 ; "
decfsz T1rtec,F ; "
goto rtecpc1 ; "
bsf biterr ;Activa bit de error.
rtecpc4: bsf RELSAL ;Cancela reloj al teclado.
movf Mtrisc,W ;Recupera direcciones de PORTC.
bsf STATUS,RP0 ; "
movwf TRISC ; "
bcf STATUS,RP0 ; "
return
;********************************************************************
; "captec"
;Subrutina encargada de leer bit a bit los nueve que envía el teclado,
;incluída la paridad. Si existe algún error en la comunicación o en
;paridad, la subrutina activa el bit de error. El dato estará presente
;en el registro Rdato.
;********************************************************************
captec: bcf biterr ;Borra marca de error.
bcf RELSAL ;Pone a "1" el reloj al teclado PC.
rel0_1: btfsc RELEN ;Espera a que el teclado ponga a 0
goto rel0_1 ;su señal de reloj.
btfsc DATEN ;Espera a recibir el bit de START
goto rel0_1 ; "
movf INTCON,W ;Salva registro de interrupciones.
movwf Tinter ; "
bcf INTCON,GIE ;Inhibe interrupciones.
movlw 8 ;Carga el número de bits a recibir,
movwf Cgentec ;sin contar el de paridad.
rel0_2: btfss RELEN ;Espera a que pase el nivel 0 del
goto rel0_2 ;reloj emitido por el teclado.
rel1_1: btfsc RELEN ;Espera a que pase el nivel 1 del
goto rel1_1 ;reloj emitido por el teclado.
btfss DATEN ;Capta bit entrante y lo va cargando
goto captec2 ;en Rdato mediante rotaciones.
bsf STATUS,C ;Carga 1 en Rdato.
captec1: rrf Rdato,F ; "
decfsz Cgentec,F ;Decrementa contador de bits.
goto rel0_2 ;Si no se ha terminado salta a rel0_2.
goto rel0_3 ;Si ha finalizado sigue en rel0_3.
captec2: bcf STATUS,C ;Carga 0 en Rdato.
goto captec1
rel0_3: btfss RELEN ;Espera a que pase el nivel 0 del
goto rel0_3 ;reloj emitido por el teclado.
rel1_3: btfsc RELEN ;Espera a que pase el nivel 1 del
goto rel1_3 ;reloj emitido por el teclado.
btfsc DATEN ;Capta bit entrante de paridad.
goto captec3
bcf parent ;Programa bit de paridad entrante.
goto captec4
captec3: bsf parent ;Programa bit de paridad entrante.
captec4: call obtpar ;Se obtiene la paridad del byte de
;Rdato y se compara con la recibida.
call cheqpar ;Programa bit de error.
rel0_4: btfss RELEN ;Espera a que pase el nivel 0 del
goto rel0_4 ;reloj emitido por el teclado.
rel1_4: btfsc RELEN ;Espera a que pase el nivel 1 del
goto rel1_4 ;reloj emitido por el teclado.
btfss DATEN ;¿Bit de STOP=1?
bsf biterr ;No: error.
rel0_5: btfss RELEN ;Espera a que pase el nivel 0 del
goto rel0_5 ;reloj emitido por el teclado.
movf Tinter,W ;Recupera estado de interrupciones.
movwf INTCON ; "
bsf RELSAL ;Anula reloj al teclado PC.
btfss biterr ;¿Existe condición de error?
return ;No: retorno.
call rsend ;Sí: rutina de reenvío de byte.
btfss biterr ;¿Existe condición de error?
goto captec ;No: repite captación de byte.
return ;Sí: retorna con marca de error.
;********************************************************************
; "rsend"
;Esta subrutina envía al teclado el código que aquél interpreta como
;petición de reenvío del último byte. El código concreto es "FEh".
;********************************************************************
rsend: movlw 0xFE ;Escribe código de reenvío.
call manda ;Envía al teclado un byte.
return
;********************************************************************
; "manda"
;Subrutina que envía al teclado el byte contenido en el registro Rdato.
;Se activa el bit de error si éste se produjese. No altera Rdato.
;********************************************************************
manda: bsf STATUS,RP0 ;Selección de banco 1.
movf TRISC,W ;Guarda las direcciones de las líneas
bcf STATUS,RP0 ;del puerto C en el registro Mtrisc,
movwf Mtrisc ;del banco 0.
andlw b'01111101' ;Programa RC1 y RC7 como salidas, RC0
iorlw b'00000101' ;y RC2 como entradas. El resto no varía.
bsf STATUS,RP0 ;Selección de banco 1.
movwf TRISC ;Programación del registro TRISC.
bcf STATUS,RP0 ;Selección del banco 0.
bcf DATSAL ;Pone bit de START.
bcf RELSAL ;Libera señal de reloj.
movlw 0xFF ;Carga valores para intentos de
movwf T1rtec ;comunicación.
mrecar: movlw 0xFF ; "
movwf T2rtec ; "
mrel0_1: btfss RELEN ;¿Reloj de teclado igual a 1?
goto conrut ;No: continúa rutina.
decfsz T2rtec,F ;Sí: Bucle de espera hasta ver el
goto mrel0_1 ;nivel bajo del reloj procedente del
decfsz T1rtec,F ;teclado PC.
goto mrecar ;salta a recargar registro.
bsf biterr ;Se activa la señal de error.
salida: bsf RELSAL ;Bloquea la línea de reloj.
movf Mtrisc,W ;Recupera direcciones de PORTC.
bsf STATUS,RP0 ; "
movwf TRISC ; "
bcf STATUS,RP0 ; "
return
conrut: movf INTCON,W ;Salva registro de interrupciones.
movwf Tinter ; "
bcf INTCON,GIE ;Inhibe interrupciones.
movlw 8 ;Carga el número de bits a enviar,
movwf Cgentec ;sin contar el de paridad.
manda1: rrf Rdato,F ;Rotamos dato a enviar para poner
btfsc STATUS,C ;en C el bit a enviar.
goto manda2
bcf DATSAL ;Envía un 0 al teclado.
goto mrel0_2
manda2: bsf DATSAL ;Envía un 1 al teclado.
mrel0_2: btfss RELEN ;Espera a que pase el nivel 0 del
goto mrel0_2 ;reloj.
mrel1_1: btfsc RELEN ;Espera a que pase el nivel 1 del
goto mrel1_1 ;reloj.
decfsz Cgentec,F ;Decrementa contador de bits.
goto manda1 ;Repite envío de bit.
rrf Rdato,F ;Rota dato para dejarlo como estaba
call obtpar ;Obtiene la paridad del byte.
btfss parobt ;¿Paridad impar?
goto manda3 ;No: sigue en manda3.
bcf DATSAL ;Sí: saca 0 para paridad impar.
goto mrel0_3
manda3: bsf DATSAL ;Manda 1 para paridad impar.
mrel0_3: btfss RELEN ;Espera a que pase el nivel 0 del
goto mrel0_3 ;reloj.
mrel1_2: btfsc RELEN ;Espera a que pase el nivel 1 del
goto mrel1_2 ;reloj.
bsf DATSAL ;Deja a nivel alto la línea de datos
;para quedar en ESPERA.
mrel0_4: btfss RELEN ;Espera a que pase el nivel 0 del
goto mrel0_4 ;reloj.
mrel1_3: btfsc RELEN ;Espera a que pase el nivel 1 del
goto mrel1_3 ;reloj.
btfss DATEN ;Chequea el dato de entrada.
goto manda4 ;Error si datos está a 0.
bsf biterr ;Borra ERROR si datos está a 1.
mrel0_5: btfss RELEN ;Espera a que pase el nivel 0 del
goto mrel0_5 ;reloj.
mdat1: btfss DATEN ;Espera a encontrar el nivel 1 en
goto mdat1 ;línea de datos.
bsf RELSAL ;Bloquea reloj.
movf Tinter,W ;Recupera estado de interrupciones.
movwf INTCON ; "
goto salida
manda4: bcf biterr ;Si DATEN=1 programa ERROR.
goto mrel0_5
;********************************************************************
; "cheqpar"
;Subrutina para chequear paridad y programar en consecuencia el bit
;de error.
;********************************************************************
cheqpar: btfss parobt ;¿Paridad obtenida es impar?
goto cheqpar2 ;No: continúa en proger1.
btfsc parent ;Sí: ¿bit de paridad entrante es 0?
goto cheqpar3 ;No: va a programar error.
cheqpar1:bcf biterr ;Sí: borra bit de error y retorna.
return
cheqpar2:btfsc parent ;¿Paridad entrante es par?
goto cheqpar1 ;No: va a borrar el error.
cheqpar3:bsf biterr ;Programa bit de error.
return
;********************************************************************
; "mandack"
;Subrutina que envía al teclado el byte contenido en el registro
;Rdato y espera recibir un ACK (0xFA). Altera el registro Rdato.
;Se activa el bit de error si éste se produjese.
;********************************************************************
mandack: call manda ;Envía el dato al teclado.
btfsc biterr ;¿Existe error?
return ;Sí: retorna con el error.
call rtecpc ;Subrutina para recibir un byte.
btfsc biterr ;¿Existe error?
return ;Sí: retorna con el error.
movf Rdato,W ;¿Dato recibibido es ACK?
xorlw 0xFA ; "
btfsc STATUS,Z ; "
return ;Sí: retorno.
movf Rdato,W ;No: ¿es un RESEND?
xorlw 0xFE ; "
btfsc STATUS,Z ; "
goto mandack ;Sí: repite el envío.
bsf biterr ;No: activa error.
return
;********************************************************************
; "cheqbat"
;Subrutina que mira si el chequeo del teclado ha sido correcto. Si no
;lo fuese se activaría el bit de error.
;********************************************************************
cheqbat: movlw 0xFF ;Carga número de intentos.
movwf Ccheqbat ; "
cheqbat1:call rtecpc ;Recibe byte desde el teclado.
btfss biterr ;¿Hay error?
goto cheqbat3 ;No: sigue en cheqbat3.
decfsz Ccheqbat,F ;Sí: decrementa contador.
goto cheqbat1 ;Salto a repetir consulta.
cheqbat2:bsf biterr ;Si hay error después de los intentos
return ;se retorna con el error.
cheqbat3:movf Rdato,W ;¿Byte es AAh?
xorlw 0xAA ; "
btfss STATUS,Z ; "
goto cheqbat2 ;No: activa error.
return
;********************************************************************
; "veltec"
;Subrutina que programa la velocidad de escrutación de las teclas y el
;retardo entre pulsaciones. El byte de programación debe estar en el
;registro Rdato.
;********************************************************************
veltec: movf Rdato,W ;Salva Rdato en registro temporal.
movwf TRdato ; "
movlw 0xF3 ;Envía el código previo a la programa-
movwf Rdato ;ción de velocidad y retardo.
call mandack ; "
movf TRdato,W ;Recupera byte de programación de
movwf Rdato ;velocidad y retardo.
btfss biterr ;¿Ha habido error en el envío anterior?
call mandack ;No: envía el byte de programación.
return ;Retorna.
;********************************************************************
; "progled"
;Subrutina que activa o desactiva los leds del teclado de acuerdo al
;1 o 0, respectivamente, que programemos en los bits de Rdato, de la
;siguiente, manera:
;Rdato0: Scroll Lock
;Rdato1: Num Lock
;Rdato2: Caps Lock
;Rdato3 - Rdato7 = 0
;biterr: 1 si hay error.
;********************************************************************
progled: movf Rdato,W ;Salva Rdato en TRdato.
movwf TRdato ; "
movlw 0xED ;Envía código para activación o desac-
movwf Rdato ;tivación de leds.
call mandack ; "
movf TRdato,W ;Recupera valor de Rdato.
movwf Rdato ; "
btfss biterr ;¿Hay error en envío?
call mandack ;No: manda código de leds.
return ;Retorna.
;********************************************************************
; "modtec"
;Subrutina que programa el modo en que el teclado va a enviar una
;tecla.
;Rdato = 0xFB -> Typematic
;Rdato = 0xFC -> Make/Break
;Rdato = 0xFD -> Make
;Rtecla = Código de tecla.
;biterr: 1 si hay error.
;********************************************************************
modtec: movf Rdato,W ;Salva Rdato en TRdato.
movwf TRdato ; "
call mandack ;Envía el código de modo.
btfss biterr ;¿Error en el envío?
goto modtec2 ;No: sigue en modtec2.
modtec1: movf TRdato,W ;Sí: recupera valor de Rdato.
movwf Rdato ; "
return
modtec2: movf Rtecla,W ;Envía el código de la tecla
call mandack ;correspondiente a ese modo.
goto modtec1
;********************************************************************
; "teciden"
;Subrutina que lee la identificación del teclado. Si no fuese correcta
;se activaría el bit de error.
;********************************************************************
teciden: movlw 0xF2 ;Envía el código de identificación.
movwf Rdato ; "
call mandack ; "
btfsc biterr ;¿Existe error?
return ;Sí: retorna con el error.
call rtecpc ;No: recibe byte desde teclado.
btfsc biterr ;¿Existe error?
return ;Sí: retorna con el error.
movf Rdato,W ;No: ¿dato es igual a 0xAB?
xorlw 0xAB ; "
btfsc STATUS,Z ; "
goto teciden1 ;Sí: sigue en teciden1.
bsf biterr ;No: activa error.
return ;Retorna.
teciden1:call rtecpc ;Recibe byte de identificación.
btfsc biterr ;¿Error en la recepción?
return ;Sí: retorno con error.
movf Rdato,W ;No: ¿byte es igual a 83h?
xorlw 0x83 ; "
btfss STATUS,Z ; "
bsf biterr ;No: activa error y retorna.
return
;********************************************************************
; "acttec"
;Subrutina para activar el teclado. Si se produce error se activa el
;bit de error.
;********************************************************************
acttec: movf Rdato,W ;Salva Rdato en TRdato.
movwf TRdato ; "
movlw 0xF4 ;Envía código para activación del
movwf Rdato ;teclado.
call mandack ; "
movf TRdato,W ;Recupera valor de Rdato.
movwf Rdato ; "
return ;Retorna.
;********************************************************************
; "destec"
;Subrutina para desactivar el teclado. Si se produce error se activa
;el bit de error.
;********************************************************************
destec: movf Rdato,W ;Salva Rdato en TRdato.
movwf TRdato ; "
movlw 0xF5 ;Envía código para desactivación del
movwf Rdato ;teclado.
call mandack ; "
movf TRdato,W ;Recupera valor de Rdato.
movwf Rdato ; "
return ;Retorna.
;********************************************************************
; "echotec"
;Subrutina que manda un ECHO al teclado y espera la recepción del ECO
;de éste. Si se produce error se activa biterr.
;********************************************************************
echotec: movf Rdato,W ;Salva Rdato en TRdato.
movwf TRdato ; "
movlw 0xEE ;Envía código de ECHO.
movwf Rdato ; "
call manda ; "
btfss biterr ;¿Hay error?
goto echotec2 ;No: sigue en echotec2.
echotec1:movf TRdato,W ;Sí: recupera valor de Rdato.
movwf Rdato ; "
return ;Retorna.
echotec2:call rtecpc ;Recibe del teclado el byte de ECO.
btfsc biterr ;¿Hay error?
goto echotec1 ;Sí: recupera Rdato y retorna.
movf Rdato,W ;No: compara byte recibido con el
xorlw 0xEE ;valor del byte de ECO.
btfss STATUS,Z ;¿Es byte de ECO?
bsf biterr ;No: activa error.
goto echotec1 ;Sí: recupera Rdato y retorna.
;********************************************************************
; "initec"
;Subrutina que inicializa al teclado en las condiciones por defecto.
;Si se produce error se activa biterr.
;********************************************************************
initec: movf Rdato,W ;Salva Rdato en TRdato.
movwf TRdato ; "
movlw 0xF6 ;Envía código de ECHO.
movwf Rdato ; "
call mandack ; "
movf TRdato,W ;Recupera valor de Rdato.
movwf Rdato ; "
return
;********************************************************************
; "modcod"
;Subrutina que determina el modo en que va a enviar el teclado el
;código de exploración.
;Rdato = 01 Modo 1
;Rdato = 02 Modo 2
;Rdato = 03 Modo 3
;Rdato = 00 Detecta el modo actual, que queda depositado en Rdato.
;biterr = 1 si hay error.
;********************************************************************
modcod: movf Rdato,W ;Salva Rdato en TRdato.
movwf TRdato ; "
movlw 0xF0 ;Envía código de ECHO.
movwf Rdato ; "
call mandack ; "
movf TRdato,W ;Recupera valor de Rdato.
movwf Rdato ; "
btfsc biterr ;¿Existe error?
return ;Sí: retorna.
call mandack ;No: envía el contenido de Rdato.
btfsc biterr ;¿Existe error?
return ;Sí: retorna.
movf TRdato,W ;¿El contenido de Rdato inicial es
xorlw 00 ;igual a 00h?
btfss STATUS,Z ; "
return ;No: retorna.
call rtecpc ;Sí: recibe el byte de teclado que
return ;informaciónrmará del Modo actual.
;********************************************************************
; "restec"
;Subrutina que envía al teclado el código de RESET.
;Si se produce error se activa biterr.
;********************************************************************
restec: movlw 0xFF ;Envía código de RESET.
movwf Rdato ; "
call mandack ; "
btfss biterr ;¿Hay error?
call cheqbat ;No: chequea la correcta inicialización.
return ;Sí: retorna.
oye, (el nombre) tienes completo el programa? pues le falta la rutina "obtpar"Con este archivo podrás conectar el teclado. No lo he porbado pero la fuente es buena. Si te da problemas coméntalo y lo probaré.
Mantenos informaciónrmados como te ha ido
Saludos