domingo, 15 de marzo de 2015

Luces estacionarias dobles con salida optoacoplada utilizando Tarjeta Digilent Basys 2 con VHDL

Se prueba inicialmente con un LED disponible en la tarjeta y luego se trabajan las estacionarias con salida optoacoplada a fin de protejer la tarjeta al no exigirle más corriente de lo permitido:

La tarjeta Digilent Basys 2 dispone de un reloj a cristal de 50 Mhz, y el Led hay que hacerlo encender y apagar con una frecuencia de 1 Hz, de tal manera que lo primero requerido es un divisor de frecuencia.

El divisor de frecuencia es un componente para reducir la frecuencia de entrada. Éste se implementa con ayuda de una Escala  y un contador, donde la Escala  es la relación o división entre la frecuencia de entrada y la frecuencia de salida deseada: 

Escala = \frac{f_{entrada}}{f_{deseada}}  


Recordemos que la frecuencia y el periodo de la señal son inversamente proporcionales, tal como se observa en las ondas mostradas, las cuales corresponden a un contador binario ascendente de 3 bits.

Como el contador cuenta del 0 al 7 (modo 8) al dividir la señal de entrada (50 Mhz) por 8 nos dá 6.25 Mhz, en el bit más significativo del contador.

Como el cristal tiene una frecuencia de 50MHz ( frecuencia de entrada) y deseamos una salida de  1 Hz, tenemos que:
Escala = 50 Mhz / 1Hz = 50 000 000 

Si el reloj tiene el mismo tiempo en alto que en bajo:

t_{alto} = t_{bajo} = \frac{50 000 000}{2} = 25 000 000

SI empezamos el conteo desde cero, y  un contador al llegar a  24 999 999 genera un pulso, esto quiere decir que la frecuencia de salida , de los pulsos generados,  debe ser de 1 Hz.

Veamos el programa en VHDL:

--Divisor de frecuencia de 50MHz a 1Hz para parpadeo de LED
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
 entity clk1Hz is
    Port (
        clk50Mhz: in  STD_LOGIC;
        reset   : in  STD_LOGIC;
        led     : out STD_LOGIC
    );
end clk1Hz;

architecture Behavioral of clk1Hz is
    signal pulso: STD_LOGIC;
    signal contador: integer range 0 to 24999999 := 0;
begin
    divisor_frecuencia: process (reset, clk50Mhz) begin
        if (reset = '0') then
            pulso <= '0';
            contador <= 0;
        elsif rising_edge(clk50Mhz) then
            if (contador = 24999999) then
                pulso <= NOT(pulso);
                contador <= 0;
            else
                contador <= contador+1;
            end if;
        end if;
    end process;
     led  <= pulso;
end Behavioral;


El contador dispone de una entrada de reset que se activa con nivel bajo, es decir si reset = 0, sin importar el flanco del reloj el contador se resetea. 
La primera vez que el contador llega al 24999999, la señal interna pulso pasa del nivel bajo a nivel alto, el contador pasa a 0, y vuelve a comenzar a contar, mientras la entrada reset sea alta, y al volver a llegar a  

24999999,pulso pasa ahora de 1 a 0, completando un pulso completo, o sea un periodo de reloj; 

de esta forma la salida es de solo 1 Hz.


¡ Cada 50 millones de pulsos a la entrada se produce 1 pulso a la salida !

Con captura esquemática es imposible lograr esto; en cambio con lenguaje VHDL se hace de una
forma muy sencilla. Por eso VHDL se impone cada día mas, como lenguaje para describir hardware y efectuar en forma simple y práctica el diseño digital, pero se requiere, por ejemplo, de una FPGA 
donde el programa se pueda aplicar e implementar.


Con el navegador de proyectos de Xilinx ISE 10.1  creamos como nuevo proyecto: LedParpadeo, y como nueva fuente en Módulo VHDL: clk1Hz. 

Copiamos y pegamos el programa ya visto, salvamos y chequeamos sintaxis

Para este caso no es necesario efectuar la simulación.

Procedemos a elaborar la síntesis y la asignación de pines. El pin del  Clock de 50 MHZ  es B8.

Procedemos ahora a estudiar la salida optoacoplada con el chip de 4 pines PC817, el cual se muestra en la figura siguiente: 



El chip PC817 dispone internamente de un diodo infrarojo y un fototransistor tal como se muestra en el siguiente diagrama




En muchas ocasiones se hace indispensable, para evitar ruidos que pueden incidir en un mal funcionamiento de un circuito secuencial, el uso de un optoacoplador que aisle la carga del circuito secuencial. Para este situación es muy util implementar una salida optoacoplada con el PC817, tal como se muestra en el siguiente esquema para manejar a traves de un relé de 5 voltios  una bombilla azul y otra roja, a 120 voltios AC.




Si la Entrada es 0 el relé está desenergizado y se activa la bombilla roja, y si la entrada es 1 se energiza el relé y se activa la bombilla roja.  Como el motor funciona al crearse un campo electromagnético en el,  si no existiera el aislamiento eléctrico causará ruido y molestaría en el circuito lógico que lo está activando, y por la alta corriente exigida dañaría la salida de la FPGA.

 El  Optoacoplamiento, quiere decir que el acoplamiento de las bombillas con el circuito lógico que lo activa, se hace en forma óptica, a través del diodo infrarojo y el fototransistor que existen en el interior del chip de 4 pines PC817. Con el 0 lógico el led infrarojo no emite luz, y el fototransistor está abierto, en cambio, si se tiene un 1 lógico a la entrada, el led emite luz. y el fototransistor conduce.


Observe además que se están utilizando  tanto los contactos normalmente abiertos como los normalmente cerrados, o sea los 5 pines de que dispone el relé de 5 voltios.El diodo de conmutacion dispuesto inversamente y en paralelo con la bobina del relevo actúa como supresor de picos de corriente cotrarrestando la Ley de Lenz (  VL = - L di / dt), y evitando que el voltaje autoinducido negativo que se genera en la bobina del relevo queme el transistor 2N2222A que se está utilizando como interface entre la salida del optoacoplador y la bobina o entrada del relevo.

Mas información sobre este interesante tema del optoacoplamiento se puede obtener en http://es.wikipedia.org/wiki/Optoacoplador

miércoles, 28 de enero de 2015

LA VELA MÁGICA: Proyecto de laboratorio

La fotografía fue tomada en Expociencia Juvenil en Corferias donde se presentó este proyecto por parte del Club de Física del INEM Santiago Perez-Tunal de Bogotá:


Veamos los detalles de los elementos que intervienen  en el desarrollo del proyecto:

Se llama fototransistor a un transistor sensible a la luz. La luz incide sobre la región de base, generando portadores en ella. Esta carga de base lleva el transistor al estado de conducción.

En el mercado se encuentran fototransistores tanto con conexión de base como sin ella y tanto en cápsulas plásticas como metálicas (TO-72, TO-5) provistas de una lente.


El símbolo del fototransistor es el mostrado en la figura: 


Para información sobre fototransistor consultar: http://es.wikipedia.org/wiki/Fototransistor

Veamos un esquema eléctrico de la Vela Electrónica:

Como elemento de memoria biestable se utiliza un flip-flop SET RESET Latch implementado con dos compuertas NOR 74LS02:

Observe además  que la base del fototransistor de tres pines  no está conectada. Se deja al aire.

 En lugar del fototransistor se puede utilizar un fotodiodo o una fotoresistencia, en un divisor de tensión. Consultar http://es.wikipedia.org/wiki/Fotodiodo , o, http://es.wikipedia.org/wiki/Fotorresistencia

“La fotorresistencia, como su nombre lo indica, es un resistencia cuyo valor depende de la energía luminosa incidente en ella, específicamente son resistencias cuyo valor de resistividad disminuye a medida que aumenta la energía luminosa incidente sobre ella y viceversa. Una fotorresistencia se compone de un material semiconductor cuya resistencia varia en función de la iluminación. La fotorresistencia reduce su valor resistivo en presencia de rayos luminosos.

Es por ello por lo que también se le llama resistencias dependientes de luz (LDR: light dependent resistors), fotoconductores o células fotoconductoras”.





miércoles, 26 de noviembre de 2014

Máquina ASM en FPGA con VHDL


Veamos el diagrama ASM:

El control en su forma esquemática debe ser tal como se muestra.

El control se puede obtener como una Máquina de Moore así:

El contador C1 tiene dos detectores D1 y D2:


C2  tiene el detector D3:

Se requiere dividir los 50 Mhz para obtener un reloj de 1 HZ:

Se añadió al control una salida para poder manejar el contador C2 mediante su enable:


Se usaron Flip-flops D, en lugar de J-K:

Los flip-flops F1,F2, y F3, tienen códigos idénticos.

Veamos el de F1:

Veamos por último el código VHDL del circuito final interconectando los bloques componentes  anteriores:

Se implementó en la tarjeta Basys 2 Digilent.

Veamos el archivo UCF de asignación de pines en la FPGA:


Veamos el esquemático RTL del circuito final:

viernes, 24 de octubre de 2014

Letrero con matriz de leds en FPGA

Se trata de obtener por pantallazos en una matriz de leds de 7 filas, 5 columnas los caracteres que se muestran: 
  Las 7 filas de la matriz, se conectan a 7 salidas de la FPGA dispuesta en la tarjeta Digilent en sus puertos de expansión.  Los cátodos de los leds, en las columnas se manejan a través de un contador de anillo de 5 bits, activo por nivel bajo.   Sólo una columna se energiza cada vez, pero al hacer la secuencia del contador de anillo muy rápidamente cada 0,01 segundo, el ojo humano, por la persistencia de la imágen en la retina, ve todas las 5 columnas como si estuvieran todas energizadas, y pareciese que todos los Leds que generan el caracter estuvieran encendidos, pero en realidad sólo se estan encendiendo columnna por columna, de acuerdo al CERO que envía el Contador de Anillo a todos los 7 leds de cada columna y aterrizarlos.  Por medio de la FPGA  se envían los UNOS para que se enciendan los leds requeridos para que vaya formando el caracter. Por ejemplo, para formar la U, inicialmente la memoria debe enviarle a los leds de la primera columna 1111110, luego 0000001 a la segunda columna al tiempo que se energiza esa columna por el contador de anillo, después eso mismo a la tercera y cuarta columna a medida que el contador de anillo se desplaza, y al final a los 0,05 segundos, cuando se energiza la quinta columna, la más a la derecha, la memoria debe enviar nuevamente 1111110,  y esto debe  hacerlo repetitivamente unas 20 veces, para que el caracter, en este caso la U se observe durante 1 segundo ( 0,05 * 20 = 1). Luego se continúa en igual forma con los otros dos caracteres, la A y la N, dejando en blanco durante 1 segundo el display, y luego seguir la secuencia  desplegando el mensaje UAN blanco, UAN blanco,.. indefinidamente.

Se utilizó una matriz miniatura 

En la implementación se utlizan 3 puertos de expansión dispuestas en la tarjeta Digilent Basys 2:
Se pueden observar en el gráfico anterior las resistencias de protección contra corto circuitos a las salidas, lo mismo que Diodos de protección ESD a tierra contra descargas electrostáticas.

Veamos la conexión de pines:

Veamos ahora el programa final en VHDL:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity Letrero_UAN is
    Port ( CLOCK50MHZ : in  STD_LOGIC;
           COL : out  STD_LOGIC_VECTOR (4 downto 0);
           FIL : out  STD_LOGIC_VECTOR (6 downto 0));
end Letrero_UAN;

architecture Behavioral of Letrero_UAN is
signal Xclk: STD_LOGIC;
signal Xclk_letras: STD_LOGIC;
signal Xq  : STD_LOGIC_VECTOR (2 downto 0);
signal Xcol: STD_LOGIC_VECTOR (4 downto 0);
signal XSL : STD_LOGIC_VECTOR (1 downto 0);

component Divisor 
    Port ( CLK50Mhz : in  STD_LOGIC;
           CLK1khz   : out STD_LOGIC);
end component;

component Cont 
    Port ( Clk : in  STD_LOGIC;
             Q : out  STD_LOGIC_VECTOR (2 downto 0));
 end component;


component anillo
    Port ( Entrada : in  STD_LOGIC_VECTOR (2 downto 0);
           Salida : out  STD_LOGIC_VECTOR (4 downto 0));
end component;

component Memoria 
      Port ( Selector_letra: in STD_LOGIC_VECTOR (1 downto 0);
       Direccion : in  STD_LOGIC_VECTOR (4 downto 0);
           Datos : out  STD_LOGIC_VECTOR (6 downto 0));
end component;

component Cont_letras 
    Port ( CLK_letras : in  STD_LOGIC;
           Q : out  STD_LOGIC_VECTOR (1 downto 0));
end component;

component Reloj_letras 
    Port ( CLK50Mhz : in  STD_LOGIC;
           CLK1hz   : out STD_LOGIC);
end component;

begin
paso1: Divisor port map (CLOCK50MHZ, Xclk);
paso2: Cont    port map (Xclk, Xq); 
paso3: anillo  port map (Xq, Xcol);
paso4: Memoria port map (XSL,Xcol, FIL );
paso5: Reloj_letras port map (CLOCK50MHZ, Xclk_letras);
paso6: Cont_letras port map (Xclk_letras, XSL);

COL <= Xcol;

end Behavioral;

El esquemático RTL es el siguiente:

A continuación  el código VHDL de  cada  componente:

-- DIVISOR 1 KHZ

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity Divisor is
    Port ( CLK50Mhz : in  STD_LOGIC;
           CLK1khz   : out STD_LOGIC);
end Divisor;

architecture Behavioral of Divisor is
signal pulso: STD_LOGIC := '0';
signal contador: integer range 0 to 24999 := 0;

begin
process (CLK50Mhz)
begin
if (CLK50Mhz'event and CLK50Mhz = '1') then 
if (contador = 24999) then
                pulso <= NOT(pulso);
                contador <= 0;
            else
                contador <= contador+1;
            end if;
    end if;
  end process;
 CLK1khz <=  pulso;
end Behavioral;

................................................................................................................................................

-- CONTADOR DEL 0 AL 4
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity Cont is
    Port ( Clk : in  STD_LOGIC;
             Q : out  STD_LOGIC_VECTOR (2 downto 0));
            
end Cont;

architecture Behavioral of Cont is
signal count: STD_LOGIC_VECTOR (2 downto 0);
begin
process (Clk) 
begin
   if count = "101" then 
      count <= "000";
   elsif Clk ='1' and Clk'event then
             count <=  count + 1;
   end if;

end process;
Q <= count;

end Behavioral;

................................................................................................................................................

-- CONTADOR DE ANILLO
-
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;


entity anillo is
    Port ( Entrada : in  STD_LOGIC_VECTOR (2 downto 0);
           Salida : out  STD_LOGIC_VECTOR (4 downto 0));
end anillo;

architecture Behavioral of anillo is

begin
process(Entrada)
begin

            case Entrada is
            when "000" => Salida <= "01111";
            when "001" => Salida <= "10111";
            when "010" => Salida <= "11011";
            when "011" => Salida <= "11101";
            when "100" => Salida <= "11110";
when others => Salida <= "00000";
         end case;

end process;


end Behavioral;

................................................................................................................................................

-- DIVISOR DE 1 HZ 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity Reloj_letras is
    Port ( CLK50Mhz : in  STD_LOGIC;
           CLK1hz   : out STD_LOGIC);
end Reloj_letras;

architecture Behavioral of Reloj_letras is
signal pulso: STD_LOGIC := '0';
signal contador: integer range 0 to 24999999 := 0;

begin
process (CLK50Mhz)
begin
if (CLK50Mhz'event and CLK50Mhz = '1') then 
if (contador = 24999999) then
                pulso <= NOT(pulso);
                contador <= 0;
            else
                contador <= contador+1;
            end if;
    end if;
  end process;

 CLK1hz <=  pulso;

................................................................................................................................................

-- CONTADOR PARA  DESPLEGAR LAS LETRAS UAN

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;


entity Cont_letras is
    Port ( CLK_letras : in  STD_LOGIC;
           Q : out  STD_LOGIC_VECTOR (1 downto 0));
end Cont_letras;

architecture Behavioral of Cont_letras is
signal count: STD_LOGIC_VECTOR (1 downto 0);
begin
process (CLK_letras) 
begin
   if (CLK_letras = '1' and CLK_letras'event) then
      count <= count + 1;
   end if;
end process;

 Q <= count;


end Behavioral;
................................................................................................................................................

-- MEMORIA CON LAS LETRAS A DESPLEGAR

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;


entity Memoria is
    Port ( Selector_letra: in STD_LOGIC_VECTOR (1 downto 0);
       Direccion : in  STD_LOGIC_VECTOR (4 downto 0);
           Datos : out  STD_LOGIC_VECTOR (6 downto 0));
end Memoria;


architecture Behavioral of Memoria is
begin

process (Selector_letra,Direccion)
begin
if Selector_letra = "00"  then


         case Direccion is   -- Letra U
            when "01111" => Datos <= "1111110";
            when "10111" => Datos <= "0000001";
            when "11011" => Datos <= "0000001";
            when "11101" => Datos <= "0000001";
when "11110" => Datos <= "1111110";
            when others => Datos <=  "0000000";
         end case;

elsif Selector_letra = "01"  then


          case Direccion is    -- Letra A
            when "01111" => Datos <= "0111111";
            when "10111" => Datos <= "1001000";
            when "11011" => Datos <= "1001000";
            when "11101" => Datos <= "1001000";
when "11110" => Datos <= "0111111";
            when others => Datos <=  "0000000";
         end case;


elsif Selector_letra = "10"  then


  case Direccion is    -- Letra N
            when "01111" => Datos <= "0111111";
            when "10111" => Datos <= "1000000";
            when "11011" => Datos <= "1000000";
            when "11101" => Datos <= "1000000";
when "11110" => Datos <= "0111111";
            when others => Datos <=  "0000000";
         end case;
-- end process ;

else 
   

  case Direccion is  -- Espacio en Blanco
            when "01111" => Datos <= "0000000";
            when "10111" => Datos <= "0000000";
            when "11011" => Datos <= "0000000";
            when "11101" => Datos <= "0000000";
when "11110" => Datos <= "0000000";
            when others => Datos <=  "0000000";
         end case;


End if;

end process ;


end Behavioral;

.....................................................................................................................................................

Fotografía: 




viernes, 22 de noviembre de 2013

Evaluación lúdica sobre Máquinas de Estado Algorítmicas

Para todos  los puntos tenga en cuenta la siguiente información, y marque la respuesta correcta en el test.

El siguiente diagrama ASM  corresponde a un sistema digital donde en el procesador de datos hay un motor DC que se maneja a través de un flip-flop J-K de salida M y un contador de década Ascendente/Descendente: C.    S es un pulsador de inicio (Start) y D1,D2 son detectores para el contador.


Solución:
Respuestas al Test de Selección Múltiple con única respuesta:
1. C     2.C     3.B     4.A     5.D     6.B     7.C     8.A     9.B     10.D     11.C     12.B     13.C     14.B
15.A     16.A     17.B     18.D

Mensaje desencriptado: