Circuitos Combinacionales y Secuenciales
Circuitos Combinacionales y Secuenciales
➢ Résumé:
Dans cette deuxième pratique, des circuits séquentiels et combinatoires ont été réalisés pour contrôler des
éléments tels que des moteurs pas à pas, des projecteurs, des décodeurs, des moteurs bipolaires, ainsi que les
circuits nécessaires à une alimentation externe de ces appareils. Les langages VHDL et Verilog ainsi que le
FPGA AMIBA2 ont été utilisés. Le fonctionnement des appareils est rapporté à travers des photos, des
simulations et des liens vers des vidéos YouTube, en plus de les avoir présentés en classe
➢ Introducción:
• Servomotor
Un servomotor es un dispositivo similar a un motor de corriente continua que tiene la capacidad de ubicarse
en cualquier posición dentro de su rango de operación, y mantenerse estable en dicha posición.
El servomotor lleva incorporado un sistema se regulación que puede ser controlado tanto en velocidad como
en posición.
Es posible modificar un servo para obtener un motor de corriente continua que, si bien ya no tiene la capacidad
de control del servo, conserva su fuerza, velocidad y baja inercia que caracteriza a estos dispositivos.
Para posicionar el servomotor es necesario aplicarle un pulso eléctrico cuya duración determinará el ángulo
de giro del motor.
En la figura muestra que para un tiempo de 1ms el eje del motor estará en la posición izquierda, para un pulso
de 1.5ms se colocará en medio y para pulsos de 2ms se moverá hasta el extremo derecho.
Las características de un circuito UART para comunicación com el módulo BT HC-06 o similar, usando el
protocolo RS232, que inicie con un bit de start y termine con un bit de stop, son: bus de datos de 8 bits, un
bit de stop y un bit de paridad, como se muestra en la figura 1, aunque otra alternativa con bit de paridad se
muestra en la figura 2.
Para la recepción de datos del módulo BT se implementa una máquina de estados finitos tipo Mealy de solo
dos estados, mostrada en la figura 3, la cual funciona con las señales Rx (terminal D0 del HC-06) que detecta
el primer nivel bajo para dar inicio a la recepción, y la señal done que indica cuando terminó de recibir los 8
bits del dato de Rx.
El primer estado EDO_1 espera a que el receptor tenga el primer bit con cero que es el bit de start del protocolo
RS232 para pasar al segundo estado EDO_2. En el EDO_2 se realizan varios procesos de la recepción, el
primero y más importante es la generación de la señal de captura (capture) a partir del contador “c2” que tiene
3 veces la velocidad de transmisión. Con la señal de captura se guardan los datos de Rx con un registro de
corrimiento, se activa un contador i que cuenta de 0 a 8 (el bit de start y los 8 bits de datos), y por último la
actualización de la máquina de estados, como se muestra en la figura 4.
Figura4: Actualización de la máquina de estados
• Motor a pasos
El motor paso a paso es un motor de corriente continua sin escobillas en el que la rotación se divide en un cierto
número de pasos resultantes de la estructura del motor. Normalmente, una revolución completa del eje de 360°
se divide en 200 pasos, lo que significa que se realiza una sola carrera del eje cada 1,8°. También hay motores
donde la carrera del eje se realiza cada 2; 2,5; 5, 15 o 30°.La funcionalidad descrita es posible gracias a la
construcción especial del motor paso a paso. Debido al hecho de que la rotación completa del eje se divide en
ciertas secciones discretas, el motor paso a paso no gira suavemente, sino que realiza saltos y cruza estados
intermedios, por lo que el funcionamiento del motor paso a paso se acompaña de un sonido y vibración
característicos.
El principio de funcionamiento del motor paso a paso en el modo de paso completo se ilustra en el dibujo. En
este modo, el motor gira en un ángulo resultante de su construcción, que puede ser, por ejemplo, 1,8°. Como es
fácil de calcular, en tal caso es necesario dar 200 pasos para un giro completo (200×1.8° = 360°).
El recorrido del eje se realiza después de energizar una o dos bobinas. El funcionamiento de una sola bobina
requiere una potencia mínima del controlador. En funcionamiento bifásico, con suministro de bobinas opuestas,
se requiere el doble de potencia, pero también aumentan la velocidad y el par.
El principio de funcionamiento del motor en el modo de medio paso se muestra en el dibujo 2. Como su nombre
lo indica, en este modo la carrera discreta del rotor se divide por 2 y, haciendo una sola carrera, gira la mitad del
ángulo nominal. Con referencia al ejemplo anterior, una sola carrera será de 0,9°, mientras que el número de
pasos por revolución completa aumentará a 400.
En el trabajo en modo de medio paso, se requiere energía alterna para las dos fases (bobinas). Esto da como
resultado un aumento del par en comparación con el funcionamiento con un suministro monofásico, un
funcionamiento "más suave" del motor y la duplicación de la resolución angular mencionada anteriormente.
➢ Desarrollo:
Para el circuito combinacional se optó por realizar el sistema de detección de personas en un torniquete del
inciso a), y los sistemas correspondientes a los incisos c) y d) como circuitos secuenciales.
a) Sistema de detección de paso de personas:
c) Sistema de detección de llenado de un tinaco con sensores:
d) Contador de objetos:
a) Sistema de detección de paso de personas por un torniquete que accione una alarma tipo “beep”, que
encienda un foco de 120V y que prenda un vibrador, además de indicar en el display la letra “A”.
Para este problema realizamos un código que enciende un motor vibrador, activa un buzzer que genera una alarma
de un solo beep, enciende un display de 7 segmentos para mostrar la letra A y enciende un foco de 120V. Todos
estos componentes se activan cuando, mediante uno de los pines tipo hembra que funciona como entrada, la
tarjeta detectaba energía.
Pines de
voltaje
de 3.3V
Pines de
Tierra
(GND)
Mediante el voltaje de 3.3V proporcionado por la tarjeta enviamos una señal la cual pasaba por un sensor de
Resistencia como el que se muestra en la siguiente imagen.
Cuando presionamos el sensor, este permite el paso del voltaje de 3.3V y la señal entra por el pin de entrada
asignado en la FPGA. Una vez que el pin detecta la señal, entonces la misma tarjeta envía un ‘1’ lógico a los
pines de salida que asignamos para poder encender el vibrador, el buzzer y el foco, además de mostrar una letra
“A” con los display de 7seg de la tarjeta.
Para encender el buzzer y el motor vibrador, mediante uno de los pines hembra, enviamos un ‘1’ lógico con ayuda
de un jumper para que este llegue a la terminal positiva de ambos componentes y estos se activen, la terminal
negativa de estos los podemos conectar a uno de los pines GND de la tarjeta.
Para el display de 7seg solo necesitamos realizar el código para poder encender únicamente uno de los 8 displays
y que se enciendan solo los segmentos necesarios. Ya que los displays son de tipo ánodo debemos asignar un ‘0’
lógico al display y a los segmentos que queremos activar. En nuestro caso activamos el ultimo display inferior
(mostrado en la sig. imagen) y solo dejamos inactivo el segmento D para simular la letra A.
Finalmente, para poder encender el foco se necesitó armar un circuito con un optoacoplador, un relevador y una
fuente como se muestra a continuación.
Este circuito nos permite tanto proteger la tarjeta como permitir que la tarjeta funciones como un “switch” para
encender el foco. El foco de 120V lo conectamos a una fuente de CA (Un enchufe) para que tenga suficiente
voltaje y encienda. Entonces cuando presionamos el sensor, tanto el buzzer, vibrador, display y el foco se activan.
El código fue escrito en VHDL y es el que se muestra a continuación.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
an <= "11111110";
process (sen)
begin
case sen is
when '1' => dis <= "10001000"; vib <= '1'; foco <= '1';
when others => dis <= "11111111"; vib <= '0'; foco <= '0';
end case;
end process;
end Behavioral;
c) Sistema de llenado de un tinaco con 3 sensores en cisterna y tres sensores en tinaco y visualización en
vummer.
Para esta parte se generó un código para activar y desactivar una bomba para el llenado de un tinaco. Debido a
que no fue posible la adquisición de los sensores de nivel de agua, se optó por simularlos con los switches de la
FPGA.
La bomba se simulo con un ventilador de 12v y una fuente de alimentación externa, como se muestra en la figura:
else
motor <= '0';
dp_sg <= "00000011";
B<='0';
end if;
end process; --Fin del proceso
end Behavioral; --Fin de la arquitectura
FPGA
entity FSM_Motor is
port(
clk,reset,vel,stop,sentido : in std_logic; --Botones de control
Bobina : out std_logic_vector(3 downto 0); --Bobinas del motor
AN : out STD_LOGIC_VECTOR (7 downto 0) := "11111111"; --Ánodos del Display
DISPLAY : out STD_LOGIC_VECTOR (7 downto 0) := "00000000" --Segmentos del
Display
);
end entity FSM_Motor;
architecture arq of FSM_Motor is
type estados_type is (E0,E1,E2,E3,E4,E5,E6,E7); --Estados posibles de la FSM
signal E_actual : estados_type := E0;
signal cont1 : std_logic_vector(21 downto 0); --para dividir la frecuencia del reloj
signal clko : std_logic; --
señal de reloj de menor frecuencia
signal conta_1250us: integer range 1 to 62_500:=1; -- pulso1 de 1250us@400Hz (0.25ms)
signal SAL_400Hz : std_logic; --señal de
reloj de 400Hz
signal SEL: std_logic_vector (1 downto 0):="00";--para recorrerse entre los displays
--signal E_sig : estados_type;
begin
Veamos que cuando la señal “sentido” pasa de 1 a 0, los estados comienzan a cambiar de manera ascendente, por
lo que el motor gira en el otro sentido también.
Ahora bien, cuando stop está activo, los estados no cambian, por lo que el motor no se mueve, y cuando la
velocidad cambia, los estados cambian de dos en dos, por lo que el motor dará pasos completos, y no medios
pasos.
c) Detector de 4 unos seguidos
Este código genera una señal mediante la lectura de los valores de un DIP switch, y en otra etapa se encuentra
la máquina de estado finito que va leyendo dicha señal, y si esta se encuentra en estado alto durante 4 ciclos
seguidos, activará una alarma. El programa se realizó en un Top Level Design, y los códigos de las entidades
se muestran a continuación:
TLD.vhd (Top Level Design):
--------------------------------------------------------------------
-- Company: PiQ2 - UPIITA
-- Create Date: 03/25/2022
--------------------------------------------------------------------
Library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity TLD is
port(
clk:in std_logic;
reset:in std_logic;
DIP:in std_logic_vector(3 downto 0);--Entradas del DIPswitch
alarma, speaker:out std_logic;
AN : out STD_LOGIC_VECTOR (7 downto 0)--Ánodos del Display
);
end TLD;
begin
FSM_Detector: entity work.FSM_Detector_unos port map(
clk => clk,
reset => reset,
dato => dato,
alarma => alarma,
speaker => speaker,
AN => AN
);
FSM_Detector_unos.vhd:
--------------------------------------------------------------------
-- Company: PiQ2 - UPIITA
-- Create Date: 03/25/2022
--------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity FSM_Detector_unos is
port(
clk,reset,dato : in std_logic;
alarma,speaker : out std_logic;
AN : out STD_LOGIC_VECTOR (7 downto 0) := "11111111"
);
end entity FSM_Detector_unos;
when E1=>
alarma <= '0';
a <= '0';
if dato='0' then estados <= E0;
elsif dato='1' then estados <= E2;
end if;
when E2=>
alarma <= '0';
a <= '0';
if dato='0' then estados <= E0;
elsif dato='1' then estados <= E3;
end if;
when E3=>
if dato='0' then estados <= E0;
elsif dato='1' then
estados <= E0;
alarma <= '1';
a <= '1';
end if;
end case;
end if;
end if;
end process;
Generador_seq.vhd
--------------------------------------------------------------------
-- Company: PiQ2 - UPIITA
-- Create Date: 03/26/2022
--------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
entity Generador_seq is
port(
clk,reset : in std_logic;
DIP : in std_logic_vector(3 downto 0);--Entradas del DIPswitch
dato : out std_logic--Salida hacia entidad "FSM_Detector"
);
end entity Generador_seq;
--implementado en la amiba2.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY PWM is
end PWM;
ARCHITECTURE PWM of PWM is
begin
generacion_PWM:
begin
end if;
case (selector) is
end if;
end if;
when "011" => -- 90°
pos<="00001101"; --3
end if;
end if;
end if;
end case;
Se empleo una lampara de mano como carga y se uso la misma como referencia para las cinco posiciones del
servomotor, este se alimentó con los 5v de la FPGA.
A continuación, se muestran las imágenes de las cinco posiciones.
En el siguiente enlace puede verse un video del funcionamiento con las cinco posiciones:
https://youtu.be/H0gS4dLEDns
b) Se implemento el código verilog para programar una secuencia de dos posiciones de un servomotor
FUTABA, empleando una lampara como carga. El código quedo como sigue:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 23:03:47 03/23/2022
// Design Name:
// Module Name: Servo_Controler
//////////////////////////////////////////////////////////////////////////////////
module top(
input mclk, //Reloj de la FPGA
output [0:0] Led, //Salida a led
output servo //Señal de salida PWM al servo
);
////////////////////////////////////////////////////////////
//Registros de control ///////////////////////////////////
////////////////////////////////////////////////////////////
reg [15:0] control = 0;
reg toggle = 1;
////////////////////////////////////////////////////////////
//Control de la secuencia///////////////////////////////////
////////////////////////////////////////////////////////////
if(control == 'd50000)
toggle <= 0;
if(control == 0)
toggle <= 1;
if(counter == 0)
begin
if(toggle == 0)
control <= control - 1000;
if(toggle == 1)
control <= control + 1000;
end
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
end
endmodule
(C) Se programo el código para generar un control de velocidad gradual para un servo sin tope, quedando el mismo
de la siguiente forma:
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
-- Create Date: 22:06:14 03/22/2022
-- Design Name:
-- Module Name: PWM - Behavioral
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity PWM_vel is
Generic(
min:integer:=100000; --mínimo
max:integer:=1000000; --Máximo
inc:integer:=1;
width:integer:=1000000;
N:integer:=11);
port(
clk: in std_logic; --reloj de la FPGA
servo: out std_logic; --Salida al servo
switch1: in std_logic); --Switch de inicio
end PWM_vel;
begin
servo<=PWMservo;
divisor:process(clk)
begin
if rising_edge(clk) then --por cada flanco de subida de reloj
clkdiv<=clkdiv + 1;
end if;
end process divisor;
tiempocnt:process(clkdiv(N))
begin
if rising_edge(clkdiv(N)) then
if switch1='1' then
cnt1<=cnt1+1;
if cnt1=250000000 then cnt1<=cnt1;
end if;
else cnt1<=1;
end if;
end if;
end process tiempocnt;
pulso:process(clk)
begin
if rising_edge(clk) then
cntPWM1<=cntPWM1+1;
high1<=min+((cnt1)*(inc));
if cntPWM1<=high1 then
PWMservo<='1';
else
PWMservo<='0';
end if;
else null;
end if;
end process pulso;
end Behavioral
Implementado para la amiba2 el UCF queda:
El el siguiente enlace puede verse un video del funcionamiento del dispositivo: https://youtu.be/hSnO-P1bCDc
Se implemento el un control on-off Con un receptor BT HC-06 conectado a la FPGA como se muestra en la
figura 2.13. A la salida (LOAD) se conectó un ventilador de 12v con fuente externa (baterías 18650) mediante
un transistor 2n222 como switch electrónico, como se muestra en el diagrama 4.1.
//////////////////////////////////////////////////////////////////////////////////
module HC_05(
//fsm states
reg [1:0] presentstate, nextstate;
parameter EDO_1 = 2'b00;
parameter EDO_2 = 2'b10;
//señales
always@(posedge clk)
begin
if(c<868)
c=c+1;
else
begin
c=0;
delay=~delay;
end
end
end
//FSM actualiza
always@(posedge capture, posedge reset)
if (reset) presentstate <= EDO_1;
nextstate= EDO_1;
endcase
end
if(i>=9)
begin
i=0;
done=1;
leds<=tmp[8:1];
case (tmp[8:1])
8'h31 : salida <= 0; // Apagado
8'h32 : salida <= 1; // Encendido
default : salida <= 0;// _
endcase
end
else
begin
i=i+1;
done=0;
end
else
done=0;
end
endmodule
Conclusiones:
• Santos López Luis Enrique
Esta práctica fue complicada debido a la necesidad de la implementación de circuitos para poder alimentar de
forma externa los dispositivos empleados, ventilador, motor a pasos etc. Así también fue necesario la adquisición
de algunos dispositivos como servos con y sin tope, motor a pasos y sensores, algunos de los cuales, como los
sensores de nivel de agua, no fue posible conseguirlos. El dispositivo HC-06 dio particulares problemas ya que
no todas las apps lo reconocían por lo que fue necesario probar con varias hasta encontrar la más adecuada.
Gracias a esta práctica aprendimos sobre circuitos combinacionales, secuenciales, así como la máquina de
estados, para esto empleamos los códigos tanto VHDL como Verilog implementados para la FPGA AMIBA2.
Referencias:
[1] NAYLAMP MECHATRONICS << MÒDULO BLUETOOTH HV06>> [En línea]. Available:
https://naylampmechatronics.com/inalambrico/24-modulo-bluetooth-hc06.html
[Último acceso: 17/03/2022].
[2] Hackeando Tec <<FPGA comunicación RS-323 con el módulo Bluethooth HC05 usando Verilog>> [En línea].
Available: https://www.youtube.com/watch?v=tpajglbrd-
A&list=PLIyIZGa1sAZqeQJ6Y02b7O8HV0gK25zc2&index=27 [Último acceso: 17/03/2022].
[3] Boletín UPIITA <<Control de posición de un servo utilizando Nexys2 y VHDL>> [En línea]. Available:
https://www.boletin.upiita.ipn.mx/index.php/ciencia/211-cyt-numero-29/214-control-de-posicion-de-un-
servomotor-utilizando-la-tarjeta-de-desarrollo-nexys-2-y-vhdl [Último acceso: 23/03/2022].
[4] Boletin UPIITA <<Control de servomotor con encorder mecánico rotatorio >> [En línea]. Available
https://www.areatecnologia.com/electricidad/servomotor.html [Último acceso: 23/03/2022].