Altera_Forum
Honored Contributor
11 years agoProblem of receiving data from UART RS232
Hello everyone. I am now working on a project and it has to receive data from the COM port (RS232). I have written a receiver in VHDL.
However, the code does not always receive correct data byte but I cannot figure out the problem on the code... I now paste the process for receiving data and hope that anyone can help for spotting out the problem. The baud rate used is 115200bit/second and the clock used by the process is 50MHz.LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
entity rs232 is
port(
recvdata : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); --received data
Clock_50M : IN STD_LOGIC;
RxD : IN STD_LOGIC --pin for receiving data
);
end rs232;
architecture a of rs232 is
type recv_state is(detect_start, check_start, receiving, detect_finish);
signal rstate: recv_state:=detect_start; --state of receiving
signal rcount: integer range 0 to 434:=0; --50MHz/115200=434 434 clk cycles=1 bit data
signal rindex: integer range 0 to 8:=0;
signal indata: STD_LOGIC_VECTOR (7 DOWNTO 0); --buffer of received data
begin
process(Clock_50M) --process for receiving
begin
if (rising_edge(Clock_50M)) then
case rstate is
when detect_start => --waiting start signal
if(RxD='0') then --start signal received
rstate<=check_start; --move to receive state
rcount<=0;
else
rstate<=detect_start;
rcount<=0;
end if;
when check_start =>
if(rcount=217) then --read data at middle (434/2=217)
if (RxD='0')then --still exist start signal
rstate<=receiving;
rcount<=0;
else
rstate<=detect_start;
end if;
else
rstate<=check_start;
end if;
when receiving =>
if(rcount=217) then --read data at middle (434/2=217)
if (rindex=7)then --the 8th bit data is received
indata(rindex)<=RxD;
rindex<=0;
rstate<=detect_finish;
else --receive the next bit
indata(rindex)<=RxD;
rindex<=rindex+1;
rstate<=receiving;
rstate<=receiving;
end if;
else
rstate<=receiving;
end if;
when detect_finish => --wait the finish signal
if(rcount=217) then --read at middle (434/2=217)
if(RxD='1') then
rstate<=detect_start;
recvdata<=indata;
else --if no correct finish signal, discard the data
rstate<=detect_start;
end if;
else
rstate<=detect_finish;
end if;
end case;
if(rcount=434) then --reset the counter if it reach 434th clock cycle
rcount<=0;
else --increase the counter
rcount<=rcount+1;
end if;
end if;
end process;
end a; Thank you for checking my code.