Buscar este blog
sábado, 28 de noviembre de 2015
PWM bidireccional con ARDUINO
http://diymakers.es/control-velocidad-y-sentido-de-motor-dc/
Etiquetas:Progrmacion ,C++, Practicas programacion
ARDUINO
Reproduce Melodía (se recomienda cambiar la melodia)
#INCLUDE <16F877.H> // LIBRERIA DEL PIC A UTILIZAR
#FUSES XT, NOPROTECT, // CODIGO NO PROTEGIDO
#USE DELAY(CLOCK=4000000) // SELECCION DE LA FRECUENCIA DEL CRISTAL
#USE rs232(BAUD=9600, xmit=PIN_C6, rcv=PIN_C7) // COMUNICAION CON EL PUERTO SERIAL
#ORG 0X1F00, 0X1FFF VOID LOADER16F877(VOID){} // DIRECCION DEL CODIGO DE BUDLOADER
#include <TONES.c> // LIBRERIA DE TONOS MUSICALES
// TIEMPOS DE DURACION DE LAS NOTAS, TIPOS DE NOTAS MUSICALES
int S_CORCHEA=125,CORCHEA=250,FUSA=62;
long NEGRA=500,BLANCA=1000,REDONDA=2000;
VOID MAIN(){
WHILE(1){
// NOTAS DE LA CANCION
DELAY_MS(FUSA);
GENERATE_TONE(G_NOTE[0], CORCHEA);
DELAY_MS(CORCHEA);
GENERATE_TONE(Bb_NOTE[0], S_CORCHEA);
DELAY_MS(NEGRA);
GENERATE_TONE(G_NOTE[0], S_CORCHEA);
DELAY_MS(S_CORCHEA);
GENERATE_TONE(C_NOTE[2], CORCHEA);
GENERATE_TONE(G_NOTE[0], CORCHEA);
GENERATE_TONE(F_NOTE[0], CORCHEA);
GENERATE_TONE(G_NOTE[0], CORCHEA);
DELAY_MS(CORCHEA);
GENERATE_TONE(D_NOTE[2], S_CORCHEA);
DELAY_MS(CORCHEA);
DELAY_MS(CORCHEA);
GENERATE_TONE(G_NOTE[0], S_CORCHEA);
DELAY_MS(S_CORCHEA);
GENERATE_TONE(G_NOTE[0], S_CORCHEA);
GENERATE_TONE(Eb_NOTE[0], CORCHEA);
GENERATE_TONE(D_NOTE[2], CORCHEA);
GENERATE_TONE(Bb_NOTE[0], CORCHEA);
GENERATE_TONE(G_NOTE[0], CORCHEA);
GENERATE_TONE(D_NOTE[2], CORCHEA);
GENERATE_TONE(G_NOTE[2], CORCHEA);
GENERATE_TONE(G_NOTE[0], S_CORCHEA);
GENERATE_TONE(F_NOTE[0], S_CORCHEA);
DELAY_MS(S_CORCHEA);
GENERATE_TONE(F_NOTE[0], S_CORCHEA);
GENERATE_TONE(D_NOTE[0], CORCHEA);
GENERATE_TONE(Bb_NOTE[0], CORCHEA);
GENERATE_TONE(G_NOTE[0], BLANCA);
DELAY_MS(NEGRA);
GENERATE_TONE(F_NOTE[2], S_CORCHEA);
GENERATE_TONE(D_NOTE[2], CORCHEA);
GENERATE_TONE(C_NOTE[2], CORCHEA);
GENERATE_TONE(Bb_NOTE[0], CORCHEA);
GENERATE_TONE(G_NOTE[0], NEGRA);
GENERATE_TONE(Bb_NOTE[0], CORCHEA);
DELAY_MS(NEGRA);
GENERATE_TONE(G_NOTE[0], S_CORCHEA);
DELAY_MS(S_CORCHEA);
GENERATE_TONE(G_NOTE[0], S_CORCHEA);
GENERATE_TONE(D_NOTE[2], CORCHEA);
GENERATE_TONE(G_NOTE[0], CORCHEA);
GENERATE_TONE(F_NOTE[0], CORCHEA);
GENERATE_TONE(G_NOTE[0], NEGRA);
GENERATE_TONE(D_NOTE[2], CORCHEA);
DELAY_MS(NEGRA);
GENERATE_TONE(G_NOTE[0], S_CORCHEA);
DELAY_MS(S_CORCHEA);
GENERATE_TONE(G_NOTE[0], S_CORCHEA);
GENERATE_TONE(Eb_NOTE[0], CORCHEA);
GENERATE_TONE(Bb_NOTE[0], CORCHEA);
GENERATE_TONE(G_NOTE[0], CORCHEA);
GENERATE_TONE(D_NOTE[2], CORCHEA);
GENERATE_TONE(G_NOTE[2], CORCHEA);
GENERATE_TONE(G_NOTE[0], S_CORCHEA);
GENERATE_TONE(F_NOTE[0], S_CORCHEA);
DELAY_MS(S_CORCHEA);
GENERATE_TONE(F_NOTE[0], S_CORCHEA);
GENERATE_TONE(D_NOTE[0], CORCHEA);
GENERATE_TONE(Bb_NOTE[0], CORCHEA);
GENERATE_TONE(G_NOTE[0], BLANCA);
}// WHILE
}// MAIN
#FUSES XT, NOPROTECT, // CODIGO NO PROTEGIDO
#USE DELAY(CLOCK=4000000) // SELECCION DE LA FRECUENCIA DEL CRISTAL
#USE rs232(BAUD=9600, xmit=PIN_C6, rcv=PIN_C7) // COMUNICAION CON EL PUERTO SERIAL
#ORG 0X1F00, 0X1FFF VOID LOADER16F877(VOID){} // DIRECCION DEL CODIGO DE BUDLOADER
#include <TONES.c> // LIBRERIA DE TONOS MUSICALES
// TIEMPOS DE DURACION DE LAS NOTAS, TIPOS DE NOTAS MUSICALES
int S_CORCHEA=125,CORCHEA=250,FUSA=62;
long NEGRA=500,BLANCA=1000,REDONDA=2000;
VOID MAIN(){
WHILE(1){
// NOTAS DE LA CANCION
DELAY_MS(FUSA);
GENERATE_TONE(G_NOTE[0], CORCHEA);
DELAY_MS(CORCHEA);
GENERATE_TONE(Bb_NOTE[0], S_CORCHEA);
DELAY_MS(NEGRA);
GENERATE_TONE(G_NOTE[0], S_CORCHEA);
DELAY_MS(S_CORCHEA);
GENERATE_TONE(C_NOTE[2], CORCHEA);
GENERATE_TONE(G_NOTE[0], CORCHEA);
GENERATE_TONE(F_NOTE[0], CORCHEA);
GENERATE_TONE(G_NOTE[0], CORCHEA);
DELAY_MS(CORCHEA);
GENERATE_TONE(D_NOTE[2], S_CORCHEA);
DELAY_MS(CORCHEA);
DELAY_MS(CORCHEA);
GENERATE_TONE(G_NOTE[0], S_CORCHEA);
DELAY_MS(S_CORCHEA);
GENERATE_TONE(G_NOTE[0], S_CORCHEA);
GENERATE_TONE(Eb_NOTE[0], CORCHEA);
GENERATE_TONE(D_NOTE[2], CORCHEA);
GENERATE_TONE(Bb_NOTE[0], CORCHEA);
GENERATE_TONE(G_NOTE[0], CORCHEA);
GENERATE_TONE(D_NOTE[2], CORCHEA);
GENERATE_TONE(G_NOTE[2], CORCHEA);
GENERATE_TONE(G_NOTE[0], S_CORCHEA);
GENERATE_TONE(F_NOTE[0], S_CORCHEA);
DELAY_MS(S_CORCHEA);
GENERATE_TONE(F_NOTE[0], S_CORCHEA);
GENERATE_TONE(D_NOTE[0], CORCHEA);
GENERATE_TONE(Bb_NOTE[0], CORCHEA);
GENERATE_TONE(G_NOTE[0], BLANCA);
DELAY_MS(NEGRA);
GENERATE_TONE(F_NOTE[2], S_CORCHEA);
GENERATE_TONE(D_NOTE[2], CORCHEA);
GENERATE_TONE(C_NOTE[2], CORCHEA);
GENERATE_TONE(Bb_NOTE[0], CORCHEA);
GENERATE_TONE(G_NOTE[0], NEGRA);
GENERATE_TONE(Bb_NOTE[0], CORCHEA);
DELAY_MS(NEGRA);
GENERATE_TONE(G_NOTE[0], S_CORCHEA);
DELAY_MS(S_CORCHEA);
GENERATE_TONE(G_NOTE[0], S_CORCHEA);
GENERATE_TONE(D_NOTE[2], CORCHEA);
GENERATE_TONE(G_NOTE[0], CORCHEA);
GENERATE_TONE(F_NOTE[0], CORCHEA);
GENERATE_TONE(G_NOTE[0], NEGRA);
GENERATE_TONE(D_NOTE[2], CORCHEA);
DELAY_MS(NEGRA);
GENERATE_TONE(G_NOTE[0], S_CORCHEA);
DELAY_MS(S_CORCHEA);
GENERATE_TONE(G_NOTE[0], S_CORCHEA);
GENERATE_TONE(Eb_NOTE[0], CORCHEA);
GENERATE_TONE(Bb_NOTE[0], CORCHEA);
GENERATE_TONE(G_NOTE[0], CORCHEA);
GENERATE_TONE(D_NOTE[2], CORCHEA);
GENERATE_TONE(G_NOTE[2], CORCHEA);
GENERATE_TONE(G_NOTE[0], S_CORCHEA);
GENERATE_TONE(F_NOTE[0], S_CORCHEA);
DELAY_MS(S_CORCHEA);
GENERATE_TONE(F_NOTE[0], S_CORCHEA);
GENERATE_TONE(D_NOTE[0], CORCHEA);
GENERATE_TONE(Bb_NOTE[0], CORCHEA);
GENERATE_TONE(G_NOTE[0], BLANCA);
}// WHILE
}// MAIN
Etiquetas:Progrmacion ,C++, Practicas programacion
C (CCS)
Visualización de salidas en HYPERTERMINAL
#INCLUDE <16F877.H> // LIBRERIA DEL PIC A UTILIZAR
#FUSES XT, NOPROTECT, // CODIGO NO PROTEGIDO
#USE DELAY(CLOCK=4000000) // SELECCION DE LA FRECUENCIA DEL CRISTAL
#USE rs232(BAUD=9600, XMIT=PIN_C6, rcv=PIN_C7) // COMUNICAION CON EL PUERTO SERIAL
#ORG 0X1F00, 0X1FFF VOID LOADER16F877(VOID){} // DIRECCION DEL CODIGO DE BUDLOADER
INT VAR;
VOID MAIN(){
WHILE(1){
VAR=INPUT_A();
IF(VAR==0){
OUTPUT_B(0X00); // SALIDAS EN CEROS
PRINTF("TODOS LOS BITS APAGADOS \n\r"); // ENVIA MENSAJE AL PUERTO SERIAL
}// IF
ELSE IF(VAR==1){
OUTPUT_B(0X01); // SALIDAS EN UNOS
PRINTF("TODOS LOS LEDS ENCENDIDOS \n\r"); // ENVIA MENSAJE AL PUERTO SERIAL
DELAY_MS(1000); // DELAY DE 1 SEGUNDO
}// ELSE IF
}//WHILE
}//MAIN
#FUSES XT, NOPROTECT, // CODIGO NO PROTEGIDO
#USE DELAY(CLOCK=4000000) // SELECCION DE LA FRECUENCIA DEL CRISTAL
#USE rs232(BAUD=9600, XMIT=PIN_C6, rcv=PIN_C7) // COMUNICAION CON EL PUERTO SERIAL
#ORG 0X1F00, 0X1FFF VOID LOADER16F877(VOID){} // DIRECCION DEL CODIGO DE BUDLOADER
INT VAR;
VOID MAIN(){
WHILE(1){
VAR=INPUT_A();
IF(VAR==0){
OUTPUT_B(0X00); // SALIDAS EN CEROS
PRINTF("TODOS LOS BITS APAGADOS \n\r"); // ENVIA MENSAJE AL PUERTO SERIAL
}// IF
ELSE IF(VAR==1){
OUTPUT_B(0X01); // SALIDAS EN UNOS
PRINTF("TODOS LOS LEDS ENCENDIDOS \n\r"); // ENVIA MENSAJE AL PUERTO SERIAL
DELAY_MS(1000); // DELAY DE 1 SEGUNDO
}// ELSE IF
}//WHILE
}//MAIN
Etiquetas:Progrmacion ,C++, Practicas programacion
C (CCS)
Control de LCD (Desplegado, Corrimiento Derecha, Corrimiento Izquierda)
; Desplegar texto
PROCESSOR 16877
INCLUDE <P16F877.INC>
RDELAY EQU H'20'
ESTADO EQU 0X03
PUERTOB EQU 0X06
PUERTOD EQU 0X08
RS EQU 0
RW EQU 2
E EQU 1
W EQU 0
F EQU 1
ORG 0
GOTO INICIO
ORG 5
; PROGRAMA PRINCIPAL
INICIO:
CLRF PORTB ;Limpia PORTB
CLRF PORTD ;Limpia PORTD
BSF STATUS, RP0
BCF STATUS, RP1 ;Selecciona el banco 1
CLRF TRISB ;Configura PORTB como salida
CLRF TRISA ;Configura PORTA como salida
BCF STATUS,RP0 ;Regresa al banco 0
; CODIGO DE DESPLIEGUE DE MENSAJES
DESPLEGAR:
CALL INICIOLCD
CALL MENSAJE1
CALL R2
CALL MENSAJE2
GOTO DESPLEGAR
; SUBRUTINA DE MENSAJE 1
MENSAJE1:
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW 'M' ;Mueve 'M' a W
MOVWF PORTB ;Mueve lo que hay en W a PORTB
CALL ESCRIBE ;Imprime en LCD
MOVLW 'I'
MOVWF PORTB
CALL ESCRIBE
MOVLW 'C'
MOVWF PORTB
CALL ESCRIBE
MOVLW 'R'
MOVWF PORTB
CALL ESCRIBE
MOVLW 'O'
MOVWF PORTB
CALL ESCRIBE
MOVLW 'S'
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
CALL RETARDO10
RETURN
MENSAJE2:
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW 'I' ;Mueve 'I' a W
MOVWF PORTB ;Mueve lo que hay en W a PORTB
CALL ESCRIBE ;Imprime en LCD
MOVLW 'T'
MOVWF PORTB
CALL ESCRIBE
MOVLW 'T'
MOVWF PORTB
CALL ESCRIBE
CALL RETARDO10
RETURN
; RENGLON 2
R2:
BCF PORTD,0 ; RS=0 MODO INST
MOVLW 0xC0 ;2da linea USAR 0C
MOVWF PORTB
CALL COMANDO
RETURN
; INICIALIZACION DE LA LCD
INICIOLCD:
CALL RETARDO100
MOVLW 30H
MOVWF PUERTOB
CALL RETARDO100
MOVLW 30H
MOVWF PUERTOB
CALL RETARDO100
MOVLW 38H
MOVWF PUERTOB
CALL COMANDO
MOVLW H'0C'
MOVWF PUERTOB
CALL COMANDO
MOVLW H'01'
MOVWF PUERTOB
CALL COMANDO
MOVLW H'06'
MOVWF PUERTOB
CALL COMANDO
MOVLW H'02'
MOVWF PUERTOB
CALL COMANDO
MOVLW H'80'
MOVWF PUERTOB
CALL COMANDO
RETURN
COMANDO:
CALL RETARDO10
BSF PUERTOD, E
BCF PUERTOD, RS
CALL RETARDO100
BCF PUERTOD, E
BCF PUERTOD, RS
CALL RETARDO10
CALL RETARDO10
RETURN
ESCRIBE:
CALL RETARDO10
BSF PUERTOD, RS
BSF PUERTOD, E
CALL RETARDO10
BCF PUERTOD, E
BCF PUERTOD, RS
CALL RETARDO10
CALL RETARDO10
RETURN
; RETARDO DE 255 MICROSEC
RETARDO255:
MOVLW 0XFF
MOVWF RDELAY
T1:
DECFSZ RDELAY, F
GOTO T1
RETURN
; RETARDO DE 100ms
RETARDO100:
CALL RETARDO10
CALL RETARDO10
CALL RETARDO10
CALL RETARDO10
CALL RETARDO10
CALL RETARDO10
CALL RETARDO10
CALL RETARDO10
CALL RETARDO10
CALL RETARDO10
RETURN
; RETARDO DE 10 ms
RETARDO10:
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
RETURN
END
; Desplazar a la derecha
processor 16f877
INCLUDE <P16f877.INC>
N EQU H'21' ; asignamos direcciones.
M EQU H'22'
Q EQU H'23'
VAL1 EQU H'24'
VAL2 EQU H'25'
CONTA1 EQU 30H
CONTA2 EQU 30H
org 0
GOTO INICIO
org 5 ; vector de reset, vector de interrupcion
INICIO
clrf PORTB ;Limpia PORTB
clrf PORTA ;Limpia PORTA
bsf STATUS, RP0
bcf STATUS, RP1 ;Selecciona el banco 1
clrf TRISB ;Configura PORTB como salida
clrf TRISA ;Configura PORTA como salida
bcf STATUS,RP0 ;Regresa al banco 0
LCD_INICIAR
CALL LCD_IN
CALL I
CALL F1
CALL NEXT
CALL I
CALL F2
GOTO LCD_INICIAR
I:
CALL DELAYL
MOVLW 'E'
CALL MANDAR
MOVLW 'J'
CALL MANDAR
MOVLW 'E'
CALL MANDAR
MOVLW 'R'
CALL MANDAR
MOVLW 'C'
CALL MANDAR
MOVLW 'I'
CALL MANDAR
MOVLW 'C'
CALL MANDAR
MOVLW 'I'
CALL MANDAR
MOVLW 'O'
CALL MANDAR
MOVLW ' '
CALL MANDAR
MOVLW '2'
CALL MANDAR
MOVLW ' '
CALL MANDAR
RETURN
F1:
MOVLW 1CH ;Desplazar 1C DERECHA 18 HIZQUIERDA
CALL EJECUTA
DECFSZ VAL1
GOTO F1
RETURN
F2:
MOVLW 1CH ;Desplazar 1C DERECHA 18 HIZQUIERDA
CALL EJECUTA
DECFSZ VAL2
GOTO F2
RETURN
NEXT:
CALL LCD_IN
MOVLW 0xD5 ;Ajusta la direccion de DD RAM
CALL EJECUTA
RETURN
LCD_IN:
MOVLW 30H ;Activa funcion
CALL EJECUTA
CALL DELAY
MOVLW 30H ;Activa funcion
CALL EJECUTA
CALL DELAY
MOVLW 38H ;Activa funcion
CALL EJECUTA
MOVLW 0CH ;Screen on/off cursor
CALL EJECUTA
MOVLW 01H ;Borrar pantalla
CALL EJECUTA
MOVLW 06H ;Direccion de movimiento
CALL EJECUTA
MOVLW 02H ;Home
CALL EJECUTA
MOVLW 95H ;Ajusta la direccion de DD RAM
CALL EJECUTA
RETURN
EJECUTA:
MOVWF PORTB
CALL DELAY
MOVLW 02H
MOVWF PORTA
CALL DELAY
MOVLW 00H
MOVWF PORTA
CALL DELAY
RETURN
MANDAR:
MOVWF PORTB
CALL DELAY
MOVLW 03H
MOVWF PORTA
CALL DELAY
MOVLW 01H
MOVWF PORTA
CALL DELAY
RETURN
DELAY:
movlw 10H
movwf Q ;la CTE1 pasa a la direccion de VALOR1.
TRES
movlw 8H
movwf M ;la CTE2 pasa a la direccion de VALOR2.
DOS
movlw 255H
movwf N ;la CTE3 pasa a la direccion de VALOR3.
UNO
DECFSZ N,1
GOTO UNO
DECFSZ M,1
GOTO DOS
DECFSZ Q,1
GOTO TRES
RETURN
DELAYL:
MOVLW CONTA1
MOVWF VAL1
MOVLW CONTA2
MOVWF VAL2
RETURN
END
; Desplazar a la izquierda
processor 16f877
INCLUDE <P16f877.INC>
N EQU H'21' ; asignamos direcciones.
M EQU H'22'
Q EQU H'23'
;quitndo el comentario podemos desplegar el mensaje en la parte alta del desplay
;VAL1 EQU H'60'
VAL2 EQU H'60'
;CONTA1 EQU 90H
CONTA2 EQU 90H
org 0
GOTO INICIO
org 5 ; vector de reset, vector de interrupcion
INICIO
clrf PORTB ;Limpia PORTB
clrf PORTD ;Limpia PORTD
bsf STATUS, RP0
bcf STATUS, RP1 ;Selecciona el banco 1
clrf TRISB ;Configura PORTB como salida
clrf TRISD ;Configura PORTD como salida
bcf STATUS,RP0 ;Regresa al banco 0
LCD_INICIAR
;quitndo el comentario podemos desplegar el mensaje en la parte alta del desplay
CALL LCD_IN
;CALL I
;CALL F1
;CALL NEXT
CALL I
CALL F2
GOTO LCD_INICIAR
I:
CALL DELAYL
MOVLW 'E'
CALL MANDAR
MOVLW 'J'
CALL MANDAR
MOVLW 'E'
CALL MANDAR
MOVLW 'R'
CALL MANDAR
MOVLW 'C'
CALL MANDAR
MOVLW 'I'
CALL MANDAR
MOVLW 'C'
CALL MANDAR
MOVLW 'I'
CALL MANDAR
MOVLW 'O'
CALL MANDAR
MOVLW ' '
CALL MANDAR
MOVLW '3'
CALL MANDAR
RETURN
;quitndo el comentario podemos desplegar el mensaje en la parte alta del desplay
;F1:
; MOVLW 18H ;Desplazar 1C DERECHA 18 HIZQUIERDA
; CALL EJECUTA
; DECFSZ VAL1
; GOTO F1
;RETURN
F2:
MOVLW 18H ;Desplazar 1C DERECHA 18 HIZQUIERDA
CALL EJECUTA
DECFSZ VAL2
GOTO F2
RETURN
NEXT:
CALL LCD_IN
MOVLW 0xD5 ;Ajusta la direccion de DD RAM
CALL EJECUTA
RETURN
LCD_IN:
MOVLW 30H ;Activa funcion
CALL EJECUTA
CALL DELAY
MOVLW 30H ;Activa funcion
CALL EJECUTA
CALL DELAY
MOVLW 38H ;Activa funcion
CALL EJECUTA
MOVLW 0CH ;Screen on/off cursor
CALL EJECUTA
MOVLW 01H ;Borrar pantalla
CALL EJECUTA
MOVLW 06H ;Direccion de movimiento
CALL EJECUTA
MOVLW 02H ;Home
CALL EJECUTA
MOVLW 95H ;Ajusta la direccion de DD RAM
CALL EJECUTA
RETURN
EJECUTA:
MOVWF PORTB
CALL DELAY
MOVLW 02H
MOVWF PORTD
CALL DELAY
MOVLW 00H
MOVWF PORTD
CALL DELAY
RETURN
MANDAR:
MOVWF PORTB
CALL DELAY
MOVLW 03H
MOVWF PORTD
CALL DELAY
MOVLW 01H
MOVWF PORTD
CALL DELAY
RETURN
DELAY:
movlw 20H
movwf Q ;la CTE1 pasa a la direccion de VALOR1.
TRES
movlw 8H
movwf M ;la CTE2 pasa a la direccion de VALOR2.
DOS
movlw 255H
movwf N ;la CTE3 pasa a la direccion de VALOR3.
UNO
DECFSZ N,1
GOTO UNO
DECFSZ M,1
GOTO DOS
DECFSZ Q,1
GOTO TRES
RETURN
DELAYL:
;quitndo el comentario podemos desplegar el mensaje en la parte alta del desplay
;MOVLW CONTA1
;MOVWF VAL1
MOVLW CONTA2
MOVWF VAL2
RETURN
END
PROCESSOR 16877
INCLUDE <P16F877.INC>
RDELAY EQU H'20'
ESTADO EQU 0X03
PUERTOB EQU 0X06
PUERTOD EQU 0X08
RS EQU 0
RW EQU 2
E EQU 1
W EQU 0
F EQU 1
ORG 0
GOTO INICIO
ORG 5
; PROGRAMA PRINCIPAL
INICIO:
CLRF PORTB ;Limpia PORTB
CLRF PORTD ;Limpia PORTD
BSF STATUS, RP0
BCF STATUS, RP1 ;Selecciona el banco 1
CLRF TRISB ;Configura PORTB como salida
CLRF TRISA ;Configura PORTA como salida
BCF STATUS,RP0 ;Regresa al banco 0
; CODIGO DE DESPLIEGUE DE MENSAJES
DESPLEGAR:
CALL INICIOLCD
CALL MENSAJE1
CALL R2
CALL MENSAJE2
GOTO DESPLEGAR
; SUBRUTINA DE MENSAJE 1
MENSAJE1:
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW 'M' ;Mueve 'M' a W
MOVWF PORTB ;Mueve lo que hay en W a PORTB
CALL ESCRIBE ;Imprime en LCD
MOVLW 'I'
MOVWF PORTB
CALL ESCRIBE
MOVLW 'C'
MOVWF PORTB
CALL ESCRIBE
MOVLW 'R'
MOVWF PORTB
CALL ESCRIBE
MOVLW 'O'
MOVWF PORTB
CALL ESCRIBE
MOVLW 'S'
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
CALL RETARDO10
RETURN
MENSAJE2:
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW ' '
MOVWF PORTB
CALL ESCRIBE
MOVLW 'I' ;Mueve 'I' a W
MOVWF PORTB ;Mueve lo que hay en W a PORTB
CALL ESCRIBE ;Imprime en LCD
MOVLW 'T'
MOVWF PORTB
CALL ESCRIBE
MOVLW 'T'
MOVWF PORTB
CALL ESCRIBE
CALL RETARDO10
RETURN
; RENGLON 2
R2:
BCF PORTD,0 ; RS=0 MODO INST
MOVLW 0xC0 ;2da linea USAR 0C
MOVWF PORTB
CALL COMANDO
RETURN
; INICIALIZACION DE LA LCD
INICIOLCD:
CALL RETARDO100
MOVLW 30H
MOVWF PUERTOB
CALL RETARDO100
MOVLW 30H
MOVWF PUERTOB
CALL RETARDO100
MOVLW 38H
MOVWF PUERTOB
CALL COMANDO
MOVLW H'0C'
MOVWF PUERTOB
CALL COMANDO
MOVLW H'01'
MOVWF PUERTOB
CALL COMANDO
MOVLW H'06'
MOVWF PUERTOB
CALL COMANDO
MOVLW H'02'
MOVWF PUERTOB
CALL COMANDO
MOVLW H'80'
MOVWF PUERTOB
CALL COMANDO
RETURN
COMANDO:
CALL RETARDO10
BSF PUERTOD, E
BCF PUERTOD, RS
CALL RETARDO100
BCF PUERTOD, E
BCF PUERTOD, RS
CALL RETARDO10
CALL RETARDO10
RETURN
ESCRIBE:
CALL RETARDO10
BSF PUERTOD, RS
BSF PUERTOD, E
CALL RETARDO10
BCF PUERTOD, E
BCF PUERTOD, RS
CALL RETARDO10
CALL RETARDO10
RETURN
; RETARDO DE 255 MICROSEC
RETARDO255:
MOVLW 0XFF
MOVWF RDELAY
T1:
DECFSZ RDELAY, F
GOTO T1
RETURN
; RETARDO DE 100ms
RETARDO100:
CALL RETARDO10
CALL RETARDO10
CALL RETARDO10
CALL RETARDO10
CALL RETARDO10
CALL RETARDO10
CALL RETARDO10
CALL RETARDO10
CALL RETARDO10
CALL RETARDO10
RETURN
; RETARDO DE 10 ms
RETARDO10:
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
CALL RETARDO255
RETURN
END
; Desplazar a la derecha
processor 16f877
INCLUDE <P16f877.INC>
N EQU H'21' ; asignamos direcciones.
M EQU H'22'
Q EQU H'23'
VAL1 EQU H'24'
VAL2 EQU H'25'
CONTA1 EQU 30H
CONTA2 EQU 30H
org 0
GOTO INICIO
org 5 ; vector de reset, vector de interrupcion
INICIO
clrf PORTB ;Limpia PORTB
clrf PORTA ;Limpia PORTA
bsf STATUS, RP0
bcf STATUS, RP1 ;Selecciona el banco 1
clrf TRISB ;Configura PORTB como salida
clrf TRISA ;Configura PORTA como salida
bcf STATUS,RP0 ;Regresa al banco 0
LCD_INICIAR
CALL LCD_IN
CALL I
CALL F1
CALL NEXT
CALL I
CALL F2
GOTO LCD_INICIAR
I:
CALL DELAYL
MOVLW 'E'
CALL MANDAR
MOVLW 'J'
CALL MANDAR
MOVLW 'E'
CALL MANDAR
MOVLW 'R'
CALL MANDAR
MOVLW 'C'
CALL MANDAR
MOVLW 'I'
CALL MANDAR
MOVLW 'C'
CALL MANDAR
MOVLW 'I'
CALL MANDAR
MOVLW 'O'
CALL MANDAR
MOVLW ' '
CALL MANDAR
MOVLW '2'
CALL MANDAR
MOVLW ' '
CALL MANDAR
RETURN
F1:
MOVLW 1CH ;Desplazar 1C DERECHA 18 HIZQUIERDA
CALL EJECUTA
DECFSZ VAL1
GOTO F1
RETURN
F2:
MOVLW 1CH ;Desplazar 1C DERECHA 18 HIZQUIERDA
CALL EJECUTA
DECFSZ VAL2
GOTO F2
RETURN
NEXT:
CALL LCD_IN
MOVLW 0xD5 ;Ajusta la direccion de DD RAM
CALL EJECUTA
RETURN
LCD_IN:
MOVLW 30H ;Activa funcion
CALL EJECUTA
CALL DELAY
MOVLW 30H ;Activa funcion
CALL EJECUTA
CALL DELAY
MOVLW 38H ;Activa funcion
CALL EJECUTA
MOVLW 0CH ;Screen on/off cursor
CALL EJECUTA
MOVLW 01H ;Borrar pantalla
CALL EJECUTA
MOVLW 06H ;Direccion de movimiento
CALL EJECUTA
MOVLW 02H ;Home
CALL EJECUTA
MOVLW 95H ;Ajusta la direccion de DD RAM
CALL EJECUTA
RETURN
EJECUTA:
MOVWF PORTB
CALL DELAY
MOVLW 02H
MOVWF PORTA
CALL DELAY
MOVLW 00H
MOVWF PORTA
CALL DELAY
RETURN
MANDAR:
MOVWF PORTB
CALL DELAY
MOVLW 03H
MOVWF PORTA
CALL DELAY
MOVLW 01H
MOVWF PORTA
CALL DELAY
RETURN
DELAY:
movlw 10H
movwf Q ;la CTE1 pasa a la direccion de VALOR1.
TRES
movlw 8H
movwf M ;la CTE2 pasa a la direccion de VALOR2.
DOS
movlw 255H
movwf N ;la CTE3 pasa a la direccion de VALOR3.
UNO
DECFSZ N,1
GOTO UNO
DECFSZ M,1
GOTO DOS
DECFSZ Q,1
GOTO TRES
RETURN
DELAYL:
MOVLW CONTA1
MOVWF VAL1
MOVLW CONTA2
MOVWF VAL2
RETURN
END
; Desplazar a la izquierda
processor 16f877
INCLUDE <P16f877.INC>
N EQU H'21' ; asignamos direcciones.
M EQU H'22'
Q EQU H'23'
;quitndo el comentario podemos desplegar el mensaje en la parte alta del desplay
;VAL1 EQU H'60'
VAL2 EQU H'60'
;CONTA1 EQU 90H
CONTA2 EQU 90H
org 0
GOTO INICIO
org 5 ; vector de reset, vector de interrupcion
INICIO
clrf PORTB ;Limpia PORTB
clrf PORTD ;Limpia PORTD
bsf STATUS, RP0
bcf STATUS, RP1 ;Selecciona el banco 1
clrf TRISB ;Configura PORTB como salida
clrf TRISD ;Configura PORTD como salida
bcf STATUS,RP0 ;Regresa al banco 0
LCD_INICIAR
;quitndo el comentario podemos desplegar el mensaje en la parte alta del desplay
CALL LCD_IN
;CALL I
;CALL F1
;CALL NEXT
CALL I
CALL F2
GOTO LCD_INICIAR
I:
CALL DELAYL
MOVLW 'E'
CALL MANDAR
MOVLW 'J'
CALL MANDAR
MOVLW 'E'
CALL MANDAR
MOVLW 'R'
CALL MANDAR
MOVLW 'C'
CALL MANDAR
MOVLW 'I'
CALL MANDAR
MOVLW 'C'
CALL MANDAR
MOVLW 'I'
CALL MANDAR
MOVLW 'O'
CALL MANDAR
MOVLW ' '
CALL MANDAR
MOVLW '3'
CALL MANDAR
RETURN
;quitndo el comentario podemos desplegar el mensaje en la parte alta del desplay
;F1:
; MOVLW 18H ;Desplazar 1C DERECHA 18 HIZQUIERDA
; CALL EJECUTA
; DECFSZ VAL1
; GOTO F1
;RETURN
F2:
MOVLW 18H ;Desplazar 1C DERECHA 18 HIZQUIERDA
CALL EJECUTA
DECFSZ VAL2
GOTO F2
RETURN
NEXT:
CALL LCD_IN
MOVLW 0xD5 ;Ajusta la direccion de DD RAM
CALL EJECUTA
RETURN
LCD_IN:
MOVLW 30H ;Activa funcion
CALL EJECUTA
CALL DELAY
MOVLW 30H ;Activa funcion
CALL EJECUTA
CALL DELAY
MOVLW 38H ;Activa funcion
CALL EJECUTA
MOVLW 0CH ;Screen on/off cursor
CALL EJECUTA
MOVLW 01H ;Borrar pantalla
CALL EJECUTA
MOVLW 06H ;Direccion de movimiento
CALL EJECUTA
MOVLW 02H ;Home
CALL EJECUTA
MOVLW 95H ;Ajusta la direccion de DD RAM
CALL EJECUTA
RETURN
EJECUTA:
MOVWF PORTB
CALL DELAY
MOVLW 02H
MOVWF PORTD
CALL DELAY
MOVLW 00H
MOVWF PORTD
CALL DELAY
RETURN
MANDAR:
MOVWF PORTB
CALL DELAY
MOVLW 03H
MOVWF PORTD
CALL DELAY
MOVLW 01H
MOVWF PORTD
CALL DELAY
RETURN
DELAY:
movlw 20H
movwf Q ;la CTE1 pasa a la direccion de VALOR1.
TRES
movlw 8H
movwf M ;la CTE2 pasa a la direccion de VALOR2.
DOS
movlw 255H
movwf N ;la CTE3 pasa a la direccion de VALOR3.
UNO
DECFSZ N,1
GOTO UNO
DECFSZ M,1
GOTO DOS
DECFSZ Q,1
GOTO TRES
RETURN
DELAYL:
;quitndo el comentario podemos desplegar el mensaje en la parte alta del desplay
;MOVLW CONTA1
;MOVWF VAL1
MOVLW CONTA2
MOVWF VAL2
RETURN
END
Etiquetas:Progrmacion ,C++, Practicas programacion
ENSAMBLADOR
Control de giro de un motor con visualización en LCD e HYPERTERMINAL
PROCESSOR 16F877; PROCESADOR A UTILIZAR
INCLUDE <P16F877.INC>; LIBRERIA DEL PIC
; VARIABLES DEL DELAY
VAL1 EQU 0x30
VAL2 EQU 0x31
ORG 0; VECTOR DE RESET
GOTO INICIO
ORG 5; INICIO DEL PROGRAMA
; CONFIGURACION DE PUERTOS
INICIO:
CLRF PORTA; LIMPIA LE PUERTO A
CLRF PORTB; LIMPIA LE PUERTO B
CLRF PORTC; LIMPIA LE PUERTO C
CLRF PORTD; LIMPIA EL PUERTO D
CLRF PORTE; LIMPIA EL PUERTO E
BSF STATUS, RP0
BCF STATUS, RP1; SELECCIONA EL BANCO 1
MOVLW 06H; CONFIGURA PUERTOS A Y E COMO DIGITALES
MOVWF ADCON1
MOVLW 3FH; CONFIGURA PUERTO A COMO ENTRADA
MOVWF TRISA
CLRF TRISB; CONFIGURA PUERTO B COMO SALIDA
CLRF TRISC; CONFIGURA PUERTO C COMO SALIDA
CLRF TRISD; CONFIGURA PUERTO D COMO SALIDA
CLRF TRISE; CONFIGURA PUERTO E COMO SALIDA
; CONFIGURACION PARA EL REGISTRO DEL TRANSMISOR
BSF STATUS, RP0; BIT DE SELECCION DE VELOCIDAD
MOVLW D'25'; VELOCIDAD DEL BAUD, 9600
MOVLW 0CFH; PROGRAMA TERMINALES RC7 RX COMO ENTRADA
MOVWF TRISC; Y RC6 - TX COMO SALIDA
MOVLW 24H; MODO ASINCRONO DE 8 BITS
MOVWF TXSTA; HABILITA LA TRANSMICION
BCF PIE1, TXIE; INTERRUPCION DE TRANSMICINO INHABILITADA
BCF PIE1, RCIE; INTERRUPCION DE RECEPCINO INHABILITADA
BCF STATUS, RP0; SELECCIONA EL BANCO CERO
MOVLW 90H; RECEPCION HABILITADA PARA 8 BITS DE DATOS
MOVWF RCSTA
; COMFIGURACION PARA EL REGISTRO DE RECEPTOR
BSF RCSTA, SPEN; HABILITA EL PUERTO SERIE
BSF RCSTA, CREN; CONFIGURA LA RECEPCION CONTINUA EN MODO ASINCRONO
; PROGRAMA PRINCIPAL
PROGRAMA:
CALL LCD_L1; CONFIGURA LA LCD
; LECTURA DE LA ENTRADA
; REVISA SI EN LA ENTRADA HAY UN CERO
REV0:
MOVF PORTA,0 ; LEE EL PUERTO A Y MANDA EL DATO A W
SUBLW 0x00 ; RESTA W CON CERO
BTFSS STATUS,Z ; REVISA SI LA RESTA ES CERO
GOTO REV1 ; NO, VE A REV1
CALL CERO ; SI VE A CERO
; REVISA SI EN LA ENTRADA HAY UN UNO
REV1:
MOVF PORTA,0 ; LEE EL PUERTO A Y MANDA EL DATO A W
SUBLW 0x01 ; RESTA W CON UNO
BTFSS STATUS,Z ; REVISA SI LA RESTA ES CERO
GOTO REV2 ; NO, VE A REV2
CALL UNO ; SI VE A UNO
; REVISA SI EN LA ENTRADA HAY UN DOS
REV2:
MOVF PORTA,0 ; LEE EL PUERTO A Y MANDA EL DATO A W
SUBLW 0x02 ; RESTA W CON DOS
BTFSS STATUS,Z ; REVISA SI LA RESTA ES CERO
GOTO REV0 ; NO, VE A PROGRAMA
CALL DOS ; SI VE A UNO
; SUBRRUTINAS DE DESPLEGADO
CERO:
CALL LCD_L1; CONFIGURA LA LCD
CALL M3; MUESTRA MENSAJE
MOVLW B'000'; MUEVE CERO A W
MOVWF PORTE; MANDA DATOS AL PUERTO E
CALL ESCRIBECERO
GOTO PROGRAMA
ESCRIBECERO:
MOVLW 'M'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'O'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'T'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'O'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'R'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW ' '
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'A'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'P'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'A'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'G'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'A'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'D'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'O'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW ' '
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
RETURN
UNO:
CALL LCD_L1; CONFIGURA LA LCD
CALL M1; MUESTRA MENSAJE
MOVLW B'001'
MOVWF PORTE; MANDA DATOS AL PORT E
CALL ESCRIBEUNO
GOTO PROGRAMA
ESCRIBEUNO:
MOVLW 'G'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'I'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'R'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'O'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW ' '
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'D'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'E'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'R'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'E'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'C'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'H'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'A'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW ' '
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
RETURN
DOS:
CALL LCD_L1; CONFIGURA LA LCD
CALL M2; MUESTRA MENSAJE
MOVLW B'010'
MOVWF PORTE; MANDA DATOS AL PORT E
CALL ESCRIBEDOS
GOTO PROGRAMA
ESCRIBEDOS:
MOVLW 'G'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'I'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'R'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'O'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW ' '
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'I'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'Z'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'Q'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'U'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'I'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'E'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'R'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'D'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'A'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW ' '
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
RETURN
; MENSAJES PARA ENVIAR
M1:
MOVLW 'G'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'I'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'R'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'O'
MOVWF PORTD
CALL ESCRIBE
MOVLW ' '
MOVWF PORTD
CALL ESCRIBE
MOVLW 'D'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'E'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'R'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'E'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'C'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'H'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'A'
MOVWF PORTD
CALL ESCRIBE
RETURN
M2:
MOVLW 'G'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'I'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'R'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'O'
MOVWF PORTD
CALL ESCRIBE
MOVLW ' '
MOVWF PORTD
CALL ESCRIBE
MOVLW 'I'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'Z'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'Q'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'U'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'I'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'E'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'R'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'D'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'A'
MOVWF PORTD
CALL ESCRIBE
RETURN
M3:
MOVLW 'M'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'O'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'T'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'O'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'R'
MOVWF PORTD
CALL ESCRIBE
MOVLW ' '
MOVWF PORTD
CALL ESCRIBE
MOVLW 'A'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'P'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'A'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'G'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'A'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'D'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'O'
MOVWF PORTD
CALL ESCRIBE
RETURN
; SUBRRUTINA PARA INICIALIZAR LA LCD
LCD_L1:
BCF PORTB,7; RS=0, MODO INSTRUCCION
CALL DELAY
MOVLW 0X01; LIMPIA EL LCD
MOVWF PORTD
CALL COMANDO; SE DA DE ALTA EL COMANDO
MOVLW 0x0C; SELECCIONA LA PRIMERA LINEA
MOVWF PORTD
CALL COMANDO; SE DA DE ALTA EL COMANDO
MOVLW 0x3C; SE CONFIGURA EL CURSOR
MOVWF PORTD
CALL COMANDO; SE DA DE ALTA EL COMANDO
BSF PORTB, 7; RS=1, MODO ALTO
RETURN
; SUBRRUTINA PARA EJECUTAR COMANDOS
COMANDO:
BSF PORTB,6; PON ENALE EN 1
CALL DELAY; TIEMPO DE ESPERA
CALL DELAY
BCF PORTB, 6; ENABLE =0
CALL DELAY
RETURN
; SUBRRUTINA PARA ESCRIBIR EN LA LCD
ESCRIBE:
BSF PORTB,7; RS=1, MODO ALTO
CALL COMANDO
RETURN
; SUBRRUTINA PARA ESCRIBIR EN HYPERTERMINAL
TRANSMITE
VERIFICA:; LOOP DE VERIFICACION
btfss TXSTA,TRMT; PREGUNTA SI TERMINO LA TRANSMICION
goto VERIFICA; NO, SIGUE VERIFICANDO
bcf STATUS,RP0; SI, CAMBIA AL BANCO CERO
return
; SUBRRUTINA DE DELAY
DELAY:
MOVLW 0x0F
MOVWF VAL2
CICLO:
MOVLW 0XFF
MOVWF VAL1
CICLO2:
DECFSZ VAL1, 1
GOTO CICLO2
DECFSZ VAL2,1
GOTO CICLO
RETURN
END
INCLUDE <P16F877.INC>; LIBRERIA DEL PIC
; VARIABLES DEL DELAY
VAL1 EQU 0x30
VAL2 EQU 0x31
ORG 0; VECTOR DE RESET
GOTO INICIO
ORG 5; INICIO DEL PROGRAMA
; CONFIGURACION DE PUERTOS
INICIO:
CLRF PORTA; LIMPIA LE PUERTO A
CLRF PORTB; LIMPIA LE PUERTO B
CLRF PORTC; LIMPIA LE PUERTO C
CLRF PORTD; LIMPIA EL PUERTO D
CLRF PORTE; LIMPIA EL PUERTO E
BSF STATUS, RP0
BCF STATUS, RP1; SELECCIONA EL BANCO 1
MOVLW 06H; CONFIGURA PUERTOS A Y E COMO DIGITALES
MOVWF ADCON1
MOVLW 3FH; CONFIGURA PUERTO A COMO ENTRADA
MOVWF TRISA
CLRF TRISB; CONFIGURA PUERTO B COMO SALIDA
CLRF TRISC; CONFIGURA PUERTO C COMO SALIDA
CLRF TRISD; CONFIGURA PUERTO D COMO SALIDA
CLRF TRISE; CONFIGURA PUERTO E COMO SALIDA
; CONFIGURACION PARA EL REGISTRO DEL TRANSMISOR
BSF STATUS, RP0; BIT DE SELECCION DE VELOCIDAD
MOVLW D'25'; VELOCIDAD DEL BAUD, 9600
MOVLW 0CFH; PROGRAMA TERMINALES RC7 RX COMO ENTRADA
MOVWF TRISC; Y RC6 - TX COMO SALIDA
MOVLW 24H; MODO ASINCRONO DE 8 BITS
MOVWF TXSTA; HABILITA LA TRANSMICION
BCF PIE1, TXIE; INTERRUPCION DE TRANSMICINO INHABILITADA
BCF PIE1, RCIE; INTERRUPCION DE RECEPCINO INHABILITADA
BCF STATUS, RP0; SELECCIONA EL BANCO CERO
MOVLW 90H; RECEPCION HABILITADA PARA 8 BITS DE DATOS
MOVWF RCSTA
; COMFIGURACION PARA EL REGISTRO DE RECEPTOR
BSF RCSTA, SPEN; HABILITA EL PUERTO SERIE
BSF RCSTA, CREN; CONFIGURA LA RECEPCION CONTINUA EN MODO ASINCRONO
; PROGRAMA PRINCIPAL
PROGRAMA:
CALL LCD_L1; CONFIGURA LA LCD
; LECTURA DE LA ENTRADA
; REVISA SI EN LA ENTRADA HAY UN CERO
REV0:
MOVF PORTA,0 ; LEE EL PUERTO A Y MANDA EL DATO A W
SUBLW 0x00 ; RESTA W CON CERO
BTFSS STATUS,Z ; REVISA SI LA RESTA ES CERO
GOTO REV1 ; NO, VE A REV1
CALL CERO ; SI VE A CERO
; REVISA SI EN LA ENTRADA HAY UN UNO
REV1:
MOVF PORTA,0 ; LEE EL PUERTO A Y MANDA EL DATO A W
SUBLW 0x01 ; RESTA W CON UNO
BTFSS STATUS,Z ; REVISA SI LA RESTA ES CERO
GOTO REV2 ; NO, VE A REV2
CALL UNO ; SI VE A UNO
; REVISA SI EN LA ENTRADA HAY UN DOS
REV2:
MOVF PORTA,0 ; LEE EL PUERTO A Y MANDA EL DATO A W
SUBLW 0x02 ; RESTA W CON DOS
BTFSS STATUS,Z ; REVISA SI LA RESTA ES CERO
GOTO REV0 ; NO, VE A PROGRAMA
CALL DOS ; SI VE A UNO
; SUBRRUTINAS DE DESPLEGADO
CERO:
CALL LCD_L1; CONFIGURA LA LCD
CALL M3; MUESTRA MENSAJE
MOVLW B'000'; MUEVE CERO A W
MOVWF PORTE; MANDA DATOS AL PUERTO E
CALL ESCRIBECERO
GOTO PROGRAMA
ESCRIBECERO:
MOVLW 'M'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'O'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'T'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'O'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'R'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW ' '
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'A'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'P'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'A'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'G'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'A'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'D'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'O'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW ' '
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
RETURN
UNO:
CALL LCD_L1; CONFIGURA LA LCD
CALL M1; MUESTRA MENSAJE
MOVLW B'001'
MOVWF PORTE; MANDA DATOS AL PORT E
CALL ESCRIBEUNO
GOTO PROGRAMA
ESCRIBEUNO:
MOVLW 'G'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'I'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'R'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'O'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW ' '
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'D'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'E'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'R'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'E'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'C'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'H'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'A'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW ' '
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
RETURN
DOS:
CALL LCD_L1; CONFIGURA LA LCD
CALL M2; MUESTRA MENSAJE
MOVLW B'010'
MOVWF PORTE; MANDA DATOS AL PORT E
CALL ESCRIBEDOS
GOTO PROGRAMA
ESCRIBEDOS:
MOVLW 'G'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'I'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'R'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'O'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW ' '
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'I'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'Z'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'Q'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'U'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'I'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'E'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'R'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'D'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW 'A'
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
MOVLW ' '
MOVWF TXREG; MUEVE W AL REGISTRO DE TRANSMICION
BSF STATUS, RP0; CAMBIO AL BANCO 1
CALL TRANSMITE; TRANSMITE EL NUMERO AL CANAL
RETURN
; MENSAJES PARA ENVIAR
M1:
MOVLW 'G'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'I'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'R'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'O'
MOVWF PORTD
CALL ESCRIBE
MOVLW ' '
MOVWF PORTD
CALL ESCRIBE
MOVLW 'D'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'E'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'R'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'E'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'C'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'H'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'A'
MOVWF PORTD
CALL ESCRIBE
RETURN
M2:
MOVLW 'G'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'I'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'R'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'O'
MOVWF PORTD
CALL ESCRIBE
MOVLW ' '
MOVWF PORTD
CALL ESCRIBE
MOVLW 'I'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'Z'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'Q'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'U'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'I'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'E'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'R'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'D'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'A'
MOVWF PORTD
CALL ESCRIBE
RETURN
M3:
MOVLW 'M'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'O'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'T'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'O'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'R'
MOVWF PORTD
CALL ESCRIBE
MOVLW ' '
MOVWF PORTD
CALL ESCRIBE
MOVLW 'A'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'P'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'A'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'G'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'A'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'D'
MOVWF PORTD
CALL ESCRIBE
MOVLW 'O'
MOVWF PORTD
CALL ESCRIBE
RETURN
; SUBRRUTINA PARA INICIALIZAR LA LCD
LCD_L1:
BCF PORTB,7; RS=0, MODO INSTRUCCION
CALL DELAY
MOVLW 0X01; LIMPIA EL LCD
MOVWF PORTD
CALL COMANDO; SE DA DE ALTA EL COMANDO
MOVLW 0x0C; SELECCIONA LA PRIMERA LINEA
MOVWF PORTD
CALL COMANDO; SE DA DE ALTA EL COMANDO
MOVLW 0x3C; SE CONFIGURA EL CURSOR
MOVWF PORTD
CALL COMANDO; SE DA DE ALTA EL COMANDO
BSF PORTB, 7; RS=1, MODO ALTO
RETURN
; SUBRRUTINA PARA EJECUTAR COMANDOS
COMANDO:
BSF PORTB,6; PON ENALE EN 1
CALL DELAY; TIEMPO DE ESPERA
CALL DELAY
BCF PORTB, 6; ENABLE =0
CALL DELAY
RETURN
; SUBRRUTINA PARA ESCRIBIR EN LA LCD
ESCRIBE:
BSF PORTB,7; RS=1, MODO ALTO
CALL COMANDO
RETURN
; SUBRRUTINA PARA ESCRIBIR EN HYPERTERMINAL
TRANSMITE
VERIFICA:; LOOP DE VERIFICACION
btfss TXSTA,TRMT; PREGUNTA SI TERMINO LA TRANSMICION
goto VERIFICA; NO, SIGUE VERIFICANDO
bcf STATUS,RP0; SI, CAMBIA AL BANCO CERO
return
; SUBRRUTINA DE DELAY
DELAY:
MOVLW 0x0F
MOVWF VAL2
CICLO:
MOVLW 0XFF
MOVWF VAL1
CICLO2:
DECFSZ VAL1, 1
GOTO CICLO2
DECFSZ VAL2,1
GOTO CICLO
RETURN
END
Etiquetas:Progrmacion ,C++, Practicas programacion
ENSAMBLADOR
Chat entre dos computadoras con PIC y Bluetooth
#INCLUDE <16F877.H> // LIBRERIA DEL PIC A UTILIZAR
#FUSES XT, NOPROTECT, // CODIGO NO PROTEGIDO
#USE DELAY(CLOCK=4000000) // SELECCION DE LA FRECUENCIA DEL
CRISTAL
#USE RS232(BAUD=9600, BITS=8, PARITY=N, XMIT=PIN_C6, RCV=PIN_C7)
// COMUNICAION CON EL PUERTO SERIAL
#ORG 0X1F00, 0X1FFF VOID LOADER16F877(VOID){} // DIRECCION DEL
CODIGO DE BUDLOADER
CHAR COMANDO; // COMANDO DE INICO
CHAR MENSAJE[20]; // ARREGLO DE LOS MENSAJES
VOID MAIN(){
WHILE(TRUE){
COMANDO=GETC(); // LEE UN COMANDO PARA INICIALIZAR LA
COMUNICACINO
IF(COMANDO==' '){
// MENSAJE INICIAL
PRINTF("\conexión
ESTABLECIDA");
PRINTF("\n");
PRINTF("\rCHAT BLUETOOTH");
PRINTF("\n");
DELAY_MS(3000);
DO{
PRINTF("\rPC1:
"); // ESCRIBE LA PC1
GETS(MENSAJE);
OUTPUT_B(0X01); //
ACTIVA EL RELAY, CAMBIA EL MANDO A LA PC2
PRINTF("\rPC2:
"); // ESCRIBE LA PC2
GETS(MENSAJE);
OUTPUT_B(0X00); //
ACTIVA EL RELAY, CAMBIA EL MANDO A LA PC1
}WHILE(COMANDO==' '); // REALIZA LO ANTERIOR MIENTRAS QUE
COMANDO NO CAMBIE DE VALOR
}//IF
}//WHILE
}//MAIN
Conexiones con pic, bluetooth y relay
Etiquetas:Progrmacion ,C++, Practicas programacion
C (CCS)
viernes, 27 de noviembre de 2015
Señal de Video en formato VGA
Señales de vídeo de pantalla blanca, 8 barras de colores verticales, tres barras horizontales y tablero de ajedrez
----------------------------------------------------------------------------------
-- PRÁCTICA 3
-- DISEÑAR EN IMPLEMENTAR UN GENERADOR DE SEÑALES DE PRUEBA DE VÍDEO UTILIZANDO EL
-- PUERTO VGA PARA EL DESPLIEGUE DE LAS MISMAS
----------------------------------------------------------------------------------
library IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY VGA IS
PORT ( R : OUT STD_LOGIC_VECTOR ( 3 DOWNTO 0);-- SEÑAL DEL COLOR ROJO
G : OUT STD_LOGIC_VECTOR (3 DOWNTO 0);-- SEÑAL DEL COLOR VERDE
B : OUT STD_LOGIC_VECTOR ( 3 DOWNTO 0);-- SEÑAL DEL COLOR AZUL
VS : OUT STD_LOGIC; -- SINCRONISMO VERTICAL
HS : out STD_LOGIC; --SINCRONISMO HORIZONTAL
RESET : IN STD_LOGIC; -- SALIDA DEL RESET
CLK : IN STD_LOGIC; -- RELOJ INTERNO
S : IN STD_LOGIC_VECTOR (1 DOWNTO 0)); -- SELECTOR DE SEÑAL
END VGA;
ARCHITECTURE VIDEO OF VGA IS
BEGIN
-- SEÑALES DE SINCRONISMO
PROCESS (CLK, RESET)
VARIABLE PIX : INTEGER := 0;-- CONTADOR DE PIXELES
VARIABLE LIN : INTEGER := 0;-- CONTADOR DE LINEAS
VARIABLE DESP_P : INTEGER :=1;-- CONTADOR PARA DESPLEGAR UN PIXEL(divisor de frecuencia a 25MHz)
VARIABLE PT_R : STD_LOGIC_VECTOR (3 DOWNTO 0):="0000"; -- VARIABLE INTERNA DE ROJO
VARIABLE PT_V : STD_LOGIC_VECTOR (3 DOWNTO 0):="0000"; -- VARIABLE INTERNA DE VERDE
VARIABLE PT_A : STD_LOGIC_VECTOR (3 DOWNTO 0):="0000"; -- VARIABLE INTERNA DE AZUL
BEGIN
--DIVISOR A 25 HHz
IF(RISING_EDGE (CLK))THEN
DESP_P := DESP_P-1;
IF (RESET = '1')THEN
DESP_P :=1;
R <= "0000";
G <= "0000";
B <= "0000";
VS <= '0';
HS <= '0';
END IF;
IF(DESP_P =0)THEN
DESP_P :=2;
CASE S IS
-- PANTALLA BLANCA
WHEN "00" =>
PT_R := "1111" ; PT_V := "1111" ; PT_A := "1111" ;
-- TRES BARRAS HORIZONTALES
WHEN "10" =>
IF LIN >= 0 AND LIN < 159 THEN
PT_R := "1111" ; PT_V := "0000" ; PT_A := "0000" ;
ELSIF LIN >= 159 AND LIN < 319 THEN
PT_R := "0000" ; PT_V := "1111" ; PT_A := "0000" ;
ELSIF LIN >= 319 AND LIN < 479 THEN
PT_R := "0000" ; PT_V := "0000" ; PT_A := "1111" ;
END IF;
-- BARRAS DE COLORES VERTICALES
WHEN "01" =>
IF PIX >= 0 AND PIX < 79 THEN -- BLANCO
PT_R := "1111" ; PT_V := "1111" ; PT_A := "1111" ;
ELSIF PIX >= 79 AND PIX < 159 THEN -- AMARILLO
PT_R := "1111" ; PT_V := "1111" ; PT_A := "0000" ;
ELSIF PIX >= 159 AND PIX < 239 THEN -- CYAN
PT_R := "0000" ; PT_V := "1111" ; PT_A := "1111" ;
ELSIF PIX >= 239 AND PIX < 319 THEN -- VERDE
PT_R := "0000" ; PT_V := "1111" ; PT_A := "0000" ;
ELSIF PIX >= 319 AND PIX < 399 THEN -- MAGENTA
PT_R := "1111" ; PT_V := "0000" ; PT_A := "1111" ;
ELSIF PIX >= 399 AND PIX < 479 THEN -- ROJO
PT_R := "1111" ; PT_V := "0000" ; PT_A := "0000" ;
ELSIF PIX >= 479 AND PIX < 559 THEN -- AZUL
PT_R := "0000" ; PT_V := "0000" ; PT_A := "1111" ;
ELSIF PIX >= 559 AND PIX < 639 THEN -- NEGRO
PT_R := "0000" ; PT_V := "0000" ; PT_A := "0000" ;
END IF;
-- TABLERO DE AJEDREZ
WHEN "11" =>
-- HORIZONTAL
IF PIX >= 0 AND PIX < 79 THEN -- BLANCO
PT_R := "1111" ; PT_V := "1111" ; PT_A := "1111" ;
ELSIF PIX >= 79 AND PIX < 159 THEN -- NEGRO
PT_R := "0000" ; PT_V := "0000" ; PT_A := "0000" ;
ELSIF PIX >= 159 AND PIX < 239 THEN -- BLANCO
PT_R := "1111" ; PT_V := "1111" ; PT_A := "1111" ;
ELSIF PIX >= 239 AND PIX < 319 THEN -- NEGRO
PT_R := "0000" ; PT_V := "0000" ; PT_A := "0000" ;
ELSIF PIX >= 319 AND PIX < 399 THEN -- BLANCO
PT_R := "1111" ; PT_V := "1111" ; PT_A := "1111" ;
ELSIF PIX >= 399 AND PIX < 479 THEN -- NEGRO
PT_R := "0000" ; PT_V := "0000" ; PT_A := "0000" ;
ELSIF PIX >= 479 AND PIX < 559 THEN -- BLANCO
PT_R := "1111" ; PT_V := "1111" ; PT_A := "1111" ;
ELSIF PIX >= 559 AND PIX < 639 THEN -- NEGRO
PT_R := "0000" ; PT_V := "0000" ; PT_A := "0000" ;
END IF;
-- VERTICAL
IF LIN >= 0 AND LIN < 59 THEN -- BLANCO
PT_R := PT_R ; PT_V := PT_V ; PT_A := PT_A;
ELSIF LIN >= 59 AND LIN < 119 THEN -- NEGRO
PT_R := NOT PT_R ; PT_V := NOT PT_V ;PT_A := NOT PT_A ;
ELSIF LIN >= 119 AND LIN < 179 THEN -- BLANCO
PT_R := PT_R ; PT_V := PT_V ; PT_A := PT_A;
ELSIF LIN >= 179 AND LIN < 239 THEN -- NEGRO
PT_R := NOT PT_R ; PT_V := NOT PT_V ;PT_A := NOT PT_A ;
ELSIF LIN >= 239 AND LIN < 299 THEN -- BLANCO
PT_R := PT_R ; PT_V := PT_V ; PT_A := PT_A;
ELSIF LIN >= 299 AND LIN < 359 THEN -- NEGRO
PT_R := NOT PT_R ; PT_V := NOT PT_V ;PT_A := NOT PT_A ;
ELSIF LIN >= 359 AND LIN < 419 THEN -- BLANCO
PT_R := PT_R ; PT_V := PT_V ; PT_A := PT_A;
ELSIF LIN >= 419 AND LIN < 479 THEN -- NEGRO
PT_R := NOT PT_R ; PT_V := NOT PT_V ;PT_A := NOT PT_A ;
END IF;
WHEN OTHERS =>
PT_R := "0000" ; PT_V := "0000" ; PT_A := "0000" ;
END CASE;
-- CUENTA HASTA 800
PIX := PIX+1;
IF PIX = 800 then
LIN := LIN+1;
PIX :=0;
END IF;
-- CUENTA HASTA 521
IF LIN = 521 then
LIN := 0;
END IF;
-- PERIODO DE BORRADO HORIZONTAL
IF PIX >= (640+16) AND PIX < (640+16+96) THEN
HS <= '0';
ELSE
HS <= '1';
END IF;
-- PERIODO DE BORRADO VERTICAL
IF LIN >= (480+10) AND LIN < (480+10+2) THEN
VS <= '0' ;
else
VS <= '1';
END IF ;
-- IGUALACIÓN DE LAS VARIABLES INTERNAS A LAS SALIDAS R, G, B.
IF PIX < 640 AND LIN <480 THEN
R <= PT_R;
G <= PT_V;
B <= PT_A;
ELSE
R <= "0000" ;
G <= "0000" ;
B <= "0000" ;
END IF;
END IF;
END IF;
END PROCESS;
END VIDEO;
----------------------------------------------------------------------------------
-- PRÁCTICA 3
-- DISEÑAR EN IMPLEMENTAR UN GENERADOR DE SEÑALES DE PRUEBA DE VÍDEO UTILIZANDO EL
-- PUERTO VGA PARA EL DESPLIEGUE DE LAS MISMAS
----------------------------------------------------------------------------------
library IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY VGA IS
PORT ( R : OUT STD_LOGIC_VECTOR ( 3 DOWNTO 0);-- SEÑAL DEL COLOR ROJO
G : OUT STD_LOGIC_VECTOR (3 DOWNTO 0);-- SEÑAL DEL COLOR VERDE
B : OUT STD_LOGIC_VECTOR ( 3 DOWNTO 0);-- SEÑAL DEL COLOR AZUL
VS : OUT STD_LOGIC; -- SINCRONISMO VERTICAL
HS : out STD_LOGIC; --SINCRONISMO HORIZONTAL
RESET : IN STD_LOGIC; -- SALIDA DEL RESET
CLK : IN STD_LOGIC; -- RELOJ INTERNO
S : IN STD_LOGIC_VECTOR (1 DOWNTO 0)); -- SELECTOR DE SEÑAL
END VGA;
ARCHITECTURE VIDEO OF VGA IS
BEGIN
-- SEÑALES DE SINCRONISMO
PROCESS (CLK, RESET)
VARIABLE PIX : INTEGER := 0;-- CONTADOR DE PIXELES
VARIABLE LIN : INTEGER := 0;-- CONTADOR DE LINEAS
VARIABLE DESP_P : INTEGER :=1;-- CONTADOR PARA DESPLEGAR UN PIXEL(divisor de frecuencia a 25MHz)
VARIABLE PT_R : STD_LOGIC_VECTOR (3 DOWNTO 0):="0000"; -- VARIABLE INTERNA DE ROJO
VARIABLE PT_V : STD_LOGIC_VECTOR (3 DOWNTO 0):="0000"; -- VARIABLE INTERNA DE VERDE
VARIABLE PT_A : STD_LOGIC_VECTOR (3 DOWNTO 0):="0000"; -- VARIABLE INTERNA DE AZUL
BEGIN
--DIVISOR A 25 HHz
IF(RISING_EDGE (CLK))THEN
DESP_P := DESP_P-1;
IF (RESET = '1')THEN
DESP_P :=1;
R <= "0000";
G <= "0000";
B <= "0000";
VS <= '0';
HS <= '0';
END IF;
IF(DESP_P =0)THEN
DESP_P :=2;
CASE S IS
-- PANTALLA BLANCA
WHEN "00" =>
PT_R := "1111" ; PT_V := "1111" ; PT_A := "1111" ;
-- TRES BARRAS HORIZONTALES
WHEN "10" =>
IF LIN >= 0 AND LIN < 159 THEN
PT_R := "1111" ; PT_V := "0000" ; PT_A := "0000" ;
ELSIF LIN >= 159 AND LIN < 319 THEN
PT_R := "0000" ; PT_V := "1111" ; PT_A := "0000" ;
ELSIF LIN >= 319 AND LIN < 479 THEN
PT_R := "0000" ; PT_V := "0000" ; PT_A := "1111" ;
END IF;
-- BARRAS DE COLORES VERTICALES
WHEN "01" =>
IF PIX >= 0 AND PIX < 79 THEN -- BLANCO
PT_R := "1111" ; PT_V := "1111" ; PT_A := "1111" ;
ELSIF PIX >= 79 AND PIX < 159 THEN -- AMARILLO
PT_R := "1111" ; PT_V := "1111" ; PT_A := "0000" ;
ELSIF PIX >= 159 AND PIX < 239 THEN -- CYAN
PT_R := "0000" ; PT_V := "1111" ; PT_A := "1111" ;
ELSIF PIX >= 239 AND PIX < 319 THEN -- VERDE
PT_R := "0000" ; PT_V := "1111" ; PT_A := "0000" ;
ELSIF PIX >= 319 AND PIX < 399 THEN -- MAGENTA
PT_R := "1111" ; PT_V := "0000" ; PT_A := "1111" ;
ELSIF PIX >= 399 AND PIX < 479 THEN -- ROJO
PT_R := "1111" ; PT_V := "0000" ; PT_A := "0000" ;
ELSIF PIX >= 479 AND PIX < 559 THEN -- AZUL
PT_R := "0000" ; PT_V := "0000" ; PT_A := "1111" ;
ELSIF PIX >= 559 AND PIX < 639 THEN -- NEGRO
PT_R := "0000" ; PT_V := "0000" ; PT_A := "0000" ;
END IF;
-- TABLERO DE AJEDREZ
WHEN "11" =>
-- HORIZONTAL
IF PIX >= 0 AND PIX < 79 THEN -- BLANCO
PT_R := "1111" ; PT_V := "1111" ; PT_A := "1111" ;
ELSIF PIX >= 79 AND PIX < 159 THEN -- NEGRO
PT_R := "0000" ; PT_V := "0000" ; PT_A := "0000" ;
ELSIF PIX >= 159 AND PIX < 239 THEN -- BLANCO
PT_R := "1111" ; PT_V := "1111" ; PT_A := "1111" ;
ELSIF PIX >= 239 AND PIX < 319 THEN -- NEGRO
PT_R := "0000" ; PT_V := "0000" ; PT_A := "0000" ;
ELSIF PIX >= 319 AND PIX < 399 THEN -- BLANCO
PT_R := "1111" ; PT_V := "1111" ; PT_A := "1111" ;
ELSIF PIX >= 399 AND PIX < 479 THEN -- NEGRO
PT_R := "0000" ; PT_V := "0000" ; PT_A := "0000" ;
ELSIF PIX >= 479 AND PIX < 559 THEN -- BLANCO
PT_R := "1111" ; PT_V := "1111" ; PT_A := "1111" ;
ELSIF PIX >= 559 AND PIX < 639 THEN -- NEGRO
PT_R := "0000" ; PT_V := "0000" ; PT_A := "0000" ;
END IF;
-- VERTICAL
IF LIN >= 0 AND LIN < 59 THEN -- BLANCO
PT_R := PT_R ; PT_V := PT_V ; PT_A := PT_A;
ELSIF LIN >= 59 AND LIN < 119 THEN -- NEGRO
PT_R := NOT PT_R ; PT_V := NOT PT_V ;PT_A := NOT PT_A ;
ELSIF LIN >= 119 AND LIN < 179 THEN -- BLANCO
PT_R := PT_R ; PT_V := PT_V ; PT_A := PT_A;
ELSIF LIN >= 179 AND LIN < 239 THEN -- NEGRO
PT_R := NOT PT_R ; PT_V := NOT PT_V ;PT_A := NOT PT_A ;
ELSIF LIN >= 239 AND LIN < 299 THEN -- BLANCO
PT_R := PT_R ; PT_V := PT_V ; PT_A := PT_A;
ELSIF LIN >= 299 AND LIN < 359 THEN -- NEGRO
PT_R := NOT PT_R ; PT_V := NOT PT_V ;PT_A := NOT PT_A ;
ELSIF LIN >= 359 AND LIN < 419 THEN -- BLANCO
PT_R := PT_R ; PT_V := PT_V ; PT_A := PT_A;
ELSIF LIN >= 419 AND LIN < 479 THEN -- NEGRO
PT_R := NOT PT_R ; PT_V := NOT PT_V ;PT_A := NOT PT_A ;
END IF;
WHEN OTHERS =>
PT_R := "0000" ; PT_V := "0000" ; PT_A := "0000" ;
END CASE;
-- CUENTA HASTA 800
PIX := PIX+1;
IF PIX = 800 then
LIN := LIN+1;
PIX :=0;
END IF;
-- CUENTA HASTA 521
IF LIN = 521 then
LIN := 0;
END IF;
-- PERIODO DE BORRADO HORIZONTAL
IF PIX >= (640+16) AND PIX < (640+16+96) THEN
HS <= '0';
ELSE
HS <= '1';
END IF;
-- PERIODO DE BORRADO VERTICAL
IF LIN >= (480+10) AND LIN < (480+10+2) THEN
VS <= '0' ;
else
VS <= '1';
END IF ;
-- IGUALACIÓN DE LAS VARIABLES INTERNAS A LAS SALIDAS R, G, B.
IF PIX < 640 AND LIN <480 THEN
R <= PT_R;
G <= PT_V;
B <= PT_A;
ELSE
R <= "0000" ;
G <= "0000" ;
B <= "0000" ;
END IF;
END IF;
END IF;
END PROCESS;
END VIDEO;
Etiquetas:Progrmacion ,C++, Practicas programacion
VHDL
viernes, 12 de junio de 2015
Desplegar Secuencia en Matriz de LEDS - LabView
Etiquetas:Progrmacion ,C++, Practicas programacion
LabView
Convertir Switch a Binario en LabView
Etiquetas:Progrmacion ,C++, Practicas programacion
LabView
sábado, 6 de junio de 2015
Unidad Aritmetica Logica en VHDL - Puerto PS2 (de 4 bits)
Programa main (Principal)
----------------------------------------------------------------------------------
-- Proyecto
-- Diseñar e implementar una unidad central de procesamiento en VHDL.
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
use ieee.std_logic_arith.all;
ENTITY ALU IS
-- PARA EL TECLADO
PORT ( CLK, CLC_E, R: IN STD_LOGIC;
-- TECLADO
PS2_CLOCK : IN STD_LOGIC; --clock signal from PS/2 keyboard
PS2_DATOS : IN STD_LOGIC; --data signal from PS/2 keyboard
-- LCD
OP: IN STD_LOGIC_VECTOR(3 DOWNTO 0);
LCD_E, LCD_RS, LCD_RW : OUT STD_LOGIC;
LCD_DB : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END ALU;
ARCHITECTURE CPU OF ALU IS
-- SEÑALES PARA LA ALU
SIGNAL A, B : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL RES_OP : STD_LOGIC_VECTOR(7 DOWNTO 0);
-- SEÑALES PARA LA LCD
SIGNAL E : STD_LOGIC:= '0';
SIGNAL RS : STD_LOGIC:= '0';
SIGNAL RW : STD_LOGIC:= '0';
SIGNAL DB : STD_LOGIC_VECTOR(7 DOWNTO 0):= "00000000";
-- COMPONENTE TECLADO
COMPONENT TECLADOREAD IS
PORT( CLK : IN STD_LOGIC;
-- TECLADO
ps2_clk : IN STD_LOGIC;
ps2_data : IN STD_LOGIC;
OUT1 : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0);
OUT2 : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0));
END COMPONENT;
-- COMPONENETE ALU
COMPONENT ALUOPS IS
PORT ( IN1 : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
IN2 : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
TIP_OPER : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
RES : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END COMPONENT;
-- COMPONENTE LCD
COMPONENT LCDWRITE IS
PORT( CLOCK : IN STD_LOGIC;
CLOCK_E: IN STD_LOGIC;
RESET : IN STD_LOGIC;
INPUT1 : STD_LOGIC_VECTOR(3 DOWNTO 0);
INPUT2 : STD_LOGIC_VECTOR(3 DOWNTO 0);
OPER : STD_LOGIC_VECTOR(3 DOWNTO 0);
S : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
LC_E : OUT STD_LOGIC;
LC_RS : OUT STD_LOGIC;
LC_RW : OUT STD_LOGIC;
LC_DB : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END COMPONENT;
FOR OPERACIONES_ALU : ALUOPS USE ENTITY WORK.ALUC(OPERACIONES);
FOR DESPLEGAR_LCD : LCDWRITE USE ENTITY WORK.LCD(IMPRIMIR);
FOR LEER_TECLADO : TECLADOREAD USE ENTITY WORK.DECODER(CODIFICACION);
BEGIN
-- LEER TECLADO
LEER_TECLADO : TECLADOREAD
PORT MAP( CLK=>CLK, ps2_clk=>PS2_CLOCK, ps2_data=>PS2_DATOS, OUT1=>A, OUT2=>B);
-- OPERACIONES DE ALU
OPERACIONES_ALU: ALUOPS
PORT MAP(IN1=>A, IN2=>B, TIP_OPER=>OP, RES=>RES_OP);
LCD_E <= E;
LCD_RS <= RS;
LCD_RW <= RW;
LCD_DB <= DB;
-- PANTALLA LCD
DESPLEGAR_LCD : LCDWRITE
PORT MAP(CLOCK=>CLK, CLOCK_E=>CLC_E, RESET=>R, INPUT1=>A, INPUT2=>B, OPER=>OP, S=>RES_OP, LC_E=>E, LC_RS=>RS, LC_RW=>RW, LC_DB=>DB);
END CPU;
-- Proyecto
-- Diseñar e implementar una unidad central de procesamiento en VHDL.
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
use ieee.std_logic_arith.all;
ENTITY ALU IS
-- PARA EL TECLADO
PORT ( CLK, CLC_E, R: IN STD_LOGIC;
-- TECLADO
PS2_CLOCK : IN STD_LOGIC; --clock signal from PS/2 keyboard
PS2_DATOS : IN STD_LOGIC; --data signal from PS/2 keyboard
-- LCD
OP: IN STD_LOGIC_VECTOR(3 DOWNTO 0);
LCD_E, LCD_RS, LCD_RW : OUT STD_LOGIC;
LCD_DB : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END ALU;
ARCHITECTURE CPU OF ALU IS
-- SEÑALES PARA LA ALU
SIGNAL A, B : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL RES_OP : STD_LOGIC_VECTOR(7 DOWNTO 0);
-- SEÑALES PARA LA LCD
SIGNAL E : STD_LOGIC:= '0';
SIGNAL RS : STD_LOGIC:= '0';
SIGNAL RW : STD_LOGIC:= '0';
SIGNAL DB : STD_LOGIC_VECTOR(7 DOWNTO 0):= "00000000";
-- COMPONENTE TECLADO
COMPONENT TECLADOREAD IS
PORT( CLK : IN STD_LOGIC;
-- TECLADO
ps2_clk : IN STD_LOGIC;
ps2_data : IN STD_LOGIC;
OUT1 : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0);
OUT2 : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0));
END COMPONENT;
-- COMPONENETE ALU
COMPONENT ALUOPS IS
PORT ( IN1 : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
IN2 : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
TIP_OPER : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
RES : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END COMPONENT;
-- COMPONENTE LCD
COMPONENT LCDWRITE IS
PORT( CLOCK : IN STD_LOGIC;
CLOCK_E: IN STD_LOGIC;
RESET : IN STD_LOGIC;
INPUT1 : STD_LOGIC_VECTOR(3 DOWNTO 0);
INPUT2 : STD_LOGIC_VECTOR(3 DOWNTO 0);
OPER : STD_LOGIC_VECTOR(3 DOWNTO 0);
S : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
LC_E : OUT STD_LOGIC;
LC_RS : OUT STD_LOGIC;
LC_RW : OUT STD_LOGIC;
LC_DB : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END COMPONENT;
FOR OPERACIONES_ALU : ALUOPS USE ENTITY WORK.ALUC(OPERACIONES);
FOR DESPLEGAR_LCD : LCDWRITE USE ENTITY WORK.LCD(IMPRIMIR);
FOR LEER_TECLADO : TECLADOREAD USE ENTITY WORK.DECODER(CODIFICACION);
BEGIN
-- LEER TECLADO
LEER_TECLADO : TECLADOREAD
PORT MAP( CLK=>CLK, ps2_clk=>PS2_CLOCK, ps2_data=>PS2_DATOS, OUT1=>A, OUT2=>B);
-- OPERACIONES DE ALU
OPERACIONES_ALU: ALUOPS
PORT MAP(IN1=>A, IN2=>B, TIP_OPER=>OP, RES=>RES_OP);
LCD_E <= E;
LCD_RS <= RS;
LCD_RW <= RW;
LCD_DB <= DB;
-- PANTALLA LCD
DESPLEGAR_LCD : LCDWRITE
PORT MAP(CLOCK=>CLK, CLOCK_E=>CLC_E, RESET=>R, INPUT1=>A, INPUT2=>B, OPER=>OP, S=>RES_OP, LC_E=>E, LC_RS=>RS, LC_RW=>RW, LC_DB=>DB);
END CPU;
Operaciones de la ALU
----------------------------------------------------------------------------------
-- OPERACIONES DE LA ALU
----------------------------------------------------------------------------------
library IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.NUMERIC_STD.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
entity ALUC is
Port ( IN1, IN2, TIP_OPER : in STD_LOGIC_VECTOR(3 DOWNTO 0);
RES : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
end ALUC;
architecture OPERACIONES of ALUC is
-- SEÑALES DE LA ALU
signal EA : std_logic_vector(7 downto 0):="00000000";
signal EB : std_logic_vector(7 downto 0):="00000000";
signal S : std_logic_vector(7 downto 0):="00000000";
begin
-- ALU
EA <= "0000" & IN1;
EB <= "0000" & IN2;
PROCESS(TIP_OPER, EB, EA)
BEGIN
IF(TIP_OPER= "0000") THEN
S<=EA+EB; -- SUMA
ELSIF (TIP_OPER= "0001")THEN
S<=EA-EB; -- RESTA
ELSIF(TIP_OPER="0010") THEN
S<=EA*EB; -- MULTIPLICACION
ELSIF(TIP_OPER="0011") THEN -- DIVICION
IF ((EA = "1111" and (EB = "1111" or EB = "1110" or EB = "1101" or EB = "1100" or EB = "1011" or EB = "1010" or EB = "1001" or EB = "1000"))
or (EA = "1110" and (EB = "1110" or EB = "1101" or EB = "1100" or EB = "1011" or EB = "1010" or EB = "1001" or EB = "1000"))
or (EA = "1101" and (EB = "1101" or EB = "1100" or EB = "1011" or EB = "1010" or EB = "1001" or EB = "1000" or EB = "0111"))
or (EA = "1100" and (EB = "1100" or EB = "1011" or EB = "1010" or EB = "1001" or EB = "1000" or EB = "0111"))
or (EA = "1011" and (EB = "1011" or EB = "1010" or EB = "1001" or EB = "1000" or EB = "0111" or EB = "0110"))
or (EA = "1010" and (EB = "1010" or EB = "1001" or EB = "1000" or EB = "0111" or EB = "0110"))
or (EA = "1001" and (EB = "1000" or EB = "0111" or EB = "0110" or EB = "0101"))
or (EA = "1000" and (EB = "0111" or EB = "0110" or EB = "0101"))
or (EA = "0111" and (EB = "0110" or EB = "0101" or EB = "0100"))
or (EA = "0110" and (EB = "0101" or EB = "0100"))
or (EA = "0101" and (EB = "0100" or EB = "0011"))
or (EA = "0100" and EB = "0011") or (EA = "0011" and EB = "0010")) THEN
S <="00000001";
elsif ((EA = "1111" and (EB = "0111" or EB = "0110" or EB = "0101"))
or (EA = "1110" and (EB = "1101" or EB = "0111" or EB = "0110" or EB = "0101"))
or (EA = "1101" and (EB = "0110" or EB = "0101" or EB = "0100"))
or (EA = "1100" and (EB = "0110" or EB = "0101"))
or (EA = "1011" and (EB = "0101" or EB = "0100"))
or (EA = "1010" and (EB = "0101" or EB = "0100"))
or (EA = "1001" and EB = "0100")
or (EA = "1000" and (EB = "0100" or EB = "0011"))
or (EA = "0111" and EB = "0011")
or (EA = "0110" and EB = "0011")
or (EA = "0101" and EB = "0010")
or (EA = "0100" and EB = "0010")) then
S <= "00000010";
elsif ((EA = "1111" and (EB = "0101" or EB = "0100"))
or (EA = "1110" and EB = "0100")
or (EA = "1101" and EB = "0100")
or (EA = "1100" and EB = "0100")
or (EA = "1011" and EB = "0011")
or (EA = "1010" and EB = "0011")
or (EA = "1001" and EB = "0011")
or (EA = "0111" and EB = "0010")
or (EA = "0110" and EB = "0010"))then
S <= "00000011";
elsif ((EB = "0010" and (EA = "1001" or EA = "1000"))) then
S <= "00000100";
elsif ((EA = "1111" and EB = "0011")
or (EA = "1010" and EB = "0010")) then
S<= "00000101";
elsif(EA < EB or EA = "0000" or EB = "0000") then
S <= "00000000";
elsif(EA = EB) then
S <= "00000001";
elsif(EB = "0001") then
S(7 downto 0) <= EA;
else
S<="00000000";
END IF;
ELSIF(TIP_OPER="0100") THEN -- COMPLEMENTO A2
S<=("0001" & NOT(std_logic_vector(unsigned(EA(3 downto 0)))));
ELSIF(TIP_OPER="0101") THEN
S<=("0" & std_logic_vector(unsigned(EA(3 downto 0)) rol to_integer(unsigned(EB)))) and "01111"; -- ROTAR A LA IZQUIERDA
elsif (TIP_OPER="0110") then
S<=("0" & std_logic_vector(unsigned(EA(3 downto 0)) ror to_integer(unsigned(EB)))) and "01111"; -- ROTAR A LA DERECHA
elsif (TIP_OPER="0111") then
S<=(EA and EB); -- AND
elsif (TIP_OPER="1000") then
S<=NOT(EA AND EB); -- NAND
elsif (TIP_OPER="1001") then
S<=(EA or EB); -- OR
ELSE
S<="00000000";
END IF;
RES <= S;
end process;
end OPERACIONES;
--------------------------------------------------------------------------------------------------------------------------
Desplegar en la LCD
----------------------------------------------------------------------------------
-- LCD
----------------------------------------------------------------------------------
liBrAry IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity LCD is
Port ( CLOCK, CLOCK_E, RESET : IN STD_LOGIC;
INPUT1, INPUT2, OPER : STD_LOGIC_VECTOR(3 DOWNTO 0);
S : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
LC_E, LC_RS, LC_RW : OUT STD_LOGIC;
LC_DB : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
end LCD;
Architecture IMPRIMIR of LCD is
-- SEÑALES DE LA LCD
SIGNAL E : STD_LOGIC:= '0';
SIGNAL RS : STD_LOGIC:= '0';
SIGNAL RW : STD_LOGIC:= '0';
SIGNAL DB : STD_LOGIC_VECTOR(7 DOWNTO 0):= "00000000";
Begin
-- PANTALLA LCD
LC_E <= E;
LC_RS <= RS;
LC_RW <= RW;
LC_DB <= DB;
PROCESS (RESET, CLOCK)
VARIABLE COUNTER : INTEGER := 0;
VARIABLE AUX : INTEGER := 0;
VARIABLE ACT_STEP : INTEGER := 0;
VARIABLE NEXT_STEP : INTEGER := 0;
BEGIN
IF (RESET='1') THEN
COUNTER:=0;
ELSE
IF (RISING_EDGE(CLOCK) AND CLOCK_E='0') THEN
COUNTER := COUNTER + 1;
IF (COUNTER >= AUX) THEN
ACT_STEP := NEXT_STEP;
NEXT_STEP := ACT_STEP + 1;
CASE ACT_STEP IS
-- IniciAlizAcion 1
WHEN 0 => E <= '0';
AUX := 750000;
WHEN 1 => DB <= "00111111";
E <= '1'; AUX := 12;
WHEN 2 => E <= '0';
AUX := 205000;
WHEN 3 => DB <= "00111111";
E <= '1'; AUX := 12;
WHEN 4 => E <= '0';
AUX := 5000;
WHEN 5 => DB <= "00111111";
E <= '1'; AUX := 12;
WHEN 6 => E <= '0';
AUX := 2000;
WHEN 7 => DB <= "00101111";
E <= '1';
AUX := 12;
WHEN 8 =>
E <= '0';
AUX := 2000;
-- IniciAlizAcion 2
-- Function Set con DL 8 Bits
WHEN 9 => E <= '1';
RS <= '0';
RW <= '0';
DB <= "00111111";
AUX := 12;
WHEN 10 => E <= '0';
AUX := 50;
WHEN 11 => E <= '1';
RS <= '0';
RW <= '0';
DB <= "10001111";
AUX := 12;
WHEN 12 => E <= '0';
AUX := 2000;
-- ENTRY MODE
WHEN 13 => E <= '1';
RS <= '0';
RW <= '0';
DB <= "00000110";
AUX := 12;
WHEN 14 => E <= '0';
AUX := 2000;
-- DisplAy On/Off
WHEN 15 => E <= '1';
RS <= '0';
RW <= '0';
DB <= "00001100";
AUX := 12;
WHEN 16 => E <= '0';
AUX := 2000;
-- CleAr DisplAy
WHEN 17 => E <= '1';
RS <= '0';
RW <= '0';
DB <= "00000001";
AUX := 12;
WHEN 18 => E <= '0';
AUX := 82000;
-- EscriBir texto
-- Set DD RAM Address (0x02)
WHEN 19 => E <= '1';
RS <= '0';
RW <= '0';
DB <= "10000010";
AUX := 12;
WHEN 20 => E <= '0';
AUX := 2000;
-- EscriBir
WHEN 21 => E <= '1';
RS <= '1';
RW <= '0';
IF(INPUT1="0000") THEN
DB <= "00110000";
ELSIF(INPUT1="0001") THEN
DB <="00110001";
ELSIF(INPUT1="0010") THEN
DB <="00110010";
ELSIF(INPUT1="0011") THEN
DB <="00110011";
ELSIF(INPUT1="0100") THEN
DB <="00110100";
ELSIF(INPUT1="0101") THEN
DB <="00110101";
ELSIF(INPUT1="0110") THEN
DB <="00110110";
ELSIF(INPUT1="0111") THEN
DB <="00110111";
ELSIF(INPUT1="1000") THEN
DB <="00111000";
ELSIF(INPUT1="1001") THEN
DB <="00111001";
ELSIF(INPUT1="1010" OR INPUT1="1011" OR INPUT1="1100" OR INPUT1="1101" OR INPUT1="1110" OR INPUT1="1111")THEN
DB <="00110001";
ELSE
DB <="00110000";
END IF;
AUX := 12;
WHEN 22 => E <= '0';
AUX := 2000;
-- Set DD RAM Address (0x03)
WHEN 23 => E <= '1';
RS <= '0';
RW <= '0';
DB <= "10000011";
AUX := 12;
WHEN 24 => E <= '0';
AUX := 2000;
WHEN 25 => E <= '1';
RS <= '1';
RW <= '0';
IF(INPUT1="1010") THEN
DB <="00110000";
ELSIF(INPUT1="1011") THEN
DB <="00110001";
ELSIF(INPUT1="1100") THEN
DB <="00110010";
ELSIF(INPUT1="1101") THEN
DB <="00110011";
ELSIF(INPUT1="1110") THEN
DB <="00110100";
ELSIF(INPUT1="1111") THEN
DB <="00110101";
ELSE
DB <="10100000";
END IF;
AUX := 12;
WHEN 26 => E <= '0';
AUX := 2000;
-- Set DD RAM Address (0x05)
WHEN 27 => E <= '1';
RS <= '0';
RW <= '0';
DB <= "10000101";
AUX := 12;
WHEN 28 => E <= '0';
AUX := 2000;
WHEN 29 => E <= '1';
RS <= '1';
RW <= '0';
IF(OPER="0000") THEN
DB <="00101011";
ELSIF(OPER="0001") THEN
DB <="00101101";
ELSIF(OPER="0010") THEN
DB <="00101010";
ELSIF(OPER="0011") THEN
DB <="00101111";
ELSIF(OPER="0100") THEN
DB <="00100010";
ELSIF(OPER="0101") THEN
DB <="01111111";
ELSIF(OPER="0110") THEN
DB <="01111110";
ELSIF(OPER="0111") THEN
DB <="01100001";
ELSIF(OPER="1000") THEN
DB <="01101110";
ELSIF(OPER="1001") THEN
DB <="01101111";
ELSE
DB <="10100000";
END IF;
AUX := 12;
WHEN 30 => E <= '0';
AUX := 2000;
-- Set DD RAM Address (0x07)
WHEN 31 => E <= '1';
RS <= '0';
RW <= '0';
DB <= "10000111";
AUX := 12;
WHEN 32 => E <= '0';
AUX := 2000;
WHEN 33 => E <= '1';
RS <= '1';
RW <= '0';
IF(INPUT2="0000") THEN
DB <= "00110000";
ELSIF(INPUT2="0001") THEN
DB <="00110001";
ELSIF(INPUT2="0010") THEN
DB <="00110010";
ELSIF(INPUT2="0011") THEN
DB <="00110011";
ELSIF(INPUT2="0100") THEN
DB <="00110100";
ELSIF(INPUT2="0101") THEN
DB <="00110101";
ELSIF(INPUT2="0110") THEN
DB <="00110110";
ELSIF(INPUT2="0111") THEN
DB <="00110111";
ELSIF(INPUT2="1000") THEN
DB <="00111000";
ELSIF(INPUT2="1001") THEN
DB <="00111001";
ELSIF(INPUT2="1010" OR INPUT2="1011" OR INPUT2="1100" OR INPUT2="1101" OR INPUT2="1110" OR INPUT2="1111")THEN
DB <="00110001";
ELSIF(OPER="0100")THEN
DB <="10100000";
ELSE
DB <="00110000";
END IF;
AUX := 12;
WHEN 34 => E <= '0';
AUX := 2000;
-- Set DD RAM Address (0x08)
WHEN 35 => E <= '1';
RS <= '0';
RW <= '0';
DB <= "10001000";
AUX := 12;
WHEN 36 => E <= '0';
AUX := 2000;
WHEN 37=> E <= '1';
RS <= '1';
RW <= '0';
IF(INPUT2="1010") THEN
DB <="00110000";
ELSIF(INPUT2="1011") THEN
DB <="00110001";
ELSIF(INPUT2="1100") THEN
DB <="00110010";
ELSIF(INPUT2="1101") THEN
DB <="00110011";
ELSIF(INPUT2="1110") THEN
DB <="00110100";
ELSIF(INPUT2="1111") THEN
DB <="00110101";
ELSE
DB <="10100000";
END IF;
AUX := 12;
WHEN 38 => E <= '0';
AUX := 2000;
-- Set DD RAM Address (0x10)
WHEN 39 => E <= '1';
RS <= '0';
RW <= '0';
DB <= "10001010";
AUX := 12;
WHEN 40 => E <= '0';
AUX := 2000;
WHEN 41 => E <= '1';
RS <= '1';
RW <= '0';
DB <="00111101";
AUX := 12;
WHEN 42 => E <= '0';
AUX := 2000;
-- Set DD RAM Address (0x12)
WHEN 43 => E <= '1';
RS <= '0';
RW <= '0';
DB <= "10001100";
AUX := 12;
WHEN 44 => E <= '0';
AUX := 2000;
WHEN 45 => E<= '1';
RS <= '1';
RW <= '0';
IF(S="00000000") THEN
DB <= "00110000";
ELSIF(S="00000001"
OR S="00001010"
OR S="00001011"
OR S="00001100"
OR S="00001101"
OR S="00001110"
OR S="00001111"
OR S ="00001010"
OR S = "00001011"
OR S = "00001100"
OR S = "00001101"
OR S = "00001110"
OR S = "00001111"
OR S = "00010000"
OR S = "00010001"
OR S = "00010010"
OR S = "00010011"
OR S = "01100100"
OR S = "01100101"
OR S = "01100110"
OR S = "01100111"
OR S = "01101000"
OR S = "01101001"
OR S = "01101010"
OR S = "01101011"
OR S = "01101100"
OR S = "01101101"
OR S = "01101110"
OR S = "01101111"
OR S = "01110000"
OR S = "01110001"
OR S = "01110010"
OR S = "01110011"
OR S = "01110100"
OR S = "01110101"
OR S = "01110110"
OR S = "01110111"
OR S = "01111000"
OR S = "01111001"
OR S = "01111010"
OR S = "01111011"
OR S = "01111100"
OR S = "01111101"
OR S = "01111110"
OR S = "01111111"
OR S = "10000000"
OR S = "10000001"
OR S = "10000010"
OR S = "10000011"
OR S = "10000100"
OR S = "10000101"
OR S = "10000110"
OR S = "10000111"
OR S = "10001000"
OR S = "10001001"
OR S = "10001010"
OR S = "10001011"
OR S = "10001100"
OR S = "10001101"
OR S = "10001110"
OR S = "10001111"
OR S = "10010000"
OR S = "10010001"
OR S = "10010010"
OR S = "10010011"
OR S = "10010100"
OR S = "10010101"
OR S = "10010110"
OR S = "10010111"
OR S = "10011000"
OR S = "10011001"
OR S = "10011010"
OR S = "10011011"
OR S = "10011100"
OR S = "10011101"
OR S = "10011110"
OR S = "10011111"
OR S = "10100000"
OR S = "10100001"
OR S = "10100010"
OR S = "10100011"
OR S = "10100100"
OR S = "10100101"
OR S = "10100110"
OR S = "10100111"
OR S = "10101000"
OR S = "10101001"
OR S = "10101010"
OR S = "10101011"
OR S = "10101100"
OR S = "10101101"
OR S = "10101110"
OR S = "10101111"
OR S = "10110000"
OR S = "10110001"
OR S = "10110010"
OR S = "10110011"
OR S = "10110100"
OR S = "10110101"
OR S = "10110110"
OR S = "10110111"
OR S = "10111000"
OR S = "10111001"
OR S = "10111010"
OR S = "10111011"
OR S = "10111100"
OR S = "10111101"
OR S = "10111110"
OR S = "10111111"
OR S = "11000000"
OR S = "11000001"
OR S = "11000010"
OR S = "11000011"
OR S = "11000100"
OR S = "11000101"
OR S = "11000110"
OR S = "11000111") THEN
DB <="00110001";
ELSIF(S="00000010"
OR S = "00010100"
OR S = "00010101"
OR S = "00010110"
OR S = "00010111"
OR S = "00011000"
OR S = "00011001"
OR S = "00011010"
OR S = "00011011"
OR S = "00011100"
OR S = "00011101"
OR S = "11001000"
OR S = "11001001"
OR S = "11001010"
OR S = "11001011"
OR S = "11001100"
OR S = "11001101"
OR S = "11001110"
OR S = "11001111"
OR S = "11010000"
OR S = "11010001"
OR S = "11010010"
OR S = "11010011"
OR S = "11010100"
OR S = "11010101"
OR S = "11010110"
OR S = "11010111"
OR S = "11011000"
OR S = "11011001"
OR S = "11011010"
OR S = "11011011"
OR S = "11011100"
OR S = "11011101"
OR S = "11011110"
OR S = "11011111"
OR S = "11100000"
OR S = "11100001") THEN
DB <="00110010";
ELSIF(S="00000011"
OR S = "00011110"
OR S = "00011111"
OR S = "00100000"
OR S = "00100001"
OR S = "00100010"
OR S = "00100011"
OR S = "00100100"
OR S = "00100101"
OR S = "00100110"
OR S = "00100111") THEN
DB <="00110011";
ELSIF(S="00000100"
OR S = "00101000"
OR S = "00101001"
OR S = "00101010"
OR S = "00101011"
OR S = "00101100"
OR S = "00101101"
OR S = "00101110"
OR S = "00101111"
OR S = "00110000"
OR S = "00110001") THEN
DB <="00110100";
ELSIF(S="00000101"
OR S = "00110010"
OR S = "00110011"
OR S = "00110100"
OR S = "00110101"
OR S = "00110110"
OR S = "00110111"
OR S = "00111000"
OR S = "00111001"
OR S = "00111010"
OR S = "00111011") THEN
DB <="00110101";
ELSIF(S="00000110"
OR S = "00111100"
OR S = "00111101"
OR S = "00111110"
OR S = "00111111"
OR S = "01000000"
OR S = "01000001"
OR S = "01000010"
OR S = "01000011"
OR S = "01000100"
OR S = "01000101") THEN
DB <="00110110";
ELSIF(S="00000111"
OR S = "00111100"
OR S = "00111101"
OR S = "00111110"
OR S = "00111111"
OR S = "01000000"
OR S = "01000001"
OR S = "01000010"
OR S = "01000011"
OR S = "01000100"
OR S = "01000101") THEN
DB <="00110111";
ELSIF(S="00001000"
OR S = "01010000"
OR S = "01010001"
OR S = "01010010"
OR S = "01010011"
OR S = "01010100"
OR S = "01010101"
OR S = "01010110"
OR S = "01010111"
OR S = "01011000"
OR S = "01011001") THEN
DB <="00111000";
ELSIF(S="00001001"
OR S = "01011010"
OR S = "01011011"
OR S = "01011100"
OR S = "01011101"
OR S = "01011110"
OR S = "01011111"
OR S = "01100000"
OR S = "01100001"
OR S = "01100010"
OR S = "01100011") THEN
DB <="00111001";
ELSE
DB <="10100000";
END IF;
WHEN 46 => E <= '0';
AUX := 2000;
-- Set DD RAM Address (0x13)
WHEN 47 => E <= '1';
RS <= '0';
RW <= '0';
DB <= "10001101";
AUX := 12;
WHEN 48 => E <= '0';
AUX := 2000;
WHEN 49 => E<= '1';
RS <= '1';
RW <= '0';
IF( S = "00001010"
OR S = "00010100"
OR S = "00011110"
OR S = "00101000"
OR S = "00110010"
OR S = "00111100"
OR S = "01000110"
OR S = "01010000"
OR S = "01011010"
OR S = "01100100"
OR S = "01100101"
OR S = "01100110"
OR S = "01100111"
OR S = "01101000"
OR S = "01101001"
OR S = "01101010"
OR S = "01101011"
OR S = "01101100"
OR S = "01101101"
OR S = "11001000"
OR S = "11001001"
OR S = "11001010"
OR S = "11001011"
OR S = "11001100"
OR S = "11001101"
OR S = "11001110"
OR S = "11001111"
OR S = "11010000"
OR S = "11010001") THEN
DB <="00110000";
ELSIF( S = "00001011"
OR S = "00010101"
OR S = "00011111"
OR S = "00101001"
OR S = "00110011"
OR S = "00111101"
OR S = "01000111"
OR S = "01010001"
OR S = "01011011"
OR S = "01101110"
OR S = "01101111"
OR S = "01110000"
OR S = "01110001"
OR S = "01110010"
OR S = "01110011"
OR S = "01110100"
OR S = "01110101"
OR S = "01110110"
OR S = "01110111"
OR S = "11010010"
OR S = "11010011"
OR S = "11010100"
OR S = "11010101"
OR S = "11010110"
OR S = "11010111"
OR S = "11011000"
OR S = "11011001"
OR S = "11011010"
OR S = "11011011") THEN
DB <="00110001";
ELSIF( S = "00001100"
OR S = "00010110"
OR S = "00100000"
OR S = "00101010"
OR S = "00110100"
OR S = "00111110"
OR S = "01001000"
OR S = "01010010"
OR S = "01011100"
OR S = "01111000"
OR S = "01111001"
OR S = "01111010"
OR S = "01111011"
OR S = "01111100"
OR S = "01111101"
OR S = "01111110"
OR S = "01111111"
OR S = "10000000"
OR S = "10000001"
OR S = "11011100"
OR S = "11011101"
OR S = "11011110"
OR S = "11011111"
OR S = "11100000"
OR S = "11100001") THEN
DB <="00110010";
ELSIF( S = "00001101"
OR S = "00010111"
OR S = "00100001"
OR S = "00101011"
OR S = "00110101"
OR S = "00111111"
OR S = "01001001"
OR S = "01010011"
OR S = "01011101"
OR S = "10000010"
OR S = "10000011"
OR S = "10000100"
OR S = "10000101"
OR S = "10000110"
OR S = "10000111"
OR S = "10001000"
OR S = "10001001"
OR S = "10001010"
OR S = "10001011") THEN
DB <="00110011";
ELSIF( S = "00001110"
OR S = "00011000"
OR S = "00100010"
OR S = "00101100"
OR S = "00110110"
OR S = "01000000"
OR S = "01001010"
OR S = "01010100"
OR S = "01011110"
OR S = "10001100"
OR S = "10001101"
OR S = "10001110"
OR S = "10001111"
OR S = "10010000"
OR S = "10010001"
OR S = "10010010"
OR S = "10010011"
OR S = "10010100"
OR S = "10010101") THEN
DB <="00110100";
ELSIF( S = "00001111"
OR S = "00011001"
OR S = "00100011"
OR S = "00101101"
OR S = "00110111"
OR S = "01000001"
OR S = "01001011"
OR S = "01010101"
OR S = "01011111"
OR S = "10010110"
OR S = "10010111"
OR S = "10011000"
OR S = "10011001"
OR S = "10011010"
OR S = "10011011"
OR S = "10011100"
OR S = "10011101"
OR S = "10011110"
OR S = "10011111") THEN
DB <="00110101";
ELSIF( S = "00010000"
OR S = "00011010"
OR S = "00100100"
OR S = "00101110"
OR S = "00111000"
OR S = "01000010"
OR S = "01001100"
OR S = "01010110"
OR S = "01100000"
OR S = "10100000"
OR S = "10100001"
OR S = "10100010"
OR S = "10100011"
OR S = "10100100"
OR S = "10100101"
OR S = "10100110"
OR S = "10100111"
OR S = "10101000"
OR S = "10101001") THEN
DB <="00110110";
ELSIF( S = "00010001"
OR S = "00011011"
OR S = "00100101"
OR S = "00101111"
OR S = "00111001"
OR S = "01000011"
OR S = "01001101"
OR S = "01010111"
OR S = "01100001"
OR S = "10101010"
OR S = "10101011"
OR S = "10101100"
OR S = "10101101"
OR S = "10101110"
OR S = "10101111"
OR S = "10110000"
OR S = "10110001"
OR S = "10110010"
OR S = "10110011") THEN
DB <="00110111";
ELSIF( S = "00010010"
OR S = "00011100"
OR S = "00100110"
OR S = "00110000"
OR S = "00111010"
OR S = "01000100"
OR S = "01001110"
OR S = "01011000"
OR S = "01100010"
OR S = "10110100"
OR S = "10110101"
OR S = "10110110"
OR S = "10110111"
OR S = "10111000"
OR S = "10111001"
OR S = "10111010"
OR S = "10111011"
OR S = "10111100"
OR S = "10111101") THEN
DB <="00111000";
ELSIF( S = "00010011"
OR S = "00011101"
OR S = "00100111"
OR S = "00110001"
OR S = "00111011"
OR S = "01000101"
OR S = "01001111"
OR S = "01011001"
OR S = "01100011"
OR S = "10111110"
OR S = "10111111"
OR S = "11000000"
OR S = "11000001"
OR S = "11000010"
OR S = "11000011"
OR S = "11000100"
OR S = "11000101"
OR S = "11000110"
OR S = "11000111") THEN
DB <="00111001";
ELSE
DB <="10100000";
END IF;
WHEN 50 => E <= '0';
AUX := 2000;
-- Set DD RAM Address (0x14)
WHEN 51 => E <= '1';
RS <= '0';
RW <= '0';
DB <= "10001110";
AUX := 12;
WHEN 52 => E <= '0';
AUX := 2000;
WHEN 53 => E<= '1';
RS <= '1';
RW <= '0';
IF( S = "01100100"
OR S = "01101110"
OR S = "01111000"
OR S = "10000010"
OR S = "10001100"
OR S = "10010110"
OR S = "10100000"
OR S = "10101010"
OR S = "10110100"
OR S = "10111110"
OR S = "11001000"
OR S = "11011100") THEN
DB <="00110000";
ELSIF( S = "01100101"
OR S = "01101111"
OR S = "01111001"
OR S = "10000011"
OR S = "10001101"
OR S = "10010111"
OR S = "10100001"
OR S = "10101011"
OR S = "10110101"
OR S = "10111111"
OR S = "11001001"
OR S = "11010011"
OR S = "11011101") THEN
DB <="00110001";
ELSIF( S = "01100110"
OR S = "01110000"
OR S = "01111010"
OR S = "10000100"
OR S = "10001110"
OR S = "10011000"
OR S = "10100010"
OR S = "10101100"
OR S = "10110110"
OR S = "11000000"
OR S = "11000001"
OR S = "11001010"
OR S = "11010100"
OR S = "11011110") THEN
DB <="00110010";
ELSIF( S = "01100111"
OR S = "01110001"
OR S = "01111011"
OR S = "10000101"
OR S = "10001111"
OR S = "10011001"
OR S = "10100011"
OR S = "10101101"
OR S = "10110111"
OR S = "11000001"
OR S = "11001011"
OR S = "11010101"
OR S = "11011111") THEN
DB <="00110011";
ELSIF( S = "01101000"
OR S = "01110010"
OR S = "01111100"
OR S = "10000110"
OR S = "10010000"
OR S = "10011010"
OR S = "10100100"
OR S = "10101110"
OR S = "10111000"
OR S = "11000010"
OR S = "11001100"
OR S = "11010110"
OR S = "11100000") THEN
DB <="00110100";
ELSIF( S = "01101001"
OR S = "01110011"
OR S = "01111101"
OR S = "10000111"
OR S = "10010001"
OR S = "10011011"
OR S = "10100101"
OR S = "10101111"
OR S = "10111001"
OR S = "11000011"
OR S = "11001101"
OR S = "11010111"
OR S = "11100001") THEN
DB <="00110101";
ELSIF( S = "01101010"
OR S = "01110100"
OR S = "01111110"
OR S = "10001000"
OR S = "10010010"
OR S = "10011100"
OR S = "10100110"
OR S = "10110000"
OR S = "10111010"
OR S = "11000100"
OR S = "11001110"
OR S = "11011000") THEN
DB <="00110110";
ELSIF( S = "01101011"
OR S = "01110101"
OR S = "01111111"
OR S = "10001001"
OR S = "10010011"
OR S = "10011101"
OR S = "10100111"
OR S = "10110001"
OR S = "10111011"
OR S = "11000101"
OR S = "11001111"
OR S = "11011001") THEN
DB <="00110111";
ELSIF(S = "01101100"
OR S = "01110110"
OR S = "10000000"
OR S = "10001010"
OR S = "10010100"
OR S = "10011110"
OR S = "10101000"
OR S = "10110010"
OR S = "10111100"
OR S = "11000110"
OR S = "11010000"
OR S = "11011010") THEN
DB <="00111000";
ELSIF( S = "01101101"
OR S = "01110111"
OR S = "10000001"
OR S = "10001011"
OR S = "10010101"
OR S = "10011111"
OR S = "10101001"
OR S = "10110011"
OR S = "10111101"
OR S = "11000111"
OR S = "11010001"
OR S = "11010010"
OR S = "11011011") THEN
DB <="00111001";
ELSE
DB <="10100000";
END IF;
WHEN 54 => E <= '0';
AUX := 2000;
WHEN OTHERS => NEXT_STEP := 19; AUX := 0;
END CASE;
COUNTER := 0;
END IF;
END IF;
END IF;
END PROCESS;
end IMPRIMIR;
--------------------------------------------------------------------------------------------------------------------------
Lectura de puerto PS2 (VERSIÓN DE PRUEBA)
- DECODIFICADOR
----------------------------------------------------------------------------------
-- DECODIFICADOR
----------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY DECODER IS
GENERIC(
clk_freq : INTEGER := 50_000_000; --system clock frequency in Hz
ps2_debounce_counter_size : INTEGER := 8); --set such that 2^size/clk_freq = 5us (size = 8 for 50MHz)
PORT(
CLK : IN STD_LOGIC; --system clock input
ps2_clk : IN STD_LOGIC; --clock signal from PS2 keyboard
ps2_data : IN STD_LOGIC; --data signal from PS2 keyboard
OUT1 : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0);
OUT2 : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0));
END DECODER;
ARCHITECTURE CODIFICACION OF DECODER IS
TYPE STATES IS(S0, S1, S2, S3, S4, S5);
SIGNAL ED_ACT, ED_SIG : STATES;
TYPE machine IS(ready, new_code, translate, output); --needed states
SIGNAL state : machine; --state machine
SIGNAL ps2_code_new : STD_LOGIC; --new PS2 code flag from ps2_keyboard component
SIGNAL ps2_code : STD_LOGIC_VECTOR(7 DOWNTO 0); --PS2 code input form ps2_keyboard component
SIGNAL prev_ps2_code_new : STD_LOGIC := '1'; --value of ps2_code_new flag on previous clock
SIGNAL break : STD_LOGIC := '0'; --'1' for break code, '0' for make code
SIGNAL e0_code : STD_LOGIC := '0'; --'1' for multi-code commands, '0' for single code commands
SIGNAL caps_lock : STD_LOGIC := '0'; --'1' if caps lock is active, '0' if caps lock is inactive
SIGNAL control_r : STD_LOGIC := '0'; --'1' if right control key is held down, else '0'
SIGNAL control_l : STD_LOGIC := '0'; --'1' if left control key is held down, else '0'
SIGNAL shift_r : STD_LOGIC := '0'; --'1' if right shift is held down, else '0'
SIGNAL shift_l : STD_LOGIC := '0'; --'1' if left shift is held down, else '0'
SIGNAL ascii : STD_LOGIC_VECTOR(7 DOWNTO 0) := x"FF"; --internal value of ASCII translation
SIGNAL ascii_new : STD_LOGIC; --output flag indicating new ASCII value
SIGNAL ascii_code : STD_LOGIC_VECTOR(6 DOWNTO 0); --ASCII value
SIGNAL BIN : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL BINREG : STD_LOGIC_VECTOR(7 DOWNTO 0);
--declare PS2 keyboard interface component
COMPONENT ps2_keyboard IS
GENERIC(
clk_freq : INTEGER; --system clock frequency in Hz
debounce_counter_size : INTEGER); --set such that 2^size/clk_freq = 5us (size = 8 for 50MHz)
PORT(
clk : IN STD_LOGIC; --system clock
ps2_clk : IN STD_LOGIC; --clock signal from PS2 keyboard
ps2_data : IN STD_LOGIC; --data signal from PS2 keyboard
ps2_code_new : OUT STD_LOGIC; --flag that new PS/2 code is available on ps2_code bus
ps2_code : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); --code received from PS/2
END COMPONENT;
BEGIN
--instantiate PS2 keyboard interface logic
ps2_keyboard_0: ps2_keyboard
GENERIC MAP(clk_freq => clk_freq, debounce_counter_size => ps2_debounce_counter_size)
PORT MAP(clk => clk, ps2_clk => ps2_clk, ps2_data => ps2_data, ps2_code_new => ps2_code_new, ps2_code => ps2_code);
PROCESS(clk)
BEGIN
IF(clk'EVENT AND clk = '1') THEN
prev_ps2_code_new <= ps2_code_new; --keep track of previous ps2_code_new values to determine low-to-high transitions
CASE state IS
--ready state: wait for a new PS2 code to be received
WHEN ready =>
IF(prev_ps2_code_new = '0' AND ps2_code_new = '1') THEN --new PS2 code received
ascii_new <= '0'; --reset new ASCII code indicator
state <= new_code; --proceed to new_code state
ELSE --no new PS2 code received yet
state <= ready; --remain in ready state
END IF;
--new_code state: determine what to do with the new PS2 code
WHEN new_code =>
IF(ps2_code = x"F0") THEN --code indicates that next command is break
break <= '1'; --set break flag
state <= ready; --return to ready state to await next PS2 code
ELSIF(ps2_code = x"E0") THEN --code indicates multi-key command
e0_code <= '1'; --set multi-code command flag
state <= ready; --return to ready state to await next PS2 code
ELSE --code is the last PS2 code in the make/break code
ascii(7) <= '1'; --set internal ascii value to unsupported code (for verification)
state <= translate; --proceed to translate state
END IF;
--translate state: translate PS2 code to ASCII value
WHEN translate =>
break <= '0'; --reset break flag
e0_code <= '0'; --reset multi-code command flag
--handle codes for control, shift, and caps lock
CASE ps2_code IS
WHEN x"58" => --caps lock code
IF(break = '0') THEN --if make command
caps_lock <= NOT caps_lock; --toggle caps lock
END IF;
WHEN x"14" => --code for the control keys
IF(e0_code = '1') THEN --code for right control
control_r <= NOT break; --update right control flag
ELSE --code for left control
control_l <= NOT break; --update left control flag
END IF;
WHEN x"12" => --left shift code
shift_l <= NOT break; --update left shift flag
WHEN x"59" => --right shift code
shift_r <= NOT break; --update right shift flag
WHEN OTHERS => NULL;
END CASE;
--translate control codes (these do not depend on shift or caps lock)
IF(control_l = '1' OR control_r = '1') THEN
CASE ps2_code IS
WHEN x"1E" => ascii <= x"00"; BIN <= "00011110"; --^@ NUL
WHEN x"1C" => ascii <= x"01"; BIN <= "00011100"; --^A SOH
WHEN x"32" => ascii <= x"02"; BIN <= "00110010"; --^B STX
WHEN x"21" => ascii <= x"03"; BIN <= "00100001"; --^C ETX
WHEN x"23" => ascii <= x"04"; BIN <= "00100011"; --^D EOT
WHEN x"24" => ascii <= x"05"; BIN <= "00100100"; --^E ENQ
WHEN x"2B" => ascii <= x"06"; BIN <= "00101011"; --^F ACK
WHEN x"34" => ascii <= x"07"; BIN <= "00110100"; --^G BEL
WHEN x"33" => ascii <= x"08"; BIN <= "00110011"; --^H BS
WHEN x"43" => ascii <= x"09"; BIN <= "01000011"; --^I HT
WHEN x"3B" => ascii <= x"0A"; BIN <= "00111011"; --^J LF
WHEN x"42" => ascii <= x"0B"; BIN <= "01000010"; --^K VT
WHEN x"4B" => ascii <= x"0C"; BIN <= "01001011"; --^L FF
WHEN x"3A" => ascii <= x"0D"; BIN <= "00111010"; --^M CR
WHEN x"31" => ascii <= x"0E"; BIN <= "00110001"; --^N SO
WHEN x"44" => ascii <= x"0F"; BIN <= "01000100"; --^O SI
WHEN x"4D" => ascii <= x"10"; BIN <= "01001101"; --^P DLE
WHEN x"15" => ascii <= x"11"; BIN <= "00010101"; --^Q DC1
WHEN x"2D" => ascii <= x"12"; BIN <= "00101101"; --^R DC2
WHEN x"1B" => ascii <= x"13"; BIN <= "00011011"; --^S DC3
WHEN x"2C" => ascii <= x"14"; BIN <= "00101100"; --^T DC4
WHEN x"3C" => ascii <= x"15"; BIN <= "00111100"; --^U NAK
WHEN x"2A" => ascii <= x"16"; BIN <= "00101010"; --^V SYN
WHEN x"1D" => ascii <= x"17"; BIN <= "00011101"; --^W ETB
WHEN x"22" => ascii <= x"18"; BIN <= "00100010"; --^X CAN
WHEN x"35" => ascii <= x"19"; BIN <= "00110101"; --^Y EM
WHEN x"1A" => ascii <= x"1A"; BIN <= "00011010"; --^Z SUB
WHEN x"54" => ascii <= x"1B"; BIN <= "01010100"; --^[ ESC
WHEN x"5D" => ascii <= x"1C"; BIN <= "01011101"; --^\ FS
WHEN x"5B" => ascii <= x"1D"; BIN <= "01011011"; --^] GS
WHEN x"36" => ascii <= x"1E"; BIN <= "00110110"; --^^ RS
WHEN x"4E" => ascii <= x"1F"; BIN <= "01001110"; --^_ US
WHEN x"4A" => ascii <= x"7F"; BIN <= "01001010"; --^? DEL
WHEN OTHERS => NULL;
END CASE;
ELSE --if control keys are not pressed
--translate characters that do not depend on shift, or caps lock
CASE ps2_code IS
WHEN x"29" => ascii <= x"20"; BIN <= "00101001"; --space
WHEN x"66" => ascii <= x"08"; BIN <= "01100110"; --backspace (BS control code)
WHEN x"0D" => ascii <= x"09"; BIN <= "00001101"; --tab (HT control code)
WHEN x"5A" => ascii <= x"0D"; BIN <= "01011010"; --enter (CR control code)
WHEN x"76" => ascii <= x"1B"; BIN <= "01110110"; --escape (ESC control code)
WHEN x"71" =>
IF(e0_code = '1') THEN --ps2 code for delete is a multi-key code
ascii <= x"7F"; BIN <= "01111111"; --delete
END IF;
WHEN OTHERS => NULL;
END CASE;
--translate letters (these depend on both shift and caps lock)
IF((shift_r = '0' AND shift_l = '0' AND caps_lock = '0') OR
((shift_r = '1' OR shift_l = '1') AND caps_lock = '1')) THEN --letter is lowercase
CASE ps2_code IS
WHEN x"1C" => ascii <= x"61"; BIN <= "00011100"; --a
WHEN x"32" => ascii <= x"62"; BIN <= "00110010"; --b
WHEN x"21" => ascii <= x"63"; BIN <= "00100001"; --c
WHEN x"23" => ascii <= x"64"; BIN <= "00100011"; --d
WHEN x"24" => ascii <= x"65"; BIN <= "00100100"; --e
WHEN x"2B" => ascii <= x"66"; BIN <= "00101011"; --f
WHEN x"34" => ascii <= x"67"; BIN <= "00110100"; --g
WHEN x"33" => ascii <= x"68"; BIN <= "00110011"; --h
WHEN x"43" => ascii <= x"69"; BIN <= "01000011"; --i
WHEN x"3B" => ascii <= x"6A"; BIN <= "00111011"; --j
WHEN x"42" => ascii <= x"6B"; BIN <= "01000010"; --k
WHEN x"4B" => ascii <= x"6C"; BIN <= "01001011"; --l
WHEN x"3A" => ascii <= x"6D"; BIN <= "00111010"; --m
WHEN x"31" => ascii <= x"6E"; BIN <= "00110001"; --n
WHEN x"44" => ascii <= x"6F"; BIN <= "01000100"; --o
WHEN x"4D" => ascii <= x"70"; BIN <= "01001101"; --p
WHEN x"15" => ascii <= x"71"; BIN <= "00010101"; --q
WHEN x"2D" => ascii <= x"72"; BIN <= "00101101"; --r
WHEN x"1B" => ascii <= x"73"; BIN <= "00011011"; --s
WHEN x"2C" => ascii <= x"74"; BIN <= "00101100"; --t
WHEN x"3C" => ascii <= x"75"; BIN <= "00111100"; --u
WHEN x"2A" => ascii <= x"76"; BIN <= "00101010"; --v
WHEN x"1D" => ascii <= x"77"; BIN <= "00011101"; --w
WHEN x"22" => ascii <= x"78"; BIN <= "00100010"; --x
WHEN x"35" => ascii <= x"79"; BIN <= "00110101"; --y
WHEN x"1A" => ascii <= x"7A"; BIN <= "00011010"; --z
WHEN OTHERS => NULL;
END CASE;
ELSE --letter is uppercase
CASE ps2_code IS
WHEN x"1C" => ascii <= x"41"; BIN <= "00011100"; --A
WHEN x"32" => ascii <= x"42"; BIN <= "00110010"; --B
WHEN x"21" => ascii <= x"43"; BIN <= "00100001"; --C
WHEN x"23" => ascii <= x"44"; BIN <= "00100011"; --D
WHEN x"24" => ascii <= x"45"; BIN <= "00100100"; --E
WHEN x"2B" => ascii <= x"46"; BIN <= "00101011"; --F
WHEN x"34" => ascii <= x"47"; BIN <= "00110100"; --G
WHEN x"33" => ascii <= x"48"; BIN <= "00110011"; --H
WHEN x"43" => ascii <= x"49"; BIN <= "01000011"; --I
WHEN x"3B" => ascii <= x"4A"; BIN <= "00111011"; --J
WHEN x"42" => ascii <= x"4B"; BIN <= "01000010"; --K
WHEN x"4B" => ascii <= x"4C"; BIN <= "01001011"; --L
WHEN x"3A" => ascii <= x"4D"; BIN <= "00111010"; --M
WHEN x"31" => ascii <= x"4E"; BIN <= "00110001"; --N
WHEN x"44" => ascii <= x"4F"; BIN <= "01000100"; --O
WHEN x"4D" => ascii <= x"50"; BIN <= "01001101"; --P
WHEN x"15" => ascii <= x"51"; BIN <= "00010101"; --Q
WHEN x"2D" => ascii <= x"52"; BIN <= "00101101"; --R
WHEN x"1B" => ascii <= x"53"; BIN <= "00011011"; --S
WHEN x"2C" => ascii <= x"54"; BIN <= "00101100"; --T
WHEN x"3C" => ascii <= x"55"; BIN <= "00111100"; --U
WHEN x"2A" => ascii <= x"56"; BIN <= "00101010"; --V
WHEN x"1D" => ascii <= x"57"; BIN <= "00011101"; --W
WHEN x"22" => ascii <= x"58"; BIN <= "00100010"; --X
WHEN x"35" => ascii <= x"59"; BIN <= "00110101"; --Y
WHEN x"1A" => ascii <= x"5A"; BIN <= "00011010"; --Z
WHEN OTHERS => NULL;
END CASE;
END IF;
--translate numbers and symbols (these depend on shift but not caps lock)
IF(shift_l = '1' OR shift_r = '1') THEN --key's secondary character is desired
CASE ps2_code IS
WHEN x"16" => ascii <= x"21"; BIN <= "00010110"; --!
WHEN x"52" => ascii <= x"22"; BIN <= "01010010"; --"
WHEN x"26" => ascii <= x"23"; BIN <= "00100110"; --#
WHEN x"25" => ascii <= x"24"; BIN <= "00100101"; --$
WHEN x"2E" => ascii <= x"25"; BIN <= "00101110"; --%
WHEN x"3D" => ascii <= x"26"; BIN <= "00111101"; --&
WHEN x"46" => ascii <= x"28"; BIN <= "01000110"; --(
WHEN x"45" => ascii <= x"29"; BIN <= "01000101"; --)
WHEN x"3E" => ascii <= x"2A"; BIN <= "00111110"; --*
WHEN x"55" => ascii <= x"2B"; BIN <= "01010101"; --+
WHEN x"4C" => ascii <= x"3A"; BIN <= "01001100"; --:
WHEN x"41" => ascii <= x"3C"; BIN <= "01000001"; --<
WHEN x"49" => ascii <= x"3E"; BIN <= "01001001"; -->
WHEN x"4A" => ascii <= x"3F"; BIN <= "01001010"; --?
WHEN x"1E" => ascii <= x"40"; BIN <= "00011110"; --@
WHEN x"36" => ascii <= x"5E"; BIN <= "00110110"; --^
WHEN x"4E" => ascii <= x"5F"; BIN <= "01001110"; --_
WHEN x"54" => ascii <= x"7B"; BIN <= "01010100"; --{
WHEN x"5D" => ascii <= x"7C"; BIN <= "01011101"; --|
WHEN x"5B" => ascii <= x"7D"; BIN <= "01011011"; --}
WHEN x"0E" => ascii <= x"7E"; BIN <= "00001110"; --~
WHEN OTHERS => NULL;
END CASE;
ELSE --key's primary character is desired
CASE ps2_code IS
WHEN x"45" => ascii <= x"30"; BIN <= "00000000"; --0
WHEN x"16" => ascii <= x"31"; BIN <= "00000001"; --1
WHEN x"1E" => ascii <= x"32"; BIN <= "00000010"; --2
WHEN x"26" => ascii <= x"33"; BIN <= "00000011"; --3
WHEN x"25" => ascii <= x"34"; BIN <= "00000100"; --4
WHEN x"2E" => ascii <= x"35"; BIN <= "00000101"; --5
WHEN x"36" => ascii <= x"36"; BIN <= "00000110"; --6
WHEN x"3D" => ascii <= x"37"; BIN <= "00000111"; --7
WHEN x"3E" => ascii <= x"38"; BIN <= "00001000"; --8
WHEN x"46" => ascii <= x"39"; BIN <= "00001001"; --9
WHEN x"52" => ascii <= x"27"; BIN <= "01010010"; --'
WHEN x"41" => ascii <= x"2C"; BIN <= "01000001"; --,
WHEN x"4E" => ascii <= x"2D"; BIN <= "01001110"; ---
WHEN x"49" => ascii <= x"2E"; BIN <= "01001001"; --.
WHEN x"4A" => ascii <= x"2F"; BIN <= "01001010"; --/
WHEN x"4C" => ascii <= x"3B"; BIN <= "01001100"; --;
WHEN x"55" => ascii <= x"3D"; BIN <= "01010101"; --=
WHEN x"54" => ascii <= x"5B"; BIN <= "01010100"; --[
WHEN x"5D" => ascii <= x"5C"; BIN <= "01011101"; --\
WHEN x"5B" => ascii <= x"5D"; BIN <= "01011011"; --]
WHEN x"0E" => ascii <= x"60"; BIN <= "00001110"; --`
WHEN OTHERS => NULL;
END CASE;
END IF;
END IF;
IF(break = '0') THEN --the code is a make
state <= output; --proceed to output state
ELSE --code is a break
state <= ready; --return to ready state to await next PS2 code
END IF;
--output state: verify the code is valid and output the ASCII value
WHEN output =>
IF(ascii(7) = '0') THEN --the PS2 code has an ASCII output
ascii_new <= '1'; --set flag indicating new ASCII output
ascii_code <= ascii(6 DOWNTO 0); --output the ASCII value
BINREG<=BIN;
END IF;
state <= ready; --return to ready state to await next PS2 code
BIN <= "00000000";
END CASE;
END IF;
END PROCESS;
PROCESS (BIN, BINREG)
BEGIN
IF(BINREG /= BIN)THEN
ED_ACT<=ED_SIG;
CASE ED_ACT IS
WHEN S0 =>
OUT1 <= "0000";
OUT2 <= "0000";
IF (BIN > "00000000") THEN
ED_SIG <= S1;
ELSIF(BIN="01011010")THEN
ED_SIG<=S3;
ELSE
ED_SIG<=S0;
END IF;
WHEN S1 =>
OUT2<="0000";
IF(BIN="00000000")THEN
OUT1<="0000";
ELSIF(BIN="00000001")THEN
OUT1<="0001";
ELSIF(BIN="00000010")THEN
OUT1<="0010";
ELSIF(BIN="00000011")THEN
OUT1<="0011";
ELSIF(BIN="00000100")THEN
OUT1<="0100";
ELSIF(BIN="00000101")THEN
OUT1<="0101";
ELSIF(BIN="00000110")THEN
OUT1<="0110";
ELSIF(BIN="00000111")THEN
OUT1<="0111";
ELSIF(BIN="00001000")THEN
OUT1<="1000";
ELSIF(BIN="00001001")THEN
OUT1<="1001";
ELSIF(BIN="01011010")THEN
ED_SIG<=S3;
ELSE
OUT1<=OUT1;
ED_SIG<=S1;
END IF;
IF(OUT1="0001")THEN
ED_SIG<=S2;
ELSE
ED_SIG<=S3;
END IF;
WHEN S2 =>
OUT2<="0000";
IF(BIN="00000000")THEN
OUT1<="1010";
ELSIF(BIN="00000001")THEN
OUT1<="1011";
ELSIF(BIN="00000010")THEN
OUT1<="1100";
ELSIF(BIN="00000011")THEN
OUT1<="1101";
ELSIF(BIN="00000100")THEN
OUT1<="1110";
ELSIF(BIN="00000101")THEN
OUT1<="1111";
ELSIF(BIN="01011010")THEN
ED_SIG<=S3;
ELSE
OUT1<=OUT1;
ED_SIG<=S2;
END IF;
WHEN S3 =>
OUT1<=OUT1;
IF(BIN="00000000")THEN
OUT2<="0000";
ELSIF(BIN="00000001")THEN
OUT2<="0001";
ELSIF(BIN="00000010")THEN
OUT2<="0010";
ELSIF(BIN="00000011")THEN
OUT2<="0011";
ELSIF(BIN="00000100")THEN
OUT2<="0100";
ELSIF(BIN="00000101")THEN
OUT2<="0101";
ELSIF(BIN="00000110")THEN
OUT2<="0110";
ELSIF(BIN="00000111")THEN
OUT2<="0111";
ELSIF(BIN="00001000")THEN
OUT2<="1000";
ELSIF(BIN="00001001")THEN
OUT2<="1001";
ELSIF(BIN="01011010")THEN
ED_SIG<=S5;
ELSE
OUT2<=OUT2;
ED_SIG<=S3;
END IF;
IF(OUT2="0001")THEN
ED_SIG<=S4;
ELSE
ED_SIG<=S5;
END IF;
WHEN S4 =>
OUT2<=OUT1;
IF(BIN="00000000")THEN
OUT2<="1010";
ELSIF(BIN="00000001")THEN
OUT2<="1011";
ELSIF(BIN="00000010")THEN
OUT2<="1100";
ELSIF(BIN="00000011")THEN
OUT2<="1101";
ELSIF(BIN="00000100")THEN
OUT2<="1110";
ELSIF(BIN="00000101")THEN
OUT2<="1111";
ELSIF(BIN="01011010")THEN
ED_SIG<=S5;
ELSE
OUT2<=OUT2;
ED_SIG<=S4;
END IF;
WHEN S5 =>
OUT1<=OUT1;
OUT2<=OUT2;
IF(BIN="01011010")THEN
ED_SIG<=S0;
END IF;
END CASE;
END IF;
END PROCESS;
END CODIFICACION;
--------------------------------------------------------------------------------------------------------------------------
- LECTURA DEL TECLADO
----------------------------------------------------------------------------------
-- TECLADO
----------------------------------------------------------------------------------
librAry IEEE;
use IEEE.STD_LOGIC_1164.ALL;
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY ps2_keyboard IS
GENERIC(
clk_freq : INTEGER := 50_000_000; --system clock frequency in Hz
debounce_counter_size : INTEGER := 8); --set such that (2^size)/clk_freq = 5us (size = 8 for 50MHz)
PORT(
clk : IN STD_LOGIC; --system clock
ps2_clk : IN STD_LOGIC; --clock signal from PS/2 keyboard
ps2_data : IN STD_LOGIC; --data signal from PS/2 keyboard
ps2_code_new : OUT STD_LOGIC; --flag that new PS/2 code is available on ps2_code bus
ps2_code : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); --code received from PS/2
END ps2_keyboard;
ARCHITECTURE logic OF ps2_keyboard IS
SIGNAL sync_ffs : STD_LOGIC_VECTOR(1 DOWNTO 0); --synchronizer flip-flops for PS/2 signals
SIGNAL ps2_clk_int : STD_LOGIC; --debounced clock signal from PS/2 keyboard
SIGNAL ps2_data_int : STD_LOGIC; --debounced data signal from PS/2 keyboard
SIGNAL ps2_word : STD_LOGIC_VECTOR(10 DOWNTO 0); --stores the ps2 data word
SIGNAL error : STD_LOGIC; --validate parity, start, and stop bits
SIGNAL count_idle : INTEGER RANGE 0 TO clk_freq/18_000; --counter to determine PS/2 is idle
--declare debounce component for debouncing PS2 input signals
COMPONENT debounce IS
GENERIC(
counter_size : INTEGER); --debounce period (in seconds) = 2^counter_size/(clk freq in Hz)
PORT(
clk : IN STD_LOGIC; --input clock
button : IN STD_LOGIC; --input signal to be debounced
result : OUT STD_LOGIC); --debounced signal
END COMPONENT;
BEGIN
--synchronizer flip-flops
PROCESS(clk)
BEGIN
IF(clk'EVENT AND clk = '1') THEN --rising edge of system clock
sync_ffs(0) <= ps2_clk; --synchronize PS/2 clock signal
sync_ffs(1) <= ps2_data; --synchronize PS/2 data signal
END IF;
END PROCESS;
--debounce PS2 input signals
debounce_ps2_clk: debounce
GENERIC MAP(counter_size => debounce_counter_size)
PORT MAP(clk => clk, button => sync_ffs(0), result => ps2_clk_int);
debounce_ps2_data: debounce
GENERIC MAP(counter_size => debounce_counter_size)
PORT MAP(clk => clk, button => sync_ffs(1), result => ps2_data_int);
--input PS2 data
PROCESS(ps2_clk_int)
BEGIN
IF(ps2_clk_int'EVENT AND ps2_clk_int = '0') THEN --falling edge of PS2 clock
ps2_word <= ps2_data_int & ps2_word(10 DOWNTO 1); --shift in PS2 data bit
END IF;
END PROCESS;
--verify that parity, start, and stop bits are all correct
error <= NOT (NOT ps2_word(0) AND ps2_word(10) AND (ps2_word(9) XOR ps2_word(8) XOR
ps2_word(7) XOR ps2_word(6) XOR ps2_word(5) XOR ps2_word(4) XOR ps2_word(3) XOR
ps2_word(2) XOR ps2_word(1)));
--determine if PS2 port is idle (i.e. last transaction is finished) and output result
PROCESS(clk)
BEGIN
IF(clk'EVENT AND clk = '1') THEN --rising edge of system clock
IF(ps2_clk_int = '0') THEN --low PS2 clock, PS/2 is active
count_idle <= 0; --reset idle counter
ELSIF(count_idle /= clk_freq/18_000) THEN --PS2 clock has been high less than a half clock period (<55us)
count_idle <= count_idle + 1; --continue counting
END IF;
IF(count_idle = clk_freq/18_000 AND error = '0') THEN --idle threshold reached and no errors detected
ps2_code_new <= '1'; --set flag that new PS/2 code is available
ps2_code <= ps2_word(8 DOWNTO 1); --output new PS/2 code
ELSE --PS/2 port active or error detected
ps2_code_new <= '0'; --set flag that PS/2 transaction is in progress
END IF;
END IF;
END PROCESS;
END logic;
----------------------------------------------------------------------------------
-- DECODIFICADOR
----------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY DECODER IS
GENERIC(
clk_freq : INTEGER := 50_000_000; --system clock frequency in Hz
ps2_debounce_counter_size : INTEGER := 8); --set such that 2^size/clk_freq = 5us (size = 8 for 50MHz)
PORT(
CLK : IN STD_LOGIC; --system clock input
ps2_clk : IN STD_LOGIC; --clock signal from PS2 keyboard
ps2_data : IN STD_LOGIC; --data signal from PS2 keyboard
OUT1 : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0);
OUT2 : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0));
END DECODER;
ARCHITECTURE CODIFICACION OF DECODER IS
TYPE STATES IS(S0, S1, S2, S3, S4, S5);
SIGNAL ED_ACT, ED_SIG : STATES;
TYPE machine IS(ready, new_code, translate, output); --needed states
SIGNAL state : machine; --state machine
SIGNAL ps2_code_new : STD_LOGIC; --new PS2 code flag from ps2_keyboard component
SIGNAL ps2_code : STD_LOGIC_VECTOR(7 DOWNTO 0); --PS2 code input form ps2_keyboard component
SIGNAL prev_ps2_code_new : STD_LOGIC := '1'; --value of ps2_code_new flag on previous clock
SIGNAL break : STD_LOGIC := '0'; --'1' for break code, '0' for make code
SIGNAL e0_code : STD_LOGIC := '0'; --'1' for multi-code commands, '0' for single code commands
SIGNAL caps_lock : STD_LOGIC := '0'; --'1' if caps lock is active, '0' if caps lock is inactive
SIGNAL control_r : STD_LOGIC := '0'; --'1' if right control key is held down, else '0'
SIGNAL control_l : STD_LOGIC := '0'; --'1' if left control key is held down, else '0'
SIGNAL shift_r : STD_LOGIC := '0'; --'1' if right shift is held down, else '0'
SIGNAL shift_l : STD_LOGIC := '0'; --'1' if left shift is held down, else '0'
SIGNAL ascii : STD_LOGIC_VECTOR(7 DOWNTO 0) := x"FF"; --internal value of ASCII translation
SIGNAL ascii_new : STD_LOGIC; --output flag indicating new ASCII value
SIGNAL ascii_code : STD_LOGIC_VECTOR(6 DOWNTO 0); --ASCII value
SIGNAL BIN : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL BINREG : STD_LOGIC_VECTOR(7 DOWNTO 0);
--declare PS2 keyboard interface component
COMPONENT ps2_keyboard IS
GENERIC(
clk_freq : INTEGER; --system clock frequency in Hz
debounce_counter_size : INTEGER); --set such that 2^size/clk_freq = 5us (size = 8 for 50MHz)
PORT(
clk : IN STD_LOGIC; --system clock
ps2_clk : IN STD_LOGIC; --clock signal from PS2 keyboard
ps2_data : IN STD_LOGIC; --data signal from PS2 keyboard
ps2_code_new : OUT STD_LOGIC; --flag that new PS/2 code is available on ps2_code bus
ps2_code : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); --code received from PS/2
END COMPONENT;
BEGIN
--instantiate PS2 keyboard interface logic
ps2_keyboard_0: ps2_keyboard
GENERIC MAP(clk_freq => clk_freq, debounce_counter_size => ps2_debounce_counter_size)
PORT MAP(clk => clk, ps2_clk => ps2_clk, ps2_data => ps2_data, ps2_code_new => ps2_code_new, ps2_code => ps2_code);
PROCESS(clk)
BEGIN
IF(clk'EVENT AND clk = '1') THEN
prev_ps2_code_new <= ps2_code_new; --keep track of previous ps2_code_new values to determine low-to-high transitions
CASE state IS
--ready state: wait for a new PS2 code to be received
WHEN ready =>
IF(prev_ps2_code_new = '0' AND ps2_code_new = '1') THEN --new PS2 code received
ascii_new <= '0'; --reset new ASCII code indicator
state <= new_code; --proceed to new_code state
ELSE --no new PS2 code received yet
state <= ready; --remain in ready state
END IF;
--new_code state: determine what to do with the new PS2 code
WHEN new_code =>
IF(ps2_code = x"F0") THEN --code indicates that next command is break
break <= '1'; --set break flag
state <= ready; --return to ready state to await next PS2 code
ELSIF(ps2_code = x"E0") THEN --code indicates multi-key command
e0_code <= '1'; --set multi-code command flag
state <= ready; --return to ready state to await next PS2 code
ELSE --code is the last PS2 code in the make/break code
ascii(7) <= '1'; --set internal ascii value to unsupported code (for verification)
state <= translate; --proceed to translate state
END IF;
--translate state: translate PS2 code to ASCII value
WHEN translate =>
break <= '0'; --reset break flag
e0_code <= '0'; --reset multi-code command flag
--handle codes for control, shift, and caps lock
CASE ps2_code IS
WHEN x"58" => --caps lock code
IF(break = '0') THEN --if make command
caps_lock <= NOT caps_lock; --toggle caps lock
END IF;
WHEN x"14" => --code for the control keys
IF(e0_code = '1') THEN --code for right control
control_r <= NOT break; --update right control flag
ELSE --code for left control
control_l <= NOT break; --update left control flag
END IF;
WHEN x"12" => --left shift code
shift_l <= NOT break; --update left shift flag
WHEN x"59" => --right shift code
shift_r <= NOT break; --update right shift flag
WHEN OTHERS => NULL;
END CASE;
--translate control codes (these do not depend on shift or caps lock)
IF(control_l = '1' OR control_r = '1') THEN
CASE ps2_code IS
WHEN x"1E" => ascii <= x"00"; BIN <= "00011110"; --^@ NUL
WHEN x"1C" => ascii <= x"01"; BIN <= "00011100"; --^A SOH
WHEN x"32" => ascii <= x"02"; BIN <= "00110010"; --^B STX
WHEN x"21" => ascii <= x"03"; BIN <= "00100001"; --^C ETX
WHEN x"23" => ascii <= x"04"; BIN <= "00100011"; --^D EOT
WHEN x"24" => ascii <= x"05"; BIN <= "00100100"; --^E ENQ
WHEN x"2B" => ascii <= x"06"; BIN <= "00101011"; --^F ACK
WHEN x"34" => ascii <= x"07"; BIN <= "00110100"; --^G BEL
WHEN x"33" => ascii <= x"08"; BIN <= "00110011"; --^H BS
WHEN x"43" => ascii <= x"09"; BIN <= "01000011"; --^I HT
WHEN x"3B" => ascii <= x"0A"; BIN <= "00111011"; --^J LF
WHEN x"42" => ascii <= x"0B"; BIN <= "01000010"; --^K VT
WHEN x"4B" => ascii <= x"0C"; BIN <= "01001011"; --^L FF
WHEN x"3A" => ascii <= x"0D"; BIN <= "00111010"; --^M CR
WHEN x"31" => ascii <= x"0E"; BIN <= "00110001"; --^N SO
WHEN x"44" => ascii <= x"0F"; BIN <= "01000100"; --^O SI
WHEN x"4D" => ascii <= x"10"; BIN <= "01001101"; --^P DLE
WHEN x"15" => ascii <= x"11"; BIN <= "00010101"; --^Q DC1
WHEN x"2D" => ascii <= x"12"; BIN <= "00101101"; --^R DC2
WHEN x"1B" => ascii <= x"13"; BIN <= "00011011"; --^S DC3
WHEN x"2C" => ascii <= x"14"; BIN <= "00101100"; --^T DC4
WHEN x"3C" => ascii <= x"15"; BIN <= "00111100"; --^U NAK
WHEN x"2A" => ascii <= x"16"; BIN <= "00101010"; --^V SYN
WHEN x"1D" => ascii <= x"17"; BIN <= "00011101"; --^W ETB
WHEN x"22" => ascii <= x"18"; BIN <= "00100010"; --^X CAN
WHEN x"35" => ascii <= x"19"; BIN <= "00110101"; --^Y EM
WHEN x"1A" => ascii <= x"1A"; BIN <= "00011010"; --^Z SUB
WHEN x"54" => ascii <= x"1B"; BIN <= "01010100"; --^[ ESC
WHEN x"5D" => ascii <= x"1C"; BIN <= "01011101"; --^\ FS
WHEN x"5B" => ascii <= x"1D"; BIN <= "01011011"; --^] GS
WHEN x"36" => ascii <= x"1E"; BIN <= "00110110"; --^^ RS
WHEN x"4E" => ascii <= x"1F"; BIN <= "01001110"; --^_ US
WHEN x"4A" => ascii <= x"7F"; BIN <= "01001010"; --^? DEL
WHEN OTHERS => NULL;
END CASE;
ELSE --if control keys are not pressed
--translate characters that do not depend on shift, or caps lock
CASE ps2_code IS
WHEN x"29" => ascii <= x"20"; BIN <= "00101001"; --space
WHEN x"66" => ascii <= x"08"; BIN <= "01100110"; --backspace (BS control code)
WHEN x"0D" => ascii <= x"09"; BIN <= "00001101"; --tab (HT control code)
WHEN x"5A" => ascii <= x"0D"; BIN <= "01011010"; --enter (CR control code)
WHEN x"76" => ascii <= x"1B"; BIN <= "01110110"; --escape (ESC control code)
WHEN x"71" =>
IF(e0_code = '1') THEN --ps2 code for delete is a multi-key code
ascii <= x"7F"; BIN <= "01111111"; --delete
END IF;
WHEN OTHERS => NULL;
END CASE;
--translate letters (these depend on both shift and caps lock)
IF((shift_r = '0' AND shift_l = '0' AND caps_lock = '0') OR
((shift_r = '1' OR shift_l = '1') AND caps_lock = '1')) THEN --letter is lowercase
CASE ps2_code IS
WHEN x"1C" => ascii <= x"61"; BIN <= "00011100"; --a
WHEN x"32" => ascii <= x"62"; BIN <= "00110010"; --b
WHEN x"21" => ascii <= x"63"; BIN <= "00100001"; --c
WHEN x"23" => ascii <= x"64"; BIN <= "00100011"; --d
WHEN x"24" => ascii <= x"65"; BIN <= "00100100"; --e
WHEN x"2B" => ascii <= x"66"; BIN <= "00101011"; --f
WHEN x"34" => ascii <= x"67"; BIN <= "00110100"; --g
WHEN x"33" => ascii <= x"68"; BIN <= "00110011"; --h
WHEN x"43" => ascii <= x"69"; BIN <= "01000011"; --i
WHEN x"3B" => ascii <= x"6A"; BIN <= "00111011"; --j
WHEN x"42" => ascii <= x"6B"; BIN <= "01000010"; --k
WHEN x"4B" => ascii <= x"6C"; BIN <= "01001011"; --l
WHEN x"3A" => ascii <= x"6D"; BIN <= "00111010"; --m
WHEN x"31" => ascii <= x"6E"; BIN <= "00110001"; --n
WHEN x"44" => ascii <= x"6F"; BIN <= "01000100"; --o
WHEN x"4D" => ascii <= x"70"; BIN <= "01001101"; --p
WHEN x"15" => ascii <= x"71"; BIN <= "00010101"; --q
WHEN x"2D" => ascii <= x"72"; BIN <= "00101101"; --r
WHEN x"1B" => ascii <= x"73"; BIN <= "00011011"; --s
WHEN x"2C" => ascii <= x"74"; BIN <= "00101100"; --t
WHEN x"3C" => ascii <= x"75"; BIN <= "00111100"; --u
WHEN x"2A" => ascii <= x"76"; BIN <= "00101010"; --v
WHEN x"1D" => ascii <= x"77"; BIN <= "00011101"; --w
WHEN x"22" => ascii <= x"78"; BIN <= "00100010"; --x
WHEN x"35" => ascii <= x"79"; BIN <= "00110101"; --y
WHEN x"1A" => ascii <= x"7A"; BIN <= "00011010"; --z
WHEN OTHERS => NULL;
END CASE;
ELSE --letter is uppercase
CASE ps2_code IS
WHEN x"1C" => ascii <= x"41"; BIN <= "00011100"; --A
WHEN x"32" => ascii <= x"42"; BIN <= "00110010"; --B
WHEN x"21" => ascii <= x"43"; BIN <= "00100001"; --C
WHEN x"23" => ascii <= x"44"; BIN <= "00100011"; --D
WHEN x"24" => ascii <= x"45"; BIN <= "00100100"; --E
WHEN x"2B" => ascii <= x"46"; BIN <= "00101011"; --F
WHEN x"34" => ascii <= x"47"; BIN <= "00110100"; --G
WHEN x"33" => ascii <= x"48"; BIN <= "00110011"; --H
WHEN x"43" => ascii <= x"49"; BIN <= "01000011"; --I
WHEN x"3B" => ascii <= x"4A"; BIN <= "00111011"; --J
WHEN x"42" => ascii <= x"4B"; BIN <= "01000010"; --K
WHEN x"4B" => ascii <= x"4C"; BIN <= "01001011"; --L
WHEN x"3A" => ascii <= x"4D"; BIN <= "00111010"; --M
WHEN x"31" => ascii <= x"4E"; BIN <= "00110001"; --N
WHEN x"44" => ascii <= x"4F"; BIN <= "01000100"; --O
WHEN x"4D" => ascii <= x"50"; BIN <= "01001101"; --P
WHEN x"15" => ascii <= x"51"; BIN <= "00010101"; --Q
WHEN x"2D" => ascii <= x"52"; BIN <= "00101101"; --R
WHEN x"1B" => ascii <= x"53"; BIN <= "00011011"; --S
WHEN x"2C" => ascii <= x"54"; BIN <= "00101100"; --T
WHEN x"3C" => ascii <= x"55"; BIN <= "00111100"; --U
WHEN x"2A" => ascii <= x"56"; BIN <= "00101010"; --V
WHEN x"1D" => ascii <= x"57"; BIN <= "00011101"; --W
WHEN x"22" => ascii <= x"58"; BIN <= "00100010"; --X
WHEN x"35" => ascii <= x"59"; BIN <= "00110101"; --Y
WHEN x"1A" => ascii <= x"5A"; BIN <= "00011010"; --Z
WHEN OTHERS => NULL;
END CASE;
END IF;
--translate numbers and symbols (these depend on shift but not caps lock)
IF(shift_l = '1' OR shift_r = '1') THEN --key's secondary character is desired
CASE ps2_code IS
WHEN x"16" => ascii <= x"21"; BIN <= "00010110"; --!
WHEN x"52" => ascii <= x"22"; BIN <= "01010010"; --"
WHEN x"26" => ascii <= x"23"; BIN <= "00100110"; --#
WHEN x"25" => ascii <= x"24"; BIN <= "00100101"; --$
WHEN x"2E" => ascii <= x"25"; BIN <= "00101110"; --%
WHEN x"3D" => ascii <= x"26"; BIN <= "00111101"; --&
WHEN x"46" => ascii <= x"28"; BIN <= "01000110"; --(
WHEN x"45" => ascii <= x"29"; BIN <= "01000101"; --)
WHEN x"3E" => ascii <= x"2A"; BIN <= "00111110"; --*
WHEN x"55" => ascii <= x"2B"; BIN <= "01010101"; --+
WHEN x"4C" => ascii <= x"3A"; BIN <= "01001100"; --:
WHEN x"41" => ascii <= x"3C"; BIN <= "01000001"; --<
WHEN x"49" => ascii <= x"3E"; BIN <= "01001001"; -->
WHEN x"4A" => ascii <= x"3F"; BIN <= "01001010"; --?
WHEN x"1E" => ascii <= x"40"; BIN <= "00011110"; --@
WHEN x"36" => ascii <= x"5E"; BIN <= "00110110"; --^
WHEN x"4E" => ascii <= x"5F"; BIN <= "01001110"; --_
WHEN x"54" => ascii <= x"7B"; BIN <= "01010100"; --{
WHEN x"5D" => ascii <= x"7C"; BIN <= "01011101"; --|
WHEN x"5B" => ascii <= x"7D"; BIN <= "01011011"; --}
WHEN x"0E" => ascii <= x"7E"; BIN <= "00001110"; --~
WHEN OTHERS => NULL;
END CASE;
ELSE --key's primary character is desired
CASE ps2_code IS
WHEN x"45" => ascii <= x"30"; BIN <= "00000000"; --0
WHEN x"16" => ascii <= x"31"; BIN <= "00000001"; --1
WHEN x"1E" => ascii <= x"32"; BIN <= "00000010"; --2
WHEN x"26" => ascii <= x"33"; BIN <= "00000011"; --3
WHEN x"25" => ascii <= x"34"; BIN <= "00000100"; --4
WHEN x"2E" => ascii <= x"35"; BIN <= "00000101"; --5
WHEN x"36" => ascii <= x"36"; BIN <= "00000110"; --6
WHEN x"3D" => ascii <= x"37"; BIN <= "00000111"; --7
WHEN x"3E" => ascii <= x"38"; BIN <= "00001000"; --8
WHEN x"46" => ascii <= x"39"; BIN <= "00001001"; --9
WHEN x"52" => ascii <= x"27"; BIN <= "01010010"; --'
WHEN x"41" => ascii <= x"2C"; BIN <= "01000001"; --,
WHEN x"4E" => ascii <= x"2D"; BIN <= "01001110"; ---
WHEN x"49" => ascii <= x"2E"; BIN <= "01001001"; --.
WHEN x"4A" => ascii <= x"2F"; BIN <= "01001010"; --/
WHEN x"4C" => ascii <= x"3B"; BIN <= "01001100"; --;
WHEN x"55" => ascii <= x"3D"; BIN <= "01010101"; --=
WHEN x"54" => ascii <= x"5B"; BIN <= "01010100"; --[
WHEN x"5D" => ascii <= x"5C"; BIN <= "01011101"; --\
WHEN x"5B" => ascii <= x"5D"; BIN <= "01011011"; --]
WHEN x"0E" => ascii <= x"60"; BIN <= "00001110"; --`
WHEN OTHERS => NULL;
END CASE;
END IF;
END IF;
IF(break = '0') THEN --the code is a make
state <= output; --proceed to output state
ELSE --code is a break
state <= ready; --return to ready state to await next PS2 code
END IF;
--output state: verify the code is valid and output the ASCII value
WHEN output =>
IF(ascii(7) = '0') THEN --the PS2 code has an ASCII output
ascii_new <= '1'; --set flag indicating new ASCII output
ascii_code <= ascii(6 DOWNTO 0); --output the ASCII value
BINREG<=BIN;
END IF;
state <= ready; --return to ready state to await next PS2 code
BIN <= "00000000";
END CASE;
END IF;
END PROCESS;
PROCESS (BIN, BINREG)
BEGIN
IF(BINREG /= BIN)THEN
ED_ACT<=ED_SIG;
CASE ED_ACT IS
WHEN S0 =>
OUT1 <= "0000";
OUT2 <= "0000";
IF (BIN > "00000000") THEN
ED_SIG <= S1;
ELSIF(BIN="01011010")THEN
ED_SIG<=S3;
ELSE
ED_SIG<=S0;
END IF;
WHEN S1 =>
OUT2<="0000";
IF(BIN="00000000")THEN
OUT1<="0000";
ELSIF(BIN="00000001")THEN
OUT1<="0001";
ELSIF(BIN="00000010")THEN
OUT1<="0010";
ELSIF(BIN="00000011")THEN
OUT1<="0011";
ELSIF(BIN="00000100")THEN
OUT1<="0100";
ELSIF(BIN="00000101")THEN
OUT1<="0101";
ELSIF(BIN="00000110")THEN
OUT1<="0110";
ELSIF(BIN="00000111")THEN
OUT1<="0111";
ELSIF(BIN="00001000")THEN
OUT1<="1000";
ELSIF(BIN="00001001")THEN
OUT1<="1001";
ELSIF(BIN="01011010")THEN
ED_SIG<=S3;
ELSE
OUT1<=OUT1;
ED_SIG<=S1;
END IF;
IF(OUT1="0001")THEN
ED_SIG<=S2;
ELSE
ED_SIG<=S3;
END IF;
WHEN S2 =>
OUT2<="0000";
IF(BIN="00000000")THEN
OUT1<="1010";
ELSIF(BIN="00000001")THEN
OUT1<="1011";
ELSIF(BIN="00000010")THEN
OUT1<="1100";
ELSIF(BIN="00000011")THEN
OUT1<="1101";
ELSIF(BIN="00000100")THEN
OUT1<="1110";
ELSIF(BIN="00000101")THEN
OUT1<="1111";
ELSIF(BIN="01011010")THEN
ED_SIG<=S3;
ELSE
OUT1<=OUT1;
ED_SIG<=S2;
END IF;
WHEN S3 =>
OUT1<=OUT1;
IF(BIN="00000000")THEN
OUT2<="0000";
ELSIF(BIN="00000001")THEN
OUT2<="0001";
ELSIF(BIN="00000010")THEN
OUT2<="0010";
ELSIF(BIN="00000011")THEN
OUT2<="0011";
ELSIF(BIN="00000100")THEN
OUT2<="0100";
ELSIF(BIN="00000101")THEN
OUT2<="0101";
ELSIF(BIN="00000110")THEN
OUT2<="0110";
ELSIF(BIN="00000111")THEN
OUT2<="0111";
ELSIF(BIN="00001000")THEN
OUT2<="1000";
ELSIF(BIN="00001001")THEN
OUT2<="1001";
ELSIF(BIN="01011010")THEN
ED_SIG<=S5;
ELSE
OUT2<=OUT2;
ED_SIG<=S3;
END IF;
IF(OUT2="0001")THEN
ED_SIG<=S4;
ELSE
ED_SIG<=S5;
END IF;
WHEN S4 =>
OUT2<=OUT1;
IF(BIN="00000000")THEN
OUT2<="1010";
ELSIF(BIN="00000001")THEN
OUT2<="1011";
ELSIF(BIN="00000010")THEN
OUT2<="1100";
ELSIF(BIN="00000011")THEN
OUT2<="1101";
ELSIF(BIN="00000100")THEN
OUT2<="1110";
ELSIF(BIN="00000101")THEN
OUT2<="1111";
ELSIF(BIN="01011010")THEN
ED_SIG<=S5;
ELSE
OUT2<=OUT2;
ED_SIG<=S4;
END IF;
WHEN S5 =>
OUT1<=OUT1;
OUT2<=OUT2;
IF(BIN="01011010")THEN
ED_SIG<=S0;
END IF;
END CASE;
END IF;
END PROCESS;
END CODIFICACION;
--------------------------------------------------------------------------------------------------------------------------
- LECTURA DEL TECLADO
----------------------------------------------------------------------------------
-- TECLADO
----------------------------------------------------------------------------------
librAry IEEE;
use IEEE.STD_LOGIC_1164.ALL;
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY ps2_keyboard IS
GENERIC(
clk_freq : INTEGER := 50_000_000; --system clock frequency in Hz
debounce_counter_size : INTEGER := 8); --set such that (2^size)/clk_freq = 5us (size = 8 for 50MHz)
PORT(
clk : IN STD_LOGIC; --system clock
ps2_clk : IN STD_LOGIC; --clock signal from PS/2 keyboard
ps2_data : IN STD_LOGIC; --data signal from PS/2 keyboard
ps2_code_new : OUT STD_LOGIC; --flag that new PS/2 code is available on ps2_code bus
ps2_code : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); --code received from PS/2
END ps2_keyboard;
ARCHITECTURE logic OF ps2_keyboard IS
SIGNAL sync_ffs : STD_LOGIC_VECTOR(1 DOWNTO 0); --synchronizer flip-flops for PS/2 signals
SIGNAL ps2_clk_int : STD_LOGIC; --debounced clock signal from PS/2 keyboard
SIGNAL ps2_data_int : STD_LOGIC; --debounced data signal from PS/2 keyboard
SIGNAL ps2_word : STD_LOGIC_VECTOR(10 DOWNTO 0); --stores the ps2 data word
SIGNAL error : STD_LOGIC; --validate parity, start, and stop bits
SIGNAL count_idle : INTEGER RANGE 0 TO clk_freq/18_000; --counter to determine PS/2 is idle
--declare debounce component for debouncing PS2 input signals
COMPONENT debounce IS
GENERIC(
counter_size : INTEGER); --debounce period (in seconds) = 2^counter_size/(clk freq in Hz)
PORT(
clk : IN STD_LOGIC; --input clock
button : IN STD_LOGIC; --input signal to be debounced
result : OUT STD_LOGIC); --debounced signal
END COMPONENT;
BEGIN
--synchronizer flip-flops
PROCESS(clk)
BEGIN
IF(clk'EVENT AND clk = '1') THEN --rising edge of system clock
sync_ffs(0) <= ps2_clk; --synchronize PS/2 clock signal
sync_ffs(1) <= ps2_data; --synchronize PS/2 data signal
END IF;
END PROCESS;
--debounce PS2 input signals
debounce_ps2_clk: debounce
GENERIC MAP(counter_size => debounce_counter_size)
PORT MAP(clk => clk, button => sync_ffs(0), result => ps2_clk_int);
debounce_ps2_data: debounce
GENERIC MAP(counter_size => debounce_counter_size)
PORT MAP(clk => clk, button => sync_ffs(1), result => ps2_data_int);
--input PS2 data
PROCESS(ps2_clk_int)
BEGIN
IF(ps2_clk_int'EVENT AND ps2_clk_int = '0') THEN --falling edge of PS2 clock
ps2_word <= ps2_data_int & ps2_word(10 DOWNTO 1); --shift in PS2 data bit
END IF;
END PROCESS;
--verify that parity, start, and stop bits are all correct
error <= NOT (NOT ps2_word(0) AND ps2_word(10) AND (ps2_word(9) XOR ps2_word(8) XOR
ps2_word(7) XOR ps2_word(6) XOR ps2_word(5) XOR ps2_word(4) XOR ps2_word(3) XOR
ps2_word(2) XOR ps2_word(1)));
--determine if PS2 port is idle (i.e. last transaction is finished) and output result
PROCESS(clk)
BEGIN
IF(clk'EVENT AND clk = '1') THEN --rising edge of system clock
IF(ps2_clk_int = '0') THEN --low PS2 clock, PS/2 is active
count_idle <= 0; --reset idle counter
ELSIF(count_idle /= clk_freq/18_000) THEN --PS2 clock has been high less than a half clock period (<55us)
count_idle <= count_idle + 1; --continue counting
END IF;
IF(count_idle = clk_freq/18_000 AND error = '0') THEN --idle threshold reached and no errors detected
ps2_code_new <= '1'; --set flag that new PS/2 code is available
ps2_code <= ps2_word(8 DOWNTO 1); --output new PS/2 code
ELSE --PS/2 port active or error detected
ps2_code_new <= '0'; --set flag that PS/2 transaction is in progress
END IF;
END IF;
END PROCESS;
END logic;
--------------------------------------------------------------------------------------------------------------------------
- CÓDIGO DE COMPONENTE ANTIRREBOTE
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
ENTITY debounce IS
GENERIC(
counter_size : INTEGER := 19); --counter size (19 bits gives 10.5ms with 50MHz clock)
PORT(
clk : IN STD_LOGIC; --input clock
button : IN STD_LOGIC; --input signal to be debounced
result : OUT STD_LOGIC); --debounced signal
END debounce;
ARCHITECTURE logic OF debounce IS
SIGNAL flipflops : STD_LOGIC_VECTOR(1 DOWNTO 0); --input flip flops
SIGNAL counter_set : STD_LOGIC; --sync reset to zero
SIGNAL counter_out : STD_LOGIC_VECTOR(counter_size DOWNTO 0) := (OTHERS => '0'); --counter output
BEGIN
counter_set <= flipflops(0) xor flipflops(1); --determine when to start/reset counter
PROCESS(clk)
BEGIN
IF(clk'EVENT and clk = '1') THEN
flipflops(0) <= button;
flipflops(1) <= flipflops(0);
If(counter_set = '1') THEN --reset counter because input is changing
counter_out <= (OTHERS => '0');
ELSIF(counter_out(counter_size) = '0') THEN --stable input time is not yet met
counter_out <= counter_out + 1;
ELSE --stable input time is met
result <= flipflops(1);
END IF;
END IF;
END PROCESS;
END logic;
--------------------------------------------------------------------------------------------------------------------------
FUENTE DE CODIGO DE TECLADO, ANTIRREBOTE Y PARTE DEL DECODIFICADOR
https://eewiki.net/pages/viewpage.action?pageId=28278929
Etiquetas:Progrmacion ,C++, Practicas programacion
VHDL
Suscribirse a:
Entradas (Atom)