Librería que permite controlar una pantalla LCD 16×2 mediante comandos de alto nivel para tarjetas de desarrollo basadas en FPGA. El código en VHDL contiene una máquina de estados que se encarga de generar los retardos y señales que controlan a la LCD. Existen tres versiones: 8 bits, 4 bits y SPI (modelo: NHD-C0216CZ-FSW-FBW-3V3-ND), el usuario deberá escoger la versión adecuada para su diseño.
Las funciones disponibles son:
- Inicializar LCD.
- Imprimir una letra mayúscula o minúscula.
- Imprimir un caracter a partir de su valor ASCII.
- Imprimir un número entero del 0 a 9.
- Limpiar pantalla.
- Indicar la posición en la que se imprimirá un caracter.
- Crear bucles para repetir un conjunto de instrucciones.
- Crear e imprimir caracteres especiales (excepto la versión SPI).
La librería cuenta con un puerto genérico para especificar la frecuencia de reloj en la que está operando el FPGA.
entity LIB_LCD_INTESC_REVD is GENERIC( FPGA_CLK : INTEGER := 100_000_000 ); PORT(CLK: IN STD_LOGIC;
Al igual que una constante para indicar el número de instrucciones para la LCD que se están utilizando, esto permite una mejor optimización en la implementación.
CONSTANT NUM_INSTRUCCIONES : INTEGER := 12;
El número de la última instrucción es el que se colocará en la constante.
CONEXIONES
Conexiones que se requieren para cada uno de los modos de operación de la LCD. La alimentación debe ser de 5V y se puede utilizar cualquier pin del FPGA para los puertos de la LCD, todos son de un bit.
LCD CON 8 BITS
LCD CON 8 BITS
LCD SPI
FUNCIONES
INICIALIZAR LCD
LCD_INI()
Comando que inicializa la LCD con la opción de configurar el cursor. Dentro de los paréntesis se colocará un vector de 2 bits, el primer bit habilita (‘1’) o deshabilita (‘0’) el cursor, el segundo habilita (‘1’) o deshabilita (‘0’) el parpadeo del cursor.
LCD_INI(“00”) – Cursor y parpadeos deshabilitados.
LCD_INI(“10”) – Cursor habilitado y parpadeo deshabilitado.
LCD_INI(“11”) – Cursor y parpadeo habilitados.
Proceso de inicialización.
IMPRIMIR TEXTO
CHAR()
Imprime una letra de la A a la Z ya sea mayúscula o minúscula. Dentro de los paréntesis se colocará la letra a imprimir, debido a que VHDL no es sensible a mayúsculas y minúsculas utilizar el comando CHAR(a) y CHAR(A) imprimirá una “a” minúscula.
Si se desea imprimir una letra mayúscula se deberá colocar la letra “m”, por ejemplo, CHAR(ma) imprimirá la letra “A”, con la excepción de la letra “s” la cual deberá acompañarse de “ma”: CHAR(maS) imprime la letra “S”.
CHAR_ASCII()
Comando que imprime un caracter a partir de su valor en ASCII, dentro de los paréntesis se colocará un vector de 8 bits (puede ser representado de forma hexadecimal con x” ” ) con el valor ASCII del caracter a imprimir.
CHAR_ASCII(“00111111”) – Imprime “?”
CHAR_ASCII(x”40″) – Imprime “@”
CHAR_ASCII(x”41″) – Imprime “A”
INT_NUM()
Imprime un número entero del 0 al 9 el cual se colocará en los paréntesis.
LIMPIAR PANTALLA
LIMPIAR_PANTALLA()
Comando que borra la información que se encuentre en la LCD y manda el cursor a la primer posición. Dentro de los paréntesis se colocará un bit que limpiará la pantalla si se encuentra en ‘1’ o no realizará ninguna acción si está en ‘0’. Es importante tener un buen control del bit para evitar que la LCD se esté limpiando.
SELECCIONAR POSICIÓN
POS()
Coloca al cursor en cualquier posición a imprimir en la LCD. En los paréntesis se coloca la fila (1-2) y la columna (1-16) separados por una coma.
POS(1,1) – Home
POS(2,3) – Coloca al curso en la segunda fila columna 3
BUCLES
BUCLE_INI() y BUCLE_FIN()
Indican el inicio y fin de un bucle que contendrá un conjunto de instrucciones que se ejecutarán de manera cíclica. Dentro de los paréntesis se colocará un número entero no importa el valor.
BUCLE_INI(1) – Indica inicio
. . . —-
. . . – Instrucciones que se repetirán
. . . —-
BUCLE_FIN(1) – Indica fin
IMPORTANTE: El bucle no puede detenerse.
IMPRIMIR CARACTERES ESPECIALES
CREAR_CHAR()
Crea el caracter especial que se haya definido en el módulo CARACTERES_ESPECIALES_REVx. Dentro de los paréntesis se colocará el número del 1 al ocho indicando el caracter que se creará, se pueden crear hasta 8 caracteres especiales.
IMPORTANTE: Siempre colocar este comando fuera de un bucle.
Para crear un caracter primero se tiene que dibujar en la matriz que se encuentre en CARACTERES_ESPECIALES_REVx, por ejemplo, se desea imprimir la siguiente figura en la LCD:
La matriz CHAR_1 que dibujará la carita queda de la siguiente forma:
CHAR_1 <= "00000"& "00000"& "01010"& "00000"& "10001"& "01110"& "00000"& "00000";
Los pixeles se activan con un ‘1’ lógico.
CHAR_CREADO()
Imprime en la LCD el caracter que se haya creado indicando en los paréntesis el número del caracter que haya sido creado (del 1 al 8). Es importante crear el caracter antes de usar este comando.
INST(xx) <= CREAR_CHAR(1)
…
…
INST(xx) <= CHAR_CREADO(1)
Este comando sí puede ser utilizado dentro de un bucle.
BANDERA BLCD
BLCD
Es una señal de 8 bits que indica qué comando se ejecutó, cada comando tiene un valor único de BLCD y sólo dura un ciclo de reloj.
CÓDIGOS DE EJEMPLO
EJEMPLO 1: HOLA MUNDO!
Código para LCD
INST(0) <= LCD_INI("11"); INST(1) <= CHAR(MH); INST(2) <= CHAR(O); INST(3) <= CHAR(L); INST(4) <= CHAR(A); INST(5) <= CHAR_ASCII(x"20"); INST(6) <= CHAR(MM); INST(7) <= CHAR(U); INST(8) <= CHAR(N); INST(9) <= CHAR(D); INST(10) <= CHAR(O); INST(11) <= CHAR_ASCII(x"21"); INST(12) <= CODIGO_FIN(1);
Código en VHDL
Para este ejemplo no se requiere código VHDL adicional, únicamente especificar el número de instrucciones en la constante NUM_INSTRUCCIONES
CONSTANT NUM_INSTRUCCIONES : INTEGER := 12;
EJEMPLO 2: CONTADOR DE 0 A 99
Código para LCD
INST(0) <= LCD_INI("11"); INST(1) <= LCD_INI("00"); INST(2) <= CHAR(MC); INST(3) <= CHAR(O); INST(4) <= CHAR(N); INST(5) <= CHAR(T); INST(6) <= CHAR(A); INST(7) <= CHAR(D); INST(8) <= CHAR(O); INST(9) <= CHAR(R); INST(10) <= CHAR_ASCII(X"3A"); INST(11) <= BUCLE_INI(1); INST(12) <= POS(2,3); INST(13) <= INT_NUM(decenas); INST(14) <= INT_NUM(unidades); INST(15) <= BUCLE_FIN(1); INST(16) <= CODIGO_FIN(1);
Código en VHDL
Constantes:
CONSTANT NUM_INSTRUCCIONES : INTEGER := 16; CONSTANT ESCALA_1S : INTEGER := FPGA_CLK -1;
Señales:
signal b : std_logic := '0'; signal conta_retardo : integer range 0 to escala_1s := 0; signal unidades, decenas : integer range 0 to 9 :=0;
Código VHDL adicional:
process(CLK) begin if rising_edge(CLK) then conta_retardo <= conta_retardo+1; if conta_retardo = escala_1s then conta_retardo <= 0; b <= '1'; else b <= '0'; end if; end if; end process; process(CLK) begin if rising_edge(CLK) then if b = '1' then unidades <= unidades+1; if unidades = 9 then unidades <= 0; decenas <= decenas +1; if decenas = 9 then decenas <= 0; end if; end if; end if; end if; end process;
EJEMPLO 3: CARACTERES ESPECIALES
Código para LCD
INST(0) <= LCD_INI("11"); INST(1) <= LCD_INI("11"); INST(2) <= CREAR_CHAR(1); INST(3) <= CREAR_CHAR(2); INST(4) <= CREAR_CHAR(3); INST(5) <= CREAR_CHAR(4); INST(6) <= CREAR_CHAR(5); INST(7) <= CREAR_CHAR(6); INST(8) <= POS(1,1); INST(9) <= CHAR_CREADO(1); INST(10) <= CHAR_CREADO(2); INST(11) <= CHAR_CREADO(3); INST(12) <= POS(2,1); INST(13) <= CHAR_CREADO(4); INST(14) <= CHAR_CREADO(5); INST(15) <= CHAR_CREADO(6); INST(16) <= CODIGO_FIN(1);
Código en VHDL
Constantes:
CONSTANT NUM_INSTRUCCIONES : INTEGER := 16;
Código VHDL adicional:
Se crean los caracteres especiales para darle forma al dinosaurio, se modifica el código del módulo CARACTERES_ESPECIALES
CHAR_1 <= "00000"& "00000"& "00000"& "00000"& "00000"& "10000"& "10000"& "11100"; CHAR_2 <= "00011"& "00101"& "00111"& "00111"& "00111"& "00111"& "01111"& "11111"; CHAR_3 <= "11110"& "11111"& "11111"& "11111"& "10000"& "11110"& "10000"& "10000"; CHAR_4 <= "11101"& "11111"& "01111"& "00111"& "00011"& "00000"& "00000"& "00000"; CHAR_5 <= "11111"& "11111"& "11111"& "11111"& "11011"& "10010"& "10010"& "11011"; CHAR_6 <= "11100"& "10100"& "10000"& "10000"& "00000"& "00000"& "00000"& "00000";
DESCARGA LIBRERÍA LCD PARA 8 BITS
DESCARGA LIBRERÍA PARA 4 BITS
DESCARGA LIBRERÍA PARA SPI