Aide code liaison RS232
Répondre à la discussion
Affichage des résultats 1 à 2 sur 2

Aide code liaison RS232



  1. #1
    Kurtich

    Aide code liaison RS232


    ------

    Bonjour,

    Je poste ce sujet car je reste bloqué depuis plusieurs jours sur mon code VHDL concernant ma liaison RS232.

    Le voici, je vous explique mon soucis juste après :

    Code:
    ----------------------------------------------------------------------------------
    -- Creation Date: 21:12:48 05/06/2010 
    -- Module Name: RS232/UART Interface - Behavioral
    -- Used TAB of 4 Spaces
    ----------------------------------------------------------------------------------
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;
    
    entity uart is
    generic (
      CLK_FREQ	: integer := 50;		-- Main frequency (MHz)
      SER_FREQ	: integer := 9600		-- Baud rate (bps)
    );
    port (
      -- Control
      clk			: in	std_logic;		-- Main clock
      rst			: in	std_logic;		-- Main reset
      -- External Interface
      rx			: in	std_logic;		-- RS232 received serial data
      tx			: out	std_logic;		-- RS232 transmitted serial data
      -- RS232/UART Configuration
      par_en		: in	std_logic;		-- Parity bit enable
      -- uPC Interface
      tx_req		: in	std_logic;						-- Request SEND of data
      tx_end		: out	std_logic;						-- Data SENDED
      tx_data		: in	std_logic_vector(7 downto 0);	-- Data to transmit
      rx_ready	: out	std_logic;						-- Received data ready to uPC read
      rx_data		: out	std_logic_vector(7 downto 0)	-- Received data 
    );
    end uart;
    
    architecture Behavioral of uart is
    
    	-- Constants
    	constant UART_IDLE	:	std_logic := '1';
    	constant UART_START	:	std_logic := '0';
    	constant PARITY_EN	:	std_logic := '1';
    	constant RST_LVL	:	std_logic := '1';
    
    	-- Types
    	type state is (idle,data,parity,stop1,stop2);			-- Stop1 and Stop2 are inter frame gap signals
    
    	-- RX Signals
    	signal rx_fsm		:	state;							-- Control of reception
    	signal rx_clk_en	:	std_logic;						-- Received clock enable
    	signal rx_rcv_init	:	std_logic;						-- Start of reception
    	signal rx_par_bit	:	std_logic;						-- Calculated Parity bit
    	signal rx_data_deb	:	std_logic;						-- Debounce RX data
    	signal rx_data_tmp	:	std_logic_vector(7 downto 0);	-- Serial to parallel converter
    	signal rx_data_cnt	:	std_logic_vector(2 downto 0);	-- Count received bits
    
    	-- TX Signals
    	signal tx_fsm		:	state;							-- Control of transmission
    	signal tx_clk_en	:	std_logic;						-- Transmited clock enable
    	signal tx_par_bit	:	std_logic;						-- Calculated Parity bit
    	signal tx_data_tmp	:	std_logic_vector(7 downto 0);	-- Parallel to serial converter
    	signal tx_data_cnt	:	std_logic_vector(2 downto 0);	-- Count transmited bits
    
    begin
    
    	tx_clk_gen:process(clk)
    		variable counter	:	integer range 0 to conv_integer((CLK_FREQ*1_000_000)/SER_FREQ-1);
    	begin
    		if clk'event and clk = '1' then
    			-- Normal Operation
    			if counter = (CLK_FREQ*1_000_000)/SER_FREQ-1 then
    				tx_clk_en	<=	'1';
    				counter		:=	0;
    			else
    				tx_clk_en	<=	'0';
    				counter		:=	counter + 1;
    			end if;
    			-- Reset condition
    			if rst = RST_LVL then
    				tx_clk_en	<=	'0';
    				counter		:=	0;
    			end if;
    		end if;
    	end process;
    
    	tx_proc:process(clk)
    		variable data_cnt	: std_logic_vector(2 downto 0);
    	begin
    		if clk'event and clk = '1' then
    			if tx_clk_en = '1' then
    				-- Default values
    				tx_end					<=	'0';
    				tx						<=	UART_IDLE;
    				-- FSM description
    				case tx_fsm is
    					-- Wait to transfer data
    					when idle =>
    						-- Send Init Bit
    						if tx_req = '1' then
    							tx			<=	UART_START;
    							tx_data_tmp	<=	tx_data;
    							tx_fsm		<=	data;
    							tx_data_cnt	<=	(others=>'1');
    							tx_par_bit	<=	'0';
    						end if;
    					-- Data receive
    					when data =>
    						tx				<=	tx_data_tmp(0);
    						tx_par_bit		<=	tx_par_bit xor tx_data_tmp(0);
    						if tx_data_cnt = 0 then
    							if par_en = PARITY_EN then
    								tx_fsm	<=	parity;
    							else
    								tx_fsm	<=	stop1;
    							end if;
    							tx_data_cnt	<=	(others=>'1');
    						else
    							tx_data_tmp	<=	'0' & tx_data_tmp(7 downto 1);
    							tx_data_cnt	<=	tx_data_cnt - 1;
    						end if;
    					when parity =>
    						tx				<=	tx_par_bit;
    						tx_fsm			<=	stop1;
    					-- End of communication
    					when stop1 =>
    						-- Send Stop Bit
    						tx				<=	UART_IDLE;
    						tx_fsm			<=	stop2;
    					when stop2 =>
    						-- Send Stop Bit
    						tx_end			<=	'1';
    						tx				<=	UART_IDLE;
    						tx_fsm			<=	idle;
    					-- Invalid States
    					when others => null;
    				end case;
    			 	-- Reset condition
    				if rst = RST_LVL then
    					tx_fsm				<=	idle;
    					tx_par_bit			<=	'0';
    					tx_data_tmp			<=	(others=>'0');
    					tx_data_cnt			<=	(others=>'0');
    				end if;
    			end if;
    		end if;
    	end process;
    
    	rx_debounceer:process(clk)
    		variable deb_buf	:	std_logic_vector(20 downto 0):= (OTHERS=>'0');
    		variable ones : std_logic_vector(20 downto 0) := (OTHERS=>'1');
    		variable zero : std_logic_vector(20 downto 0) := (OTHERS=>'0');
    	begin
    		if clk'event and clk = '1' then
    			-- Debounce logic
    			if deb_buf = zero then
    				rx_data_deb		<=	'0';
    			elsif deb_buf = ones then
    				rx_data_deb		<=	'1';
    			end if;
    			-- Data storage to debounce
    			deb_buf				:=	deb_buf(19 downto 0) & rx;
    		end if;
    	end process;
    
    	rx_start_detect:process(clk)
    		variable rx_data_old	:	std_logic;
    	begin
    		if clk'event and clk = '1' then
    			-- Falling edge detection
    			if rx_data_old = '1' and rx_data_deb = '0' and rx_fsm = idle then
    				rx_rcv_init		<=	'1';
    			else
    				rx_rcv_init		<=	'0';
    			end if;
    			-- Default assignments
    			rx_data_old			:=	rx_data_deb;
    			-- Reset condition
    			if rst = RST_LVL then
    				rx_data_old		:=	'0';
    				rx_rcv_init		<=	'0';
    			end if;
    		end if;
    	end process;
    
    
    	rx_clk_gen:process(clk)
    		variable counter	:	integer range 0 to conv_integer(((CLK_FREQ*1_500_000)/SER_FREQ)-1):=conv_integer(((CLK_FREQ*1_200_000)/SER_FREQ)-1);
    	begin
    		if clk'event and clk = '1' then
    			-- Normal Operation
    			if rx_rcv_init = '1'  then
    				rx_clk_en	<=	'1';
    				counter		:=	conv_integer(((CLK_FREQ*1_500_000)/SER_FREQ)-1);			  
    			elsif ( counter = 0  )  then
    				rx_clk_en	<=	'1';
    				counter		:=	conv_integer(((CLK_FREQ*1_000_000)/SER_FREQ)-1);
    			else
    				rx_clk_en	<=	'0';
    				counter		:=	counter - 1;
    			end if;
    			-- Reset condition
    			if rst = RST_LVL then
    				rx_clk_en	<=	'0';
    				counter		:=	0;
    			end if;
    		end if;
    	end process;
    
    	rx_proc:process(clk)
    	begin
    		if clk'event and clk = '1' then
    			-- Default values
    			rx_ready		<=	'0';
    			-- Enable on UART rate
    			if rx_clk_en = '1' then
    				-- FSM description
    				case rx_fsm is
    					-- Wait to transfer data
    					when idle =>
    						if rx_data_deb = UART_START then
    							rx_fsm		<=	data;
    						end if;
    						rx_par_bit		<=	'0';
    						rx_data_cnt		<=	(others=>'0');
    					-- Data receive
    					when data =>
    						-- Check data to generate parity
    						if par_en = PARITY_EN then
    							rx_par_bit		<=	rx_par_bit xor rx_data_deb;
    						end if;
    
    						if rx_data_cnt = 7 then
    							-- Data path
    							rx_data(7)		<=	rx;
    							for i in 0 to 6 loop
    								rx_data(i)	<=	rx_data_tmp(6-i);
    							end loop;
    
    							-- With parity verification
    							if par_en = PARITY_EN then
    								rx_fsm		<=	parity;
    							-- Without parity verification
    							else
    								rx_ready	<=	'1';
    								rx_fsm		<=	idle;
    							end if;
    						else
    							rx_data_tmp		<=	rx_data_tmp(6 downto 0) & rx;
    							rx_data_cnt		<=	rx_data_cnt + 1;
    						end if;
    					when parity =>
    						-- Check received parity
    						rx_fsm				<=	idle;
    						if rx_par_bit = rx then
    							rx_ready		<=	'1';
    						end if;
    						
    					-- End of communication
    					when stop1 =>
    						-- Send Stop Bit
    						--tx				<=	UART_IDLE;
    						rx_fsm			<=	stop2;
    					when stop2 =>
    						-- Send Stop Bit
    						rx_ready			<=	'1';
    						--tx				<=	UART_IDLE;
    						rx_fsm			<=	idle;						
    					when others => null;
    				end case;
    				-- Reset condition
    				if rst = RST_LVL then
    					rx_fsm			<=	idle;
    					rx_ready		<=	'0';
    					rx_data			<=	(others=>'0');
    					rx_data_tmp		<=	(others=>'0');
    					rx_data_cnt		<=	(others=>'0');
    				end if;
    			end if;
    		end if;
    	end process;
    
    end Behavioral;

    Et voici le testbench utilisé pour la simulation :

    Code:
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;
    
    entity testbench is
    end entity;
    
    ARCHITECTURE testbench1 of testbench is
    
    signal CLK_tb : std_logic;
    signal RST_tb : std_logic;
    signal RX_tb : std_logic;
    signal TX_tb : std_logic;
    signal PAR_EN_tb : std_logic;
    signal TX_REQ_tb : std_logic;
    signal TX_END_tb : std_logic;
    signal TX_DATA_tb : std_logic_vector(7 downto 0);
    signal RX_READY_tb : std_logic;
    signal RX_DATA_tb : std_logic_vector(7 downto 0);
    
    
    COMPONENT uart 
    port(
    clk : in std_logic;		
    rst : in std_logic;		
    rx : in	std_logic;		
    tx : out std_logic;		
    par_en : in std_logic;		
    tx_req : in std_logic;						
    tx_end : out std_logic;						
    tx_data : in std_logic_vector(7 downto 0);
    rx_ready : out std_logic;						
    rx_data : out std_logic_vector(7 downto 0)	
    );
    
    end COMPONENT;
    
    
    
    BEGIN
    
    
    U1 : uart port map (CLK_tb, RST_tb, RX_tb, TX_tb, PAR_EN_tb, TX_REQ_tb, TX_END_tb, TX_DATA_tb, RX_READY_tb,RX_DATA_tb);  
    
    
    p1 : PROCESS
    begin
    RST_tb <= '0';
    RX_tb <= '0';
    wait for 45 ns;
    RST_tb <='1'; --after 30 ns, '0' after 40 ns;
    RX_tb <='1';
    wait;
    end process p1;
    
    --p2 : PROCESS
    --begin
    --TX_tb <= '0';
    --wait for 45 ns;
    --TX_tb <='1'; --after 30 ns, '0' after 40 ns;
    --wait;
    --end process p2;
    
    
    
    PAR_EN_tb <= '1';
    TX_REQ_tb <= '1';
    
    p4: process
    begin
    TX_DATA_tb <="00000000";
    wait for 45 ns;
    TX_DATA_tb <= "00000001";
    wait for 35 ns;
    TX_DATA_tb <= "00000001" ;
    wait for 25 ns;
    TX_DATA_tb <= "00000010";
    wait for 55 ns;
    TX_DATA_tb <= "00000011" ;
    wait for 35 ns;
    TX_DATA_tb <= "00000100" ;
    wait for 55 ns;
    TX_DATA_tb <= "00000101" ;
    wait for 65 ns;
    TX_DATA_tb <= "00000111"  ;
    wait for 35 ns;
    TX_DATA_tb <= "00000001";
    wait for 35 ns;     
    TX_DATA_tb <=   "00000001" ;
    wait for 45 ns;
    end PROCESS p4;
    
    p3 : process
    begin
    CLK_tb <='0';
    wait for 10 ns;
    CLK_tb <='1';
    wait for 10 ns;
    end process p3;
    
    --p3 : process
    --begin
     
    --  wait for  50 ns;
    --  TX_tb <= '1' ;
    --end process p3;
    
    end testbench1;


    Donc mon but est de simuler un signal en entrée et d'obtenir le même signal en sortie. Mais quand je simule, mon signal d'entrée et bien présent mais je n'ai rien en sortie .. JE galère vraiment dessus donc si quelqu'un à une piste ou un conseil à me donner je suis preneur !

    Merci d'avance tout le monde !

    -----

  2. #2
    Flo7374

    Re : Aide code liaison RS232

    Salut,
    Je m'excuse d'avance, j'avoue ne pas avoir eu la motivation de lire ton code. Par contre j'ai réalisé un projet du même genre, un PIC envoyait des infos à un FPGA en rs232.

    - Tu bosses sur une carte d'évaluation ?

    - Es-tu sur que tu puisses le simuler ? Sur ma carte d'éval du fpga, c'était un module à part qui gérais ça.

    - On utilisait plutôt l'hyperterminal de windows, si t'as de quoi faire c'est pas mal, tu envois un caractère ASCII et tu essais de l'afficher du les LED, c'est souvent plus rapide que de faire des simuls.

    -Sépare bien envoi/reception dans un premier temps. Il faut que tu scrutes le bit de start, dès qu'il arrive sur ton port, pouf, tu prends direct les 8 suivants et tu les stockes.

    J’espère t'avoir un peu aidé

Discussions similaires

  1. liaison RS232
    Par atolip dans le forum Électronique
    Réponses: 9
    Dernier message: 12/01/2014, 10h22
  2. Réponses: 5
    Dernier message: 10/09/2010, 16h25
  3. liaison rs232
    Par invitef486b422 dans le forum Électronique
    Réponses: 11
    Dernier message: 17/04/2009, 17h05
  4. la liaison rs232
    Par invited776d929 dans le forum Électronique
    Réponses: 9
    Dernier message: 24/02/2009, 18h01
  5. Liaison RS232, Bus I2C et SPI.
    Par invite43feaeee dans le forum Électronique
    Réponses: 1
    Dernier message: 01/06/2003, 18h31
Découvrez nos comparatifs produits sur l'informatique et les technologies.