Muy buenas a todos, en esta entrada os voy a explicar cómo
elaborar nuestro propio carácter y hacer que éste se nos muestre en nuestra
pantalla LCD. Como en el ejercicio anterior, nuestra práctica se lleva a cabo
en una FPGA, y utilizamos un LCD alfanumérico 2x16.
Para aclarar, crear un carácter significa elaborar un
elemento que no aparezca en la tabla ASCII. Es decir, esta que os muestro a
continuación.
Bien, a partir de aquí procederemos a elaborar nuestro
propio carácter. Para eso he utilizado un programilla muy útil el cual, tras
marcar cada punto, me dice el código que debería meter.
Arriba a la izquierda os muestro el nombre del programa y el
cuadro de la derecha muestra el código. La “A”, es el carácter que voy a sacar
en el LCD, perdonadme pero ahora mismo no recuerdo si era exactamente así, no
tengo ninguna placa para probarlo, pero creo que era así, de todas formas ya
mostraré en vivo y en directo el mensaje.
No me voy a entretener mucho en el inicio del proyecto
puesto que es exactamente igual que la entrada anterior de mostrar un mensaje
en el LCD. Aquí os muestro lo que es el inicio.
Pero no me pararé a explicarlo porque ya lo hice en la
entrada anterior.
Bien, una vez hemos habilitado el LCD a través de las tres
instrucciones y demás, es momento de empezar a mostrar las cosas por el LCD. En
primer lugar, mi práctica tiene que mostrar primero mi nombre “Gabi”, seguido
del carácter. En este caso, aproveché lo que hice en la anterior práctica y
simplemente me limité a copiar como se creaba la “G”,”a”,”b” y la ”i”, con esto
escribí en primer lugar “Gabi”. El inicio del nuevo programa empieza más o
menos a partir del estado 13.
Es importante mencionar una cosa, el motivo de que solo
ponga gabi, no es por el simple hecho de ahorrarme molestias, sino porque por
culpa de esto, xilinx no era capaz de generarme el fit, el problema que me daba
era algo así como “Imposible compilar, exceso de macrocélulas”, es decir,
estaba utilizando más de las que debía, y por eso no me dejaba.
Estas son las transiciones que hay a partir del estado 13 a
los siguientes.
Del 13 al 18 : Q0_D='1' & Q1_D='0' & Q2_D='0' &
Q3_D='0' & Q4_D='0'
Del 13 al 15 : Q0_D='0' & Q1_D='1' & Q2_D='0' &
Q3_D='0' & Q4_D='0'
Del 13 al 16: Q0_D='1' & Q1_D='1' & Q2_D='0'
& Q3_D='0' & Q4_D='0'
Del 13 al 17: Q0_D='0' & Q1_D='0' & Q2_D='1' &
Q3_D='0' & Q4_D='0'
Del 13 al 31: Q0_D='0' & Q1_D='1' & Q2_D='1' &
Q3_D='0' & Q4_D='0'
El estado 31 contiene la dirección DDRAM, yo he puesto la
dirección 00000000, cada uno puede ponerla donde quiera, aunque aconsejo poner
esta porque es fácil identificar a lo que se refiere.
Los 4 primeros
estados anteriormente mencionados pasarán al estado 38 sin condición. Como os
enseño en la imagen.
Si os fijais solo los verdes van al 38, sin embargo el 31
(el carácter), no pasa por él, sino que va a otro, que es el 41, para que os
situéis, la transición marcada con una X es la que conecta con el estado 31.
En el estado 41 activamos el “reloj_carácter” incrementando
así el contador de datos.
Del 41 pasamos al 44 sin condiciones. En éste activamos el
LCD y lo ponemos en lectura.
Como os muestro a continuación.
Del 44 pasamos al 45 sin condiciones, éste estado es
exactamente igual al 44, solo que le
colocamos un “else”, de tal manera que no saldrá de ese estado hasta que el LCD
deje de estar ocupado.
Después pasamos al state 46 si D7_I =0.
Y a partir del 46, pasamos al 47 con las siguientes
condiciones, que son unas cuantas.
Q0_C='0' & Q1_C='1' & Q2_C='0' & Q3_C='0' &
Q4_C='0'
Q0_C='0' & Q1_C='0' & Q2_C='1' & Q3_C='0' &
Q4_C='0'
Q0_C='0' & Q1_C='1' & Q2_C='1' & Q3_C='0' &
Q4_C='0'
Q0_C='0' & Q1_C='0' & Q2_C='0' & Q3_C='1' &
Q4_C='0'
Q0_C='0' & Q1_C='1' & Q2_C='0' & Q3_C='1' &
Q4_C='0'
Q0_C='0' & Q1_C='0' & Q2_C='1' & Q3_C='1' &
Q4_C='0'
Q0_C='0' & Q1_C='1' & Q2_C='1' & Q3_C='1' &
Q4_C='0'
Q0_C='0' & Q1_C='0' & Q2_C='0' & Q3_C='0' &
Q4_C='1'
Desde el State46 a State48
si:
[Q0_C='1' & Q1_C='0' &
Q2_C='0' & Q3_C='0' & Q4_C='0']
[Q0_C='1' & Q1_C='1' &
Q2_C='0' & Q3_C='0' & Q4_C='0']
[Q0_C='1' & Q1_C='0' &
Q2_C='1' & Q3_C='0' & Q4_C='0']
[Q0_C='1' & Q1_C='1' &
Q2_C='1' & Q3_C='0' & Q4_C='0']
[Q0_C='1' & Q1_C='0' &
Q2_C='0' & Q3_C='1' & Q4_C='0']
[Q0_C='1' & Q1_C='1' &
Q2_C='0' & Q3_C='1' & Q4_C='0']
[Q0_C='1' & Q1_C='0' &
Q2_C='1' & Q3_C='1' & Q4_C='0']
[Q0_C='1' & Q1_C='1' &
Q2_C='1' & Q3_C='1' & Q4_C='0']
En el estado 47 activamos
el “RS”, es decir, ponemos el LCD en modo registro. Y en el estado 48 lo ponemos a 0.
Las condiciones que debíamos poner para pasar del estado 46
al 48, vamos a copiarlas, es decir, las transiciones que salen del estado 48
son las que salieron del 46. Cada transición finalizará en un nuevo estado, que
va desde el 49 al 56. Como os muestro en la imagen.
Cada estado representa a una línea del carácter, por eso son
8. En todos ellos mantenemos habilitado el “THREE STATE”, para direccionar CGRAM en cada estado.Una vez
hecho esto, empezaremos a crear el carácter.
Finalmente todos ellos pasarán sin condiciones al último
estado, el 65, que a su vez volverá al estado 42 del diagrama, para que se
repita en un bucle constante.
Como os enseé un poco más arriba, del estado 46, pasamos al
47 y 48, bien, en el estado 47 dijimos que tendría que estar activado el
registro, para que podamos ir pasando los datos de nuestro carácter.
Una vez llegados a este punto, tendremos que tener ya
pensado nuestro carácter, yo os lo enseñé al principio del programa, pero lo
volveré a meter para que lo veais.
Como veis, es simplemente una “A”, como carácter queda
bastante bien en el LCD, además al ser el fondo negro crea una especie de
“marco”. IMPORTANTE, aprovecharos de las líneas que sean iguales!, por qué digo
esto?, pues porque yo he sufrido en mis propias carnes el no poder compilar por
culpa de overflow de espacio. Lo que os comenté de las macrocélulas algo más
arriba. Por eso, prestad atención a la siguiente imagen, en ella me limito a
hacer grupos de mismas líneas.
Como veis aquí, hay 3 líneas diferentes, por lo que en vez
de hacer uno por cada línea, simplemente ponemos 1 y hacemos que cada línea
vaya a dicho estado, ahorrándonos así bastante espacio.
Con esta siguiente imagen lo entenderéis bien.
Cada círculo representa a un grupo, como os mostré en el
carácter. Las transiciones son las siguientes, entendiendo que todas llegan del
estado 47.
Es decir:
Del 47 al 57:
Q0_C='0' & Q1_C='1' & Q2_C='0' & Q3_C='0' &
Q4_C='0'
Q0_C='0' & Q1_C='0' & Q2_C='0' & Q3_C='0' &
Q4_C='1'
Del 47 al 19:
Q0_C='0' & Q1_C='0' & Q2_C='1' & Q3_C='0' &
Q4_C='0'
Del 47 al 14:
Q0_C='0' & Q1_C='1' & Q2_C='0' & Q3_C='1' &
Q4_C='0'
Q0_C='0' & Q1_C='1' & Q2_C='1' & Q3_C='0' &
Q4_C='0'
Del 47 al 59:
Q0_C='0' & Q1_C='0' & Q2_C='0' & Q3_C='1' &
Q4_C='0'
Q0_C='0' & Q1_C='0' & Q2_C='1' & Q3_C='1' &
Q4_C='0'
Q0_C='0' & Q1_C='1' & Q2_C='1' & Q3_C='1' &
Q4_C='0'
Después, los 4 estados van al 65 sin ninguna condición.
Y justo después del estado 65 lanzamos una transición hacia
el estado 42, que va sin condiciones.
Como veis, del estado 42 salen una gran cantidad de
transiciones hacia el 41, estas son:
[Q0_C='1' & Q1_C='0' &
Q2_C='0' & Q3_C='1' & Q4_C='0']
[Q0_C='0' & Q1_C='1' &
Q2_C='0' & Q3_C='1' & Q4_C='0']
[Q0_C='1' & Q1_C='1' &
Q2_C='0' & Q3_C='1' & Q4_C='0']
[Q0_C='0' & Q1_C='0' &
Q2_C='1' & Q3_C='1' & Q4_C='0']
[Q0_C='1' & Q1_C='0' &
Q2_C='1' & Q3_C='1' & Q4_C='0']
[Q0_C='0' & Q1_C='1' &
Q2_C='1' & Q3_C='1' & Q4_C='0']
[Q0_C='1' & Q1_C='1' &
Q2_C='1' & Q3_C='1' & Q4_C='0']
[Q0_C='1' & Q1_C='0' &
Q2_C='0' & Q3_C='0' & Q4_C='0']
[Q0_C='0' & Q1_C='1' &
Q2_C='0' & Q3_C='0' & Q4_C='0']
[Q0_C='1' & Q1_C='1' &
Q2_C='0' & Q3_C='0' & Q4_C='0']
[Q0_C='0' & Q1_C='0' &
Q2_C='1' & Q3_C='0' & Q4_C='0']
[Q0_C='1' & Q1_C='0' &
Q2_C='1' & Q3_C='0' & Q4_C='0']
[Q0_C='0' & Q1_C='1' &
Q2_C='1' & Q3_C='0' & Q4_C='0']
[Q0_C='1' & Q1_C='1' &
Q2_C='1' & Q3_C='0' & Q4_C='0']
[Q0_C='0' & Q1_C='0' &
Q2_C='0' & Q3_C='1' & Q4_C='0']
Del estado 42 al 43 con la condición:
Q0_C='0' & Q1_C='0' & Q2_C='0'
& Q3_C='0' & Q4_C='1'
Este estado es importante, habilitamos
el LCD, lo primero, y después, introducimos el código de la DDRAM. Que es
11000110.
Después pasamos del 43 al 38 sin
condición.
Subimos un poquito más y nos vamos al
estado 39, que va hacia el 10 mediante estas transiciones:
Q0_D='1' & Q1_D='0' & Q2_D='0'
& Q3_D='0' & Q4_D='0'
Q0_D='0' & Q1_D='1' & Q2_D='0'
& Q3_D='0' & Q4_D='0'
Q0_D='1' & Q1_D='1' & Q2_D='0'
& Q3_D='0' & Q4_D='0'
Q0_D='0' & Q1_D='0' & Q2_D='1'
& Q3_D='0' & Q4_D='0'
Q0_D='1' & Q1_D='0' & Q2_D='1'
& Q3_D='0' & Q4_D='0'
Q0_D='0' & Q1_D='1' & Q2_D='1'
& Q3_D='0' & Q4_D='0'
Q0_D='1' & Q1_D='1' & Q2_D='1'
& Q3_D='0' & Q4_D='0'
Ya con esto lo esencial ya estaría
para hacer funcionar nuestro carácter en el LCD. Me dijeron que existía una
manera de “optimizar” el proyecto dándole desde el stateCAD a donde pone
“optimize” en la parte superior, mi problema es que cuando le doy, me
desaparece el diagrama entero, como su fuera una especie de error grave, y no
puedo usarlo. Aún no sé el motivo, disculpad.
Tras verificar que todo está correcto
y al 100% podremos realizar el proceso de creación de VHDL, como siempre,
dándole en la parte superior a “Generate VHD”.
Una vez tengamos el código VHD
generado será el momento de crear un esquemático, en este caso, bastante
parecido a la entrada de “crear un mensaje en el LCD con xilinx”, solo que he
tenido que hacer unos pequeños retoques, como cambiar la máquina de estados y
demás, claro.
Es algo así.
El esquemático es muy similar al
anterior, éste tiene incorporado un contador binario de 4 bits y 2 contadores
binarios de 8 bits. Además de la máquina de estados, claro.
Cuando tengamos creado el esquemático,
pasaremos al PACE, para meter los pines, y por ultimo generaremos el .JED, como
hacemos siempre.
Una vez tengamos acabado todo esto y utilicemos el JTAG para simularlo en la placa entrenadora tendremos nuestro caracter listo, como os enseño a continuación:
Y ya tendríamos nuestra máquina que muestra un carácter en el lCD. Espero que os haya servido de ayuda, un saludo y feliz año!
No hay comentarios:
Publicar un comentario