Está en la página 1de 13

INSTITUTO POLITÉCNICO NACIONAL

Unidad Profesional Interdisciplinaria en Ingeniería y


Tecnología Avanzada

Dispositivos Lógicos Programables


Práctica 5
Comunicación RS232.

Castanedo Hernández Juan Eduardo.


Fajardo Aguirre José Ignacio.
Terán León Fernando Rafael.

Ing. Mecatrónica

2MM15

Profesor: Suárez Tapia Julio César.

28 de octubre del 2019


Comunicación RS232
El protocolo RS-232 es una norma o estándar mundial que rige los parámetros de uno de los modos
de comunicación serial. Por medio de este protocolo se estandarizan las velocidades de transferencia
de datos, la forma de control que utiliza dicha transferencia, los niveles de voltajes utilizados, el tipo
de cable permitido, las distancias entre equipos, los conectores, etc.
Además de las líneas de transmisión (Tx) y recepción (Rx), las comunicaciones seriales poseen otras
líneas de control de flujo (Hands-hake), donde su uso es opcional dependiendo del dispositivo a
conectar.
A nivel de software, la configuración principal que se debe dar a una conexión a través de puertos
seriales. RS-232 es básicamente la selección de la velocidad en baudios (1200, 2400, 4800, etc.), la
verificación de datos o paridad (parida par o paridad impar o sin paridad), los bits de parada luego de
cada dato (1 ó 2), y la cantidad de bits por dato (7 ó 8), que se utiliza para cada símbolo o carácter
enviado.
La Norma RS-232 fue definida para conectar un ordenador a un modem. Además de transmitirse los
datos de una forma serie asíncrona son necesarias una serie de señales adicionales, que se definen en
la norma. Las tensiones empleadas están comprendidas entre +15/-15 Volts.
Puerta serial full dúplex para comunicación punto a punto a una distancia no superior a 30 metros.
Desde 3 hilos hasta 19 hilos.

Este protocolo está disponible en los puertos seriales de la mayoría de las computadoras personales
(PC).

El primer puerto serial denominado comúnmente COM1 tiene asignada la interrupción IRQ4 y sus
registros empiezan en la dirección de la memoria %3F8, y de ahí en adelante hasta la %3FE. Para las
máquinas que tienen un segundo puerto serial este se denomina COM2, tiene asignada la interrupción
IRQ3 y sus registros se alojan en las direcciones %2F8 hasta la %2FE. Los puertos denominados
COM3 y COM4 a pesar de que se mapean en un espacio diferente de los puertos anteriores, comparten
las interrupciones, COM1 con COM3 y COM2 con COM4, por esto es muy difícil utilizar los cuatro
cuando se trata de hacerlos funcionar mediante interrupciones.

PuTTY
PuTTY es una aplicación de emulador de terminal que puede actuar como cliente para los protocolos
informáticos SSH, Telnet, rlogin y TCP sin procesar. La palabra "PuTTY" no tiene significado, [1]
aunque 'tty' a veces se usa para referirse a los terminales Unix, como un acrónimo de "teletipo".
PuTTY se escribió por primera vez para Microsoft Windows, pero se ha portado a otros sistemas
operativos, incluidas algunas plataformas similares a Unix. Mac OS y Mac OS X todavía se están
portando, mientras que los puertos no oficiales se han portado a los sistemas operativos Symbian y
Windows Mobile.
PuTTY es actualmente un software beta. Licenciado bajo la Licencia MIT, y es un software gratuito
y de código abierto.
En esta práctica, pudimos experimentar el protocolo de comunicación RS232, para esto se necesitó
de la implementación de tres módulos: Transmisión (TX), recepción (RX) y uno para visualizar los
datos en un display de 7 segmentos, así como la asistencia de un programa que permite leer los puertos
COM, de la computadora, en este caso se utilizó PuTTY.

A través de las terminales TX y RX de la Nexys, es enviada una cadena de caracteres, los cuales, bajo
el protocolo RS232, se mandan con un pulso que abarca los 9600 bits por segundo, así pues, esta
cadena es recibida a través del puerto COM y mostrada en PuTTY. Así mismo se envía al presionar
una tecla, el código binario correspondiente a una palabra de 8 caracteres (8 bits), los cuales,
representan una letra en código ascii , la cual se verá representada en el display de 7 segmentos.

Cabe aclarar que el proceso de transmisión y recepción se realizan paralelamente y con ayuda de la
estructura en TOP LEVEL, nos permite tener una visualización más certera de su funcionamiento, al
momento de programar.
A continuación, se anexarán los códigos correspondientes:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 22.10.2019 07:55:09
// Design Name:
// Module Name: top_level
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////

module top_level( clk,btn_in,DATA, READY,UART_TX, i_RX_Serial,segm, anod,led,led2 );


input wire btn_in,clk;
input wire [7:0]DATA;
input wire i_RX_Serial ;
output wire [7:0]segm;
output wire [7:0] anod;
output wire [7:0]led;
output wire [7:0] led2;
output wire READY,UART_TX;
wire [7:0] o_RX_Byte;
wire o_RX_DV;
wire btn_out;

bounce u1(.clk(clk),.btn_in(btn_in),.btn_out(btn_out));
UART_TX_CTRL u2(.SEND(btn_out),.DATA(DATA),
.READY(READY),.UART_TX(UART_TX),.CLK(clk));
UART_RX u3(.clock_100Mhz(clk), .i_RX_Serial(i_RX_Serial),
.o_RX_DV(o_RX_DV),.o_RX_Byte(o_RX_Byte) );
seg
u4(.segm(segm),.anod(anod),.o_RX_Byte(o_RX_Byte),.o_RX_DV(o_RX_DV),.led(led),.led2(le
d2));

endmodule
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_unsigned.all;

entity UART_TX_CTRL is
Port ( SEND : in STD_LOGIC;
DATA : in STD_LOGIC_VECTOR (7 downto 0);
CLK : in STD_LOGIC;
READY : out STD_LOGIC;
UART_TX : out STD_LOGIC);
end UART_TX_CTRL;

architecture Behavioral of UART_TX_CTRL is

type TX_STATE_TYPE is (RDY, LOAD_BIT, SEND_BIT);


-- "10100010110000"; --10416 = (round(100MHz / 9600)) - 1
constant BIT_TMR_MAX : std_logic_vector(13 downto 0) := "00001101100011"; --867 =
(round(100MHz / 115200)) - 1
constant BIT_INDEX_MAX : natural := 10;

signal bitTmr : std_logic_vector(13 downto 0) := (others => '0');

signal bitDone : std_logic;

signal bitIndex : natural;

signal txBit : std_logic := '1';


signal txData : std_logic_vector(9 downto 0);

signal txState : TX_STATE_TYPE := RDY;

begin

--Logica de estado
next_txState_process : process (CLK)
begin
if (rising_edge(CLK)) then
case txState is
when RDY =>
if (SEND = '1') then
txState <= LOAD_BIT;
end if;
when LOAD_BIT =>
txState <= SEND_BIT;
when SEND_BIT =>
if (bitDone = '1') then
if (bitIndex = BIT_INDEX_MAX) then
txState <= RDY;
else
txState <= LOAD_BIT;
end if;
end if;
when others=>
txState <= RDY;
end case;
end if;
end process;

bit_timing_process : process (CLK)


begin
if (rising_edge(CLK)) then
if (txState = RDY) then
bitTmr <= (others => '0');
else
if (bitDone = '1') then
bitTmr <= (others => '0');
else
bitTmr <= bitTmr + 1;
end if;
end if;
end if;
end process;

bitDone <= '1' when (bitTmr = BIT_TMR_MAX) else


'0';

bit_counting_process : process (CLK)


begin
if (rising_edge(CLK)) then
if (txState = RDY) then
bitIndex <= 0;
elsif (txState = LOAD_BIT) then
bitIndex <= bitIndex + 1;
end if;
end if;
end process;

tx_data_latch_process : process (CLK)


begin
if (rising_edge(CLK)) then
if (SEND = '1') then
txData <= '1' & DATA & '0';
end if;
end if;
end process;

tx_bit_process : process (CLK)


begin
if (rising_edge(CLK)) then
if (txState = RDY) then
txBit <= '1';
elsif (txState = LOAD_BIT) then
txBit <= txData(bitIndex);
end if;
end if;
end process;

UART_TX <= txBit;


READY <= '1' when (txState = RDY) else
'0';

end Behavioral;

library ieee;
use ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;

entity UART_RX is
generic (
g_CLKS_PER_BIT : integer := 868 -- Needs to be set correctly
);
port (
clock_100Mhz : in std_logic;
i_RX_Serial : in std_logic;
o_RX_DV : out std_logic;
o_RX_Byte : out std_logic_vector(7 downto 0)

);
end UART_RX;

architecture RTL of UART_RX is

type t_SM_Main is (s_Idle, s_RX_Start_Bit, s_RX_Data_Bits,


s_RX_Stop_Bit, s_Cleanup);
signal r_SM_Main : t_SM_Main := s_Idle;
signal w_SM_Main : std_logic_vector(2 downto 0);

signal r_Clk_Count : integer range 0 to g_CLKS_PER_BIT-1 := 0;


signal r_Bit_Index : integer range 0 to 7 := 0; -- 8 Bits Total
signal r_RX_Byte : std_logic_vector(7 downto 0) := (others => '0');
signal r_RX_DV : std_logic := '0';

begin
-- Purpose: Control RX state machine
p_UART_RX : process (clock_100Mhz)
begin
if rising_edge(clock_100Mhz) then

case r_SM_Main is

when s_Idle =>


r_RX_DV <= '0';
r_Clk_Count <= 0;
r_Bit_Index <= 0;

if i_RX_Serial = '0' then -- detector de principio de trama


r_SM_Main <= s_RX_Start_Bit;
else
r_SM_Main <= s_Idle;
end if;

when s_RX_Start_Bit =>


if r_Clk_Count = (g_CLKS_PER_BIT-1)/2 then
if i_RX_Serial = '0' then
r_Clk_Count <= 0;
r_SM_Main <= s_RX_Data_Bits;
else
r_SM_Main <= s_Idle;
end if;
else
r_Clk_Count <= r_Clk_Count + 1;
r_SM_Main <= s_RX_Start_Bit;
end if;

--espera un ciclo de reloj para muestrear los datos


when s_RX_Data_Bits =>
if r_Clk_Count < g_CLKS_PER_BIT-1 then
r_Clk_Count <= r_Clk_Count + 1;
r_SM_Main <= s_RX_Data_Bits;
else
r_Clk_Count <= 0;
r_RX_Byte(r_Bit_Index) <= i_RX_Serial;

-- Verifica si se han mandado datos


if r_Bit_Index < 7 then
r_Bit_Index <= r_Bit_Index + 1;
r_SM_Main <= s_RX_Data_Bits;
else
r_Bit_Index <= 0;
r_SM_Main <= s_RX_Stop_Bit;
end if;
end if;

-- Recive el Stop bit. Stop bit = 1


when s_RX_Stop_Bit =>
-- Espera un ciclo de reloj para recibir el Stop bit
if r_Clk_Count < g_CLKS_PER_BIT-1 then
r_Clk_Count <= r_Clk_Count + 1;
r_SM_Main <= s_RX_Stop_Bit;
else
r_RX_DV <= '1';
r_Clk_Count <= 0;
r_SM_Main <= s_Cleanup;
end if;

-- Se mantiene aqui un ciclo


when s_Cleanup =>
r_SM_Main <= s_Idle;
r_RX_DV <= '0';

when others =>


r_SM_Main <= s_Idle;

end case;
end if;
end process p_UART_RX;

o_RX_DV <= r_RX_DV;


o_RX_Byte <= r_RX_Byte;

-- Genera la trama a mandar


w_SM_Main <= "000" when r_SM_Main = s_Idle else
"001" when r_SM_Main = s_RX_Start_Bit else
"010" when r_SM_Main = s_RX_Data_Bits else
"011" when r_SM_Main = s_RX_Stop_Bit else
"100" when r_SM_Main = s_Cleanup else
"101"; --

end RTL;
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 16.10.2019 09:29:14
-- Design Name:
-- Module Name: seg - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating


-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity seg is
Port (o_RX_Byte: in std_logic_vector(7 downto 0);
segm:out std_logic_vector(7 downto 0);
o_RX_DV: in std_logic;
led: out std_logic_vector(7 downto 0);
led2: out std_logic_vector(7 downto 0);
anod: out std_logic_vector(7 downto 0) );
end seg;

architecture Behavioral of seg is


signal baff: std_logic_vector(7 downto 0);

begin
process(o_RX_DV)
begin
led<=o_RX_Byte;
anod<="10111111";
if (o_RX_DV'event and o_RX_DV='1') then
baff<= o_RX_Byte;

end if;
end process;

process(baff)
begin

case(baff) is
when "00110000" =>segm<="00000011";--0
when "00110001" =>segm<="10011111" ;--1
when "00110010" =>segm<="00100101" ;--2
when "00110011" =>segm<="00001101" ;--3
when "00110100" =>segm<="10011001" ;--4
when "00110101" =>segm<="01001001" ;--5
when "00110110" =>segm<="01000001" ;--6
when "00110111" =>segm<="00011111" ;--7
when "00111000" =>segm<="00000001" ;--8
when "00111001" =>segm<= "00001001"; --9
when "01100001" =>segm<= "00010001"; --A
when "01100101" =>segm<= "01100001"; --E
when "01101001" =>segm<= "10011110"; --I
when "01101111" =>segm<= "00000010"; --O
when "01110101" =>segm<= "10000011"; --U
when others =>segm<= "11111111"; --U
end case;

end process;

end Behavioral;
Conclusiones
Fajardo Aguirre José Ignacio:
Para la realización de esta práctica, considero que la complejidad radica, en el buen manejo del pulso,
pues, al este ser un sistema asíncrono, depende mucho de la cantidad de bits por segundo que envía
y al terminar los 8 bits, es importante enviar un bit de finalización de la cadena, para poder dar por
terminada la recepción, de otra forma, se estancará en este estado.
Castanedo Hernández Juan Eduardo:
Gracias a esta práctica se apreció y aprendió de la complejidad y la manera de establecer una
comunicación entre el FPGA y la computadora, siendo los datos tanto de transmisión como de
recepción, así mismo recibir los datos transmitidos por ambos casos para pasar a interpretarlos y
mostrarlos en su respectivo equipo. Así mismo se comprendió sobre la importancia de la transmisión
de datos de forma serial asíncrona pues con una sola señal de transmisión se pueden enviar y recibir
varias cantidades de datos de una manera más simplificada.
Terán León Fernando Rafael:
Mediante la comunicación serial, es posible tanto enviar como recibir datos entre la FPGA y nuestra
PC, lo cual es bastante útil para la lectura de sensores así como el almacenamiento de datos. Gracias
al desarrollo de esta práctica, nos fue posible el comprender que mediante el puerto RS232 de la
FPGA es posible enviar y recibir datos simultáneamente entre la PC y la tarjeta, así de cómo es posible
esta comunicación.
Mediante una señal de reloj, la FPGA Lee los bits de entrada a una velocidad en este caso de 9600
baudios (9600 bits por segundo) así como también es capaz de enviar datos simultáneamente a dicha
velocidad. Esto gracias a una serie de sentencia lógicas que almacenan la información recibida, la
analiza e interpreta en la FPGA

También podría gustarte