Images

Ejercicio Sencillo para Comunicaciones Vía Bluetooh con Microcontroladores de Arquitectura ARM7 de 32 bits.

Introducción:

Lo que vamos a ver en el tutorial de esta entrada es un ejercicio que he visto hecho con Arduino y PIC y excelentemente explicado en tutoriales en Internet. La cuestión es que no lo he visto mucho con micros de 32 bits y arquitectura ARM7, y de ahí que veo la utilidad de publicarlo.

El ejercicio consiste básicamente en encender y apagar un LED mediante un dispositivo con sistema operativo Android como podría ser una Tablet (con bluetooth) o un móvil (o también conocido en castellano como celular). En el siguiente clip se ilustra lo que acabo de decir. 





Para hacer esto usaremos un módulo hardware ampliamente conocido y de unas excelentes prestaciones considerando su bajo precio que es el HC-05.

Con el fin de no alargar mucho el tutorial daré las indicaciones necesarias que considero claves o que no se explican en otros lugares de Internet.


Como siempre vamos a lo relativamente sencillo, rápido y barato con el fin de que el lector tenga una base para realizar proyectos más complejos. 

Como viene siendo habitual últimamente dejo el tutorial en un enlace en formato PDF.

Tutorial Ejercicio Sencillo HC-05 y Micro 32 bits.

También dejo el código en C para que se pueda copiar y pegar..

//************************************************************ // Nombre: main1_BT_LED.c //Descripción: //Encendido y apagado de un LED dándo la orden // al micro mediante un dispositivo android vía bluetooth // con un módulo tipo HC-05. /* Si en nuestro celular o móvil pulsamos un 1, el led se enciende, si pulsamos un 0, el led se apaga. */ //Target: STM32F407VG //ToolChain: MDK-ARM //IDE: uVision 5 //************************************************************ #include "stm32f4xx_rcc.h" #include "stm32f4xx_gpio.h" #include #include #include "stm32f4xx.h" #include "defines.h" #include "tm_stm32f4_usart.h" #include "tm_stm32f4_delay.h" #define USARTx USART2 //Puerto que se usará. /* Esta función se utiliza para trasmitir una cadene de caracteres a través * El USART especificado en USARTx * La cadena tiene que ser pasado a la función como un puntero porque * El compilador no conoce el tipo de datos string. En C una cadena es sólo * un conjunto de caracteres. */ //Función para configurar el periférico USART2 void Config_USARTx(void){ /* TX = GPIOA_Pin_2 (RX) RX = GPIOA_Pin_3 (TX) RTS = GPIOA_Pin_1 (CTS) CTS = GPIOD_Pin_3 (RTS) */ //Estructuras para configurar los puertos, el USART2 y las interrupciones NVIC GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; //Activación del reloj del APB1 para el USART2 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //Ativación del reloj del periférico para los pines utilizadas por la //USART2, PA3 para TX y RX PARA pa2 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //Conecta los pines a la UART //GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_USART2); //RTS (no usado) GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); //TX GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); //RX //GPIO_PinAFConfig(GPIOD, GPIO_PinSource3, GPIO_AF_USART2); //TX //Configura los pines GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; GPIO_Init(GPIOA, &GPIO_InitStructure); //Configura la USART USART_InitStructure.USART_BaudRate = 9600; //Velocidad en buadios USART_InitStructure.USART_WordLength = USART_WordLength_8b; //8 Bits USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USARTx, &USART_InitStructure); //Hace efectiva la configuración. //Activación de la interrupción del receptor USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //Inte del receptor de activa //Configura interrupción por el USART NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; //Configura la interrupción NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //Prioridad de USART NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //Subprioridad NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //Habilitador global de inte. NVIC_Init(&NVIC_InitStructure); //La configuración se pasa a NVIC_Init() USART_Cmd(USARTx, ENABLE); //Finalmente se habilita la USART2 } void Configurar_LED(void){ //Configura pin donde está el LED (PD15) GPIO_InitTypeDef GPIO_LED; //Estructura para configurar Puerto D RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); //Habilita el bus AHB1 GPIO_LED.GPIO_Pin = GPIO_Pin_15; //Pin que deseamos configurar GPIO_LED.GPIO_Mode = GPIO_Mode_OUT; //Configura como salida GPIO_LED.GPIO_OType = GPIO_OType_PP; //Configura el pin tipo push/pul //(opuesto a open drain) GPIO_LED.GPIO_Speed = GPIO_Speed_100MHz; //Configura el pin a 100 MHz GPIO_LED.GPIO_PuPd = GPIO_PuPd_NOPULL; //Desactiva los pull-up, no hacen falta GPIO_Init(GPIOD, &GPIO_LED); //Hacer efectiva configuración del puerto } //Función principal int main(void){ Config_USARTx(); //Enviar_String("Esperando datos..."); //Mensaje inicial. Configurar_LED(); //TM_USART_Puts(USARTx, "OK\n\r"); while(1){ //Espera por la interrupción } } //ISR (rutina de servivio de interrupción) para todas las interrupciones de USART2 void USART2_IRQHandler(void){ //GPIO_SetBits(GPIOD, GPIO_Pin_15); //GPIO_ResetBits(GPIOD, GPIO_Pin_15); if(USART_GetITStatus(USART2, USART_IT_RXNE)){ char caracter = USART2->DR; //El dato recibido es salvado en caracter USART_SendData(USART2, caracter); //Re-envia el dato recibido if(caracter == '1') GPIO_SetBits(GPIOD, GPIO_Pin_15); if(caracter == '0') GPIO_ResetBits(GPIOD, GPIO_Pin_15); } }


Por el momento lo dejamos aquí, espero que este tutorial resulte útil :).

-Fin-
Images

Ejercicio Práctico para Trabajar con Multicapas en Altium.


Introducción:

La primera cuestión que podría surgir a algún lector es:  ¿Qué es eso de las multicapas?.

Bueno, la misma palabra multicapas da una idea bastante aproximada de su significado. Tradicionalmente se ha usado PCBs (y aún se sigue usando) dónde hay dos capas, los componentes van en la capa superior (top layer), y las pistas pueden ir en la capa superior, la inferior (bottom layer) o en ambas si la complejidad del circuito impreso o PCB así lo exige.

La cuestión es que hay contextos en que por espacio u otros requisitos es recomendable usar otra alternativa diferente que el avance de la tecnología ya permite desde hace ya un tiempo. Y es aquí donde entran las multicapas o el concepto relacionado con estas: “Stack-Up”.

En este tipo de diseños es posible tener más capas de manera que no sólo tenemos el top layer para soldar componentes, y el top layer y el bottom layer para las pistas, con lo que podemos aumentar la capacidad de integración en una misma placa ahorrando espacio.

Se podría decir que un diseño multicapas es una configuración de PCBs apilados unos encima de otros. Y digo “que se podría decir” porque esos PCBs en muchos casos (por no decir la mayoría), están íntimamente conectados unos con otros, así que de alguna manera forman un solo PCB.  

Por supuesto, este aumento de la integración no sale gratis, ni por el dinero ni porque aparecen ciertos desafíos como la especial consideración que hay que tener de la EMC (compatibilidad electromagnética), así como de EMI (acrónimo de Electro-Magnetic Interference).  Esto efectos no sólo pueden aparecer como resultado del mismo diseño, también por el ambiente en dónde se espera que trabaje el PCB, algo que hay que considerar también y en lo que hay personas, departamentos y empresas especializadas, pues no es un tema en absoluto trivial.

Afortunadamente los programas de diseño de PCBs cuentan con herramientas para abordar esto, y si especificas estos requerimientos del PCB a los fabricantes, los fabricantes lo tendrán en consideración. Sin embargo nada de eso excluye que el diseñador debe conocer esos conceptos y tenerlos seriamente en cuenta en el proceso de diseño.

Tras esta breve y simplificada descripción del concepto de multicapas, pasamos a nuestro ejercicio práctico que hará uso de lo hecho en la anterior publicación de este blog.


Si deseas profundiza un poco más en los conceptos de Stack-Up o Multicapas, puedes echar un vistazo a la documentación de una publicación anterior de este blog:


La documentación que puedes encontrar ahí (descargable en formato PDF), no es muy extensa y no le llevará al lector mucho tiempo echarle un ojo. No obstante,  eso es decisión suya dama o caballero  J, como usted desee.

¿Qué vamos a hacer básicamente?

Como ya dije, usaremos el diseño del anterior post para introducirnos en este  en el diseño de multicapas, para ello veo más práctico hacer uso en este caso de video-tutoriales.

En dicho diseño había dos reguladores de tensión que podían ser activados o desactivados con dos interruptores. Usaremos un diseño de cuatro capas para situar el circuito de entrada y los interruptores en la región superior, y los dos reguladores en la inferior. Es un diseño bastante sencillo pero en estos casos siempre mejor empezar con cosas sencillas ¿verdad?.

De nuevo me centraré en las cuestiones que puedan resultar más útiles en el diseño multicapas (y que he aprendido de forma auto-didacta con lo que eso implica…). De forma que en ningún caso lo que muestro en los clips se puede considerar como el diseño completo. Para tener el diseño completo hacen falta más cosas (y posiblemente un repaso de lo hecho).

Sin embargo, considero que como punto de partida para introducirse en el diseño con multicapas puede ser útil (ojalá que sí).

Come on!, go ahead!

1- Configurando el Layer Stack Manager (Administrador de Apilamiento de Capas).



2- Situando los componentes en sus capas.



3- Situando las capas y rutenado (rooting).


4- Seguimos con el diseño: introducción de planos de tierra, vías... etc.

https://www.youtube.com/watch?v=LMNbzqqc7JI


5- Puliendo lo hecho hasta ahora y últimos apuntes.



Y con esto podemos considerar terminado esta entrada. Como parece que con tanta electrónica empiezo a hablar como un autómata programable, me despediré por el momento con algo de lírica.

Por algún lugar escuche algo que me gustó mucho:

Si cultivas un pensamiento, cosechas una acción,
si cultivas una acción, cosechas un hábito,
si cultivas un hábito, forjas un carácter.

A mi se me ocurre a raíz de esto que la mejor manera de vencer dificultades es enfrentándote a ellas (tengas o no éxito luego), y la mejor manera de ser perseverante es perseverar.

A fin de cuentas, el movimiento se demuestra andando, ¿cierto?. 

Un saludo cordial al que haya "caído" por aquí y mi mayor deseo de que lo que por aquí publico sea de utilidad.



Images

Trabajando con Jerarquías (Schematic Sheet Symbol) en Altium.


¿Qué significa eso de trabajar con jerarquías en el diseño de un  PCB?

Cuando las personas nos enfrentamos a un problema de cierta complejidad, lo que a menudo hacemos es dividir el problema en partes más sencillas, resolver estas y luego relacionar todas esas partes para formar el todo.  Es la vieja táctica (pero no por eso menos útil) del “divide y vencerás”.

De igual manera para crear un diseño de un PCB en Altium Designer  de una cierta complejidad - y dónde tengamos un número mayor de componentes que en otros diseños menos complejos-, podemos ir agrupando componentes por su funcionalidad  en módulos.

 Después estos módulos se integrarán en una hoja del esquemático (schematic sheet) del proyecto para que tengamos nuestro proyecto completo.

A esta hoja dónde usamos estos módulos para que trabajen junto, es la  que consideramos de mayor jerarquía, y de ahí el nombre de jerarquía para denominar esta forma de diseñar (que nos puede ser muy útil en muchos casos).

Además, los módulos - que en el proyecto llamamos de menor  jerarquía - pueden ser replicados en el mismo proyecto (en caso de que se usen varias veces), o incluso usados en otros proyectos.

Por último se pasa lo hecho a layout del PCB.

Para esto Altium Designer tiene una herramienta magnifica que es el “shematic sheet symbol”.

Si todo lo que he explicado le suena al lector muy abstracto no hay problema, en el tutorial y la documentación adjunta que presento en este post, veremos cómo se implementa la idea en la práctica y al final tendrá una idea bastante clara de lo que significa el diseño jerárquico.

Por otro lado este post (o publicación) nos servirá como base para explicar -con un ejercicio práctico- más sobre cómo trabajar con multicapas o StackUp en una próxima publicación que ya tengo preparada.

 ¿Qué necesitas para este tutorial?

Esta vez no necesitarás gastar dinero (plata, pesos, noney…), si no tienes una versión no muy antigua de Altium, puedes descargarte un trial o versión gratuita que caducará en un tiempo suficiente para realizar este tutorial, a continuación dejo el enlace:

http://www.altium.com/free-trial

Para obtenerla sólo tendrás previamente que rellenar unos formularios para registrarte, pero no es nada difícil seguir os pasos y en la página web está perfectamente explicado.

El tutorial del que parto es para una versión más antigua de la que probablemente obtendrás con ña versión gratuita, eso implica que cambia un poco la interfaz de las distintas ventanas, pero no lo suficiente como para que el tutorial no te sea útil.

¿Qué vamos a hacer básicamente?

Como ya he dicho parto de un tutorial bastante completo e interesante que encontré en inglés en Internet, y que luego he traducido (daré los enlaces tanto en del original en inglés como mi traducción en castellano).

En ese tutorial se usa un regulador de tensión (útil para control de motores por ejemplo) como base para explicar los distintos pasos,  y ahí -entre otras muchas cosas-  se explica cómo trabajar con jerarquías y en un anexo como replicar los módulos o “schematic sheet symbols”.

En dicho tutorial se explica – excluyendo el anexo-  para un solo regulador de tensión.

Yo le he dado “una vuelta de tuerca” más y lo he hecho para un diseño dónde se trabaja con dos reguladores de tensión, de manera tal que mediante interruptores puedas poner en marcha uno (el A) o el otro (el B), o ambos a la vez (A y B). Para no complicarlo mucho he usado dos interruptores manuales.  

Para no alargar mucho el tutorial,  al final presento unos video-tutoriales dónde explico las  partes del diseño que he estimado más interesantes y dónde el lector (o lectora) no muy experimentado en jerarquías y multicapas podría encontrar más dudas.

Let´s go!

Tutoriales de los que parto encontrados en Internet:

 - Originales en Inglés:

Altium_Schematic_Tutorial.pdf

El anterior enlace tiene su continuación en el siguiente:



- Mis traducciones hechas en castellano con anotaciones añadidas para el lector:

Tutorial_Esquematicos_Altium

Tutorial_Layout_PCB_Altium

Según las preferencias de cada uno se puede seguir cualquiera de las dos opciones (inglés o español).

------------------------------------------------------------------------------------------------------------------------

Notas:

En las traducciones he procurado no hacer una traducción demasiado literal y a la vez ceñirme lo más posible al original.

Realicé una revisión rápida una vez acabadas las traducciones y me hubiera gustado hacer una segunda más, espero que el resultado sea del gusto de los lectores y eso no sea un gran impedimento para que esto resulte útil.

También cuento – tanto en las  traducciones como en los clips – que hay personas que podrían llegar a este blog y encuentren que mi castellano no es exactamente como al que suelen usar, Ojala que eso tampoco sea un impedimento serio. 

-----------------------------------------------------------------------------------------------------------------------

Cips o video-tutoriales para explicar las partes críticas del desarrollo del ejercicio:

Por ahí dicen que mi inglés se parece al loquendo traducido, ese programa que lee palabras y que suena a robot de la “Guerra de las Galaxias” (Star Wars). Seguro que el loquendo  pronuncia mejor que yo :D. En fin, se hace lo que se puede estimados lectores que hayáis llegado a este lugar recóndito de Internet.

1- Inicio: esquemáticos de punto de partida.


2- Trabajando con módulos (schematic sheet symbolos) en el esquemático y pasando al layout del PCB.


3- Seguimos con el diseño en layout del PCB. Replicando el footprint de los módulos.



Bueno, por el momento lo dejamos aquí. Usaremos este diseño en la siguiente publicación para abordar la cuestión de las multicapas o stack-up. See you soon!



Images

Manuales de ayuda para trabajar con PCBs multicapas.

Me he hecho un par de manuales sobre el concepto de "Stack-Up" o "apilamiento" (íntimamente ligado al concepto de PCBs con multicapas o multilayers).

Para ello he traducido al castellano un par de  interesantes manuales en inglés, y luego he añadido anotaciones sobre conceptos y términos que aparecen ahí.

En un principio lo hice para mí, pero creo que puede ser útil para las personas interesadas en el tema que se manejen mejor con el castellano que con el inglés (o que directamente no se manejen con el inglés).

Además, como están en formato PDF, cualquiera que lo desee lo puede tener en su disco duro sin necesidad de tener que ir a Google - o al buscador que use - .

Para el que entienda el inglés tan bien como el castellano -o mejor-, pues bueno, quizás encuentre aquí una posible traducción a parte de los links en inglés. Eso depende del uso que cada uno quiera darle a este blog.



Fuentes:

Como lo honrado es dejar las fuentes (en este caso en inglés) en las que te has basado, primero dejo los enlaces/links a esos lugares de Internet:

http://www.pcbcart.com/pcb-capability/layer-stackup.html

http://techdocs.altium.com/display/ADRR/PCB_Dlg-LayerStackConfigurationForm((Layer%20Stack%20Manager))_AD

Hay otros manuales y tutoriales magníficos sobre el tema, pero tienes que decidirte por algo porque sino puedes pasarte horas y horas navegando por Internet hasta que llega un momento en que  ni te acuerdas de lo que estabas buscando y para que.  Internet está lleno de ventajas pero también tiene sus inconvenientes.

Manuales:

A continuación dejo las traducciones hechas por mí completadas con comentarios y notas (en castellano).

Layer StackUp (apilamiento de capas).

El Layer Stack Manager de Altium

Ojalá pueda serle útil a algún lector.

En cualquier caso bienvenido sea cualquier navegante que "recale" por este puerto.


Images

Ejercicio sencillo con sensor de luz y micro de 32 bits.

Introducción:

La idea de esta entrada al blog -con la que adjunto un enlace a un PDF al final-, es hacer un ejercicio con un sensor de luz tipo LDR (Light Dependent Resistor) modelo GL5528, que cumpliera los siguientes requisitos:

- Que sea sencillo para las personas que empiezan a introducirse en esto.

- Que sea lo más barato posible.

- Que no sea un plagio de otras cosas que hay por Internet.

- Que se pudiera hacer en un lapso de tiempo no muy largo. Tenga en cuenta el lector que entre explorar que cosas son factibles en poco tiempo a la vez que interesantes (buscar la idea), y en documentar se me va más tiempo que en realizar este tipo de ejercicios y también tengo que contar con eso.

El tutorial completo lo dejo en formato PDF a través de un enlace al final de esta introducción.

¿Qué necesitas para realizar este ejercicio práctico?.

•Hardware:

- Una placa de desarrollo STM32F4-Discovery. Precio aproximado 18,72 euros (aproximadamente 20 dólares USA al cambio del día que en que escribo esto).

- Un sensor de luz LDR modelo GL5528. Precio aproximado 1,36 euros (1,45 dólares USA).

- Dos resistencias de orificio pasante de unos 220 ohmios. Precio aproximado de la unidad 0,059 euros (0,06 dólares USA).  Las dos unidades unos 0,118 euros (0,12 dólares USA).

- Un LED normal para protoboard. Precio aproximado unos 0,18 euros o menos (0,19 dólares USA).

- Un protoboard. Precio aproximado 8,36 euros (8,92 dólares USA).
Monto total: 28,738 euros o 30,66 dólares USA. Redondeando puede salir todo por unos 30 euros o 32 dólares.

•Software:

- IDE para programar la placa STM32, preferentemente el Keil µVision 5 que es el que yo uso en este tutorial.

- Una aplicación para desarrollo de PCBs, la que yo uso en este tutorial es el Altium Designer.

¿Qué hará exactamente el sistema que desarrollaremos?.

Nuestro sistema será sensible a la luz –que será el Input del sistema – de manera que a mayor cantidad de luz detectada un LED (Output del sistema) parpadeará con una frecuencia menor, esto es, más lentamente, y a menor cantidad de luz el LED parpadeará con mayor frecuencia (más deprisa).


Gráficamente:

   
A mayor luz registrada parpadeo del LED más lento.
A menor luz registrada parpadeo del LED más rápido.

Para ilustrarlo mejor y de paso dar fe de que funciona, dejo un clip:




Este ejercicio ya lo hice con un Arduino Uno, ¿entonces que novedoso tiene esto si se puede hacer con un micro de 8 bits?, pues la novedad es que no encuentro tantos tutoriales sobre micros de 32 bits sobre este tipo de ejercicios (menos aún en castellano), por eso me parece interesante para el que quiera introducirse en la programación de micros de 32 bits.

Además, al final aprovecho todo esto para hacer un ejercicio de desarrollo de PCBs que -dada las limitación de tiempo que me he impuesto- se considerará como sólo eso, un ejercicio que me sirve además de excusa para hacer hincapié en conceptos que considero fundamentales en el desarrollo de un PCB, algo con lo que hubiera tenido menos tiempo si lo hubiera elaborado más.

Por otro lado, para el que se está introduciendo en este tipo de temas es siempre mejor empezar de lo sencillo para ir a lo complejo.

Aquí va el enlace al tutorial:


Images

Mostrando por display la entrada en tensión regulada por un potenciómetro.


En esta entrada vamos a ver un ejemplo muy sencillo para aprender a manejar la placa STM32F4-Discovery. Dicha tarjeta de desarrollo puede ser una excelente herramienta para introducir al lector en la programación de microcontroladores de 32 bits (con arquitectura ARM).

Básicamente en primer lugar se trata de hacer lo que se muestra en el siguiente clip.



Además en este tutorial se incluye un posible diseño de un circuito impreso (o PCB por su acrónimo en inglés). El layout del mencionado PCB implementaría este sistema sin la tarjeta de desarrollo STM32F4-Discovery, con los elementos esenciales para realizar lo que el ejercicio propone.

 Viene a ser algo así como un voltimetro sencillo que mide la tensión entre los terminales del potenciómetro. Recordemos que el potenciómetro no es más que una resistencia que podemos variar entre cero y el límite máximo de ohmios de dicho potenciómetro. 

He pensado que tal y como trabajo las publicaciones de este blog, quizás es más interesante que deje enlaces para que se pueda ver la mayor parte en PDF, de forma que no resulte tan largo y más legible.

El post lo he dividido en dos partes, Una intraducción y el tutorial en sí. 

En la introducción comento principalmente el hardware y el software que se necesita así como una aproximación del dinero que te puede costar. 

En el tutorial se da las indicaciones de como ir  realizando este ejercicio que propongo. Aviso que se hace más hincapié en la parte de programación del micro que en el diseño del PCB que tan sólo se esboza.

Si haces clic o pulsas los siguientes enlaces lo verás:



Espero que resulte útil y más cómodo de leer. ¡Hasta la próxima!.
Images

Generando código VHDL con SIMULINK (I): Tutorial introductorio.

Introducción:

Ya vimos anteriormente como introducir el código VHDL usado en el software de XILINX (más concretamene Vivado) en un modelo de SIMULINK, que luego nos servía para simular el comportamiento de las salidas del diseño previamente hecho.

A ese diseño descrito en VHDL lo  llamamos LEDA_blog, y lo hemos usado profusamente hasta ahora.

Dejo los enlaces de las entradas de este blog dónde se hizo (así no tienes que navegar en él y te facilito las cosas):



Sintetizando lo que hicimos fue:

XILINX (VHDL) => SIMULINK


Esta vez vamos a realizar el proceso contrario,

SIMULINK => XILINX (VHDL)

Sólo que esta vez partiremos de un diseño más sencillo, un simple multiplexor 2 a 1 (2 entradas una salida), lo que en electrónica digital usamos muchas veces como un "Hola Mundo" (y sin embargo eso no quita que los multplexores son circuitos combinacionales muy importantes en electrónica digital).

Las razones por las que vamos a partir de un diseño sencillo son tres:

- La primera es que siempre es más pedagógico ir de lo sencillo a lo complejo.

- La segunda es algo bastante más prosaico, y es que esta entrada la voy a hacer con los trials de las últimas versiones de Vivado y Matlab -en la versión más completa de los dos programas- y los 30 días que los tengo gratis están a punto de vencer. Si me pongo con algo más complejo es posible que me quede a medias.

- La tercera es que no quiero que acabemos odiando el dichoso diseño LEDA_blog (estoy intentando parecer divertido, no el tipo serio y aburrido que soy :P).

Si no sabes lo que es un multiplexor (ya dije que pretendo escribir para todos los públicos como las antiguas películas de Walt Disney), no te preocupes, cuando acabe el tutorial tendrás unas nociones muy claras, te lo garantizo.

 Esto es uno de los motivos por los que me gustan tanto los tutoriales tipo "receta de cocina" (pantallazos y más pantallazos), aprendes mucho casi sin darte cuenta, es casi un método socrático de aprender. 

Bueno, basta de pedantería mía y vamos "al meollo" (algunos tipos serios y aburridos además somos pedantes hasta decir basta).


Tutorial:

Paso 1: Enlazar Vivado con Matlab.

Tal y como lo he planteado la idea que te puedes hacer es que se empieza por abrir el Matlab y luego el Simulink, si lo haces así lo más probable es que no se carguen las librerías de XILINX en Matlab y SIMULINK. 

Se empieza por el nexo de unión entre estos dos softwares (el paquete de aplicaciones de XILINX y Matlab-SIMULINK), el System Generator

Para que todo te funcione correctamente antes deberías haber configurado ese nexo de unión mediante el System Generator Matlab Configurator.

Si leíste los tutoriales que dejé para pasar de Vivado a Simulink, y lo pusiste en práctica en tu ordenador (computador o computadora), puedes saltarte directamente esta parte.

 En caso contrario es aconsejable que sigas leyendo porque sino no te va a funcionar.

El proceso para enlazar Vivado con Matlab lo explico en el "1er Paso" de la entrada:


Con el primer apartado "1er Paso" es suficiente, no hace falta que lo leas todo si no quieres.

Paso 2: Abrir Matlab y luego SIMULINK mediante el System Generator.

Dónde tengas tu XILINX, encontrarás el System Generator - entre otras aplicaciones del paquete de software-. 

Según tu sistema operativo tendrás que navegar hasta su ubicación. Por ejemplo, si tienes un Widows 7 (XP o Vista), una forma puede ser clic en inicio, programas, xilinx....

Yo lo tengo en el escritorio como un enlace directo.



Haces doble clic en él y se abre el Matlab. Una vez abierto Matlab abrimos Simulink para lo cual clic con el ratón en el icono que señalo a continuación:



Después de un rato más o menos grande (según la potencia de tu ordenador, las condiciones en que lo tengas etc), se abre la interfaz de Simulink, que en las últimas versiones de Matlab es así (antes se abría primero las librerías, y luego creabas el modelo):



En ese cuadro de diálogo o ventana emergente que se nos abre, hacemos clic en Blank Model para crear nuestro modelo desde cero.


Aparece nuestro modelo aún "virgen":


Paso 3: Creación del modelo de Simulink.

Para crear nuestro modelo tenemos que abrir las librerías de Simulink (Library Browser), para ello clic dónde señalo:


Tenemos:


Fijemosnos en el "Simulink Library Browser", porqué si todo ha ido bien se deben de haber cargado las nuevas librerías de Xilinx, si es la primera vez que usas el "System Generator" seguramente -si la memoria no me falla-  que a la vez que se abre el "Simulink Library Browser, se estará procesando la carga de las librerías en él.

Como son las últimas en incorporarse deslizamos el scrollbar (o barra de deslizamiento en este caso vertical) hacia abajo.





Desplegando la lista de esas librerías tenemos dentro de ellas otras:



Dentro de la librería Xilinx Blockset vamos a hacer uso de la Basic Elements.


Haciendo doble clic en Basic Elements tenemos:


Vemos que dentro de la sub-librería Basic Elements tenemos a su vez un conjunto de bloques de diseño que se pueden incorporar a nuestro modelo aún vacío de Simulink.

El primero (y muy importante en este caso), es el System Generator que se destaca de otros por ser el primero de color rojo y con una forma característica de 'E' mayúscula.

Hay dos formas de incorporar un bloque de diseño a el modelo, ambas muy sencillas e intuitivas.
Una es "pinchando" (o haciendo clic en él) y arrastrando con el ratón a la ventana del modelo.

Forma 1:


Forma 2:

Otra es hacer clic derecho en el bloque seleccionado y en la lista desplegable que aparece clic en Add block to model 'nombre del modelo', en este caso no le hemos puesto aún nombre y por defecto se denomina untitled, así que sería Add block to model untitled.




Una vez está el bloque en el modelo, lo mantenemos seleccionado - y sino lo está lo seleccionamos- para desplazarlo arrastrando con el ratón. Yo lo suelo ver en el extremo superior izquierda en los tutoriales de Internet, y a mi me parece un buen lugar para colocar el System Generator, así que "pincho" (un sólo clic del botón izquierdo del ratón) en él y lo arrastro (desplazamos con el ratón) a ese lugar.


Aún nos queda configurar el bloque System Generator dentro del modelo, para lo cual hacemos doble clic en el icono que nos ha quedado en el modelo de Simulink.


Tal y como está configurado en la anterior figura nos valdría (es como me viene a mi por defecto), sobre todo por el hecho de que no vamos a implementar el sistema digital que estamos diseñando en ningún hardware. Si pudiera lo implementaría en la Spartan-3E, pero en las nuevas versiones de Vivado ya no se encuentra la Spartan-3E y menos la placa de desarrollo Core3S250E.

Pero vamos a suponer que quisiéramos implementar lo para una versión muy concreta de FPGA, por ejemplo la  Kintex7 en lugar de una Zynq que es la que viene por defecto, En el drop-down list del campo Part, vamos a hacer:


Y nos queda:


En esta ocasión tampoco nos preocupa demasiado las pestañas Clocking y General, lo que venga por defecto estará bien.

Ahora sólo falta pulsar Apply y luego OK, tras lo cual conviene salvar el modelo y darle nombre. Más adelante haremos uso del botón Generate justo a la izquierda de OK.




Por tanto hacemos clic en File, Save As, y navegamos hasta dónde deseemos guardar el modelo de Simulink.




Yo le damos el nombre que queramos (yo le he dado el nombre de mux2a1_blog) y pulsamos en guardar.

Continuamos construyendo el modelo, el próximo bloque que vamos a añadir también está en Basic Elements de la librería de BlockSet Xilinx, y es obviamente el bloque que corresponde al multiplexor denominado Mux, en realidad todos los bloques que vamos a usar en este tutorial están es Basic Elements.



Ahora hacemos doble clic sobre el bloque Mux seleccionado en el modelo de Simulink (que yo he llamado mux2a1_blog) para configurarlo.

Tenemos la ventana emergente:




La pestaña Basic la dejamos tal cual está en la figura que es como viene por defecto.

Clic en la pestaña Output:


Al igual que antes por defecto tendremos lo que se muestra en la figura anterior (sino es así ponlo de esta forma please).

Ahora Apply y Ok.

Antes de seguir, voy a comentar (estoy partiendo de la base de que algún lector no tiene mucha experiencia con Simulink) que los bloques de diseño que vamos incorporando a nuestro modelo se pueden cambiar de tamaño, tanto en horizontal como en vertical.

En este caso nos interesa cambiar de tamaño el bloque Mux. Para ello basta con tener seleccionado el bloque e ir arrastrando con el ratón en los extremos cuando el puntero del ratón lo señala.



Seguimos construyendo del modelo, como dijimos antes nos basta con los bloques de Basic Elements.



Ahora realizamos las conexiones, es fácil e intuitivo, pero ya que me estoy metiendo a tanto nivel de detalle voy a dejar algunas figuras que dan una idea de como se hace.






Hacemos lo mismo con el resto de conexiones y nos queda:


Ahora tenemos que configurar los nuevos bloques introducidos, los del tipo "Gateway In" y "Gateway Out".


Aparece una ventana emergente o cuadro de diálogo.


Por defecto yo lo tengo de esta manera:



Lo modificamos para que quede como sigue:


Ahora seleccionamos la pestaña Implementation:


La dejamos tal y como está. Apply y Ok.

Hacemos exactamente igual con Gate Way In1 y Gate Way In2.

Con Gate Way Out no hay que hacer cambios, no obstante le vamos a echar un vistazo.



No changes!, keep the same! (spanglish).

El resto de bloques ya no son de las librerías de Xilinx, son de la principal de Simulink (la primera, más concretamente de Sinks, Sources y Signal Routing).



Finalmente quedaría:



No obstante, para no perder mucho tiempo buscando en las librerías, puedes hacer una cosa que es usar el buscador de las librerías (Libraries Search).





Enter (o Intro) y se obtienen los resultados de la búsqueda:


Para dar valores a los bloques Constant, doble clic en cada uno de ellos:


Y modificamos:


Ahora ya lo tenemos completado, ahora guardamos los cambios (clic en save):


Paso 4: Generar, compilar y simular.

Para generar el código (que luego se podrá abrir con Vivado), compilarlo y simularlo en Simulink, volvemos a hacer doble clic en el bloque de diseño System Generator.


Una vez hecho doble clic, tarde más o menos, se abrirá la ventana que ya abrimos.


En ella pulsamos el botón generate, y se abre una pequeña ventana con el logo rojo en forma de 'E' cambiando a distintas formas e indicando que se está procesando la generación y compilación.



Finalmente el proceso de generación de código y compilación termina, y tan sólo tenemos que dar en OK en esa pequeña ventana en la que el logo iba tomando distintas formas y ahora permanece de nuevo con su forma característica fija y con el mensaje "Generation Compiled".


Una vez hecho clic en OK cerramos la ventana de informes y pulsamos en el botón de OK en la ventana de System Generator.



Antes de abrir el código VHDL  en Vivado, estamos ya en disposición de simular con el Simulink.
Para mostrar como la simulación, si todo ha ido bien resulta, dejo un clip.

 


-------------------------------------------------------
Nota:

Si lo ves muy pequeño haz clic en fullscreen en el extremo inferior izquierda, y luego pulsa Esc del teclado. 



-------------------------------------------------------


Paso 5: Obtener el código VHDL en Vivado.

Para ello ejecutamos Vivado, yo lo tengo como acceso directo en el escritorio.




En mi caso tarda un poco en abrirse un poco (es un programa potente), si es tu caso también un poco de paciencia.


Una vez abierto el interfaz de Vivado clic en OpenProject y navegamos hasta el lugar dónde hemos guardado el modelo de Simulink.


En dicha carpeta ya se ha creado otra llamada netlist, entramos en ella.


Dentro de ella encontramos una llamada hdl_netlist nos introducimos en ella. 



Dentro de la carpeta en hdl_netlist hacemos clic en el archivo con el icono característico de Vivado y con extensión '.xpr'. En mi caso es el archivo mux2a1_blog.xpr.


Clic en Ok.


Tenemos lo siguiente:


Si nos fijamos en la ventana dentro del interfaz llamada Sources, tenemos ahí varios archivos con extensión '.vhd', es ahí dónde se ha creado no uno, sino varios códigos VHDL del multiplexor 2 a 1.


El principal es el mux2a1_blog-estructural (mux2a1_blog.vhd), si hacemos doble clic en él, 


Justo a la derecha de esta ventana se nos despliega los códigos que son:

-- Generated from Simulink block mux2a1_blog_struct

-- Generated from Simulink block

-- Generated from Simulink block

Estos sólo dentro de la raíz de mux2a1_blog-estructural (mux2a1_blog.vhd).




Si encuentro tiempo los explicaré con más detalle en el futuro, no obstante por si desea el lector o lectora echarles un ojo, los dejo en el siguiente cuadro para copiar y pegar.



-- Generated from Simulink block mux2a1_blog_struct library IEEE; use IEEE.std_logic_1164.all; library xil_defaultlib; use xil_defaultlib.conv_pkg.all; entity mux2a1_blog_struct is port ( gateway_in : in std_logic_vector( 1-1 downto 0 ); gateway_in1 : in std_logic_vector( 1-1 downto 0 ); gateway_in2 : in std_logic_vector( 1-1 downto 0 ); clk_1 : in std_logic; ce_1 : in std_logic; gateway_out : out std_logic_vector( 1-1 downto 0 ) ); end mux2a1_blog_struct; architecture structural of mux2a1_blog_struct is signal gateway_in_net : std_logic_vector( 1-1 downto 0 ); signal gateway_in1_net : std_logic_vector( 1-1 downto 0 ); signal gateway_in2_net : std_logic_vector( 1-1 downto 0 ); signal mux_y_net : std_logic_vector( 1-1 downto 0 ); signal clk_net : std_logic; signal ce_net : std_logic; begin gateway_in_net <= gateway_in; gateway_in1_net <= gateway_in1; gateway_in2_net <= gateway_in2; gateway_out <= mux_y_net; clk_net <= clk_1; ce_net <= ce_1; mux : entity xil_defaultlib.sysgen_mux_36237b0251 port map ( clr => '0', sel => gateway_in_net, d0 => gateway_in1_net, d1 => gateway_in2_net, clk => clk_net, ce => ce_net, y => mux_y_net ); end structural; -- Generated from Simulink block library IEEE; use IEEE.std_logic_1164.all; library xil_defaultlib; use xil_defaultlib.conv_pkg.all; entity mux2a1_blog_default_clock_driver is port ( mux2a1_blog_sysclk : in std_logic; mux2a1_blog_sysce : in std_logic; mux2a1_blog_sysclr : in std_logic; mux2a1_blog_clk1 : out std_logic; mux2a1_blog_ce1 : out std_logic ); end mux2a1_blog_default_clock_driver; architecture structural of mux2a1_blog_default_clock_driver is begin clockdriver : entity xil_defaultlib.xlclockdriver generic map ( period => 1, log_2_period => 1 ) port map ( sysclk => mux2a1_blog_sysclk, sysce => mux2a1_blog_sysce, sysclr => mux2a1_blog_sysclr, clk => mux2a1_blog_clk1, ce => mux2a1_blog_ce1 ); end structural; -- Generated from Simulink block library IEEE; use IEEE.std_logic_1164.all; library xil_defaultlib; use xil_defaultlib.conv_pkg.all; entity mux2a1_blog is port ( gateway_in : in std_logic; gateway_in1 : in std_logic; gateway_in2 : in std_logic; clk : in std_logic; gateway_out : out std_logic ); end mux2a1_blog; architecture structural of mux2a1_blog is attribute core_generation_info : string; attribute core_generation_info of structural : architecture is "mux2a1_blog,sysgen_core_2016_2,{,compilation=HDL Netlist,block_icon_display=Default,family=kintex7,part=xc7k325t,speed=-2,package=ffg900,synthesis_language=vhdl,hdl_library=xil_defaultlib,synthesis_strategy=Vivado Synthesis Defaults,implementation_strategy=Vivado Implementation Defaults,testbench=0,interface_doc=0,ce_clr=0,clock_period=10,system_simulink_period=1,waveform_viewer=0,axilite_interface=0,ip_catalog_plugin=0,hwcosim_burst_mode=0,simulation_time=10,mux=1,}"; signal clk_1_net : std_logic; signal ce_1_net : std_logic; begin mux2a1_blog_default_clock_driver : entity xil_defaultlib.mux2a1_blog_default_clock_driver port map ( mux2a1_blog_sysclk => clk, mux2a1_blog_sysce => '1', mux2a1_blog_sysclr => '0', mux2a1_blog_clk1 => clk_1_net, mux2a1_blog_ce1 => ce_1_net ); mux2a1_blog_struct : entity xil_defaultlib.mux2a1_blog_struct port map ( gateway_in(0) => gateway_in, gateway_in1(0) => gateway_in1, gateway_in2(0) => gateway_in2, clk_1 => clk_1_net, ce_1 => ce_1_net, gateway_out(0) => gateway_out );


Por el momento lo dejamos aquí, espero que este tutorial resulte útil :).

-Fin-