FPGA RS232 Interface

Program Download:

Quartus II Project Files
RS232.zip
RS232.vhd

The Software
           There are two main portions of code that we are concerned with:
    -ASCII Decoding
    -RS232 Receiver Module



           The first portion of code we'll look at is responsible for looking at the last 8 bits of received RS232 communication and decoding their ASCII value. Each ASCII value will have a corresponding led output value that will be fed to the 7 segment LEDs, displaying the proper letter or number.

ASCII to Numbers/Letters

------------« Begin Code »------------
CASE SHIFT_REG is
			--ASCII -> Number, Decoding
		WHEN x"30" => LED_DISPLAY <= zero;
		WHEN x"31" => LED_DISPLAY <= one;
		WHEN x"32" => LED_DISPLAY <= two;
		WHEN x"33" => LED_DISPLAY <= three;
		WHEN x"34" => LED_DISPLAY <= four;
		WHEN x"35" => LED_DISPLAY <= five;
		WHEN x"36" => LED_DISPLAY <= six;
		WHEN x"37" => LED_DISPLAY <= seven;
		WHEN x"38" => LED_DISPLAY <= eight;
		WHEN x"39" => LED_DISPLAY <= nine;
			--ASCII -> Letter, Decoding
		WHEN x"61" => LED_DISPLAY <= letter_a;
		WHEN x"62" => LED_DISPLAY <= letter_b;
		WHEN x"63" => LED_DISPLAY <= letter_c;
		WHEN x"64" => LED_DISPLAY <= letter_d;
		WHEN x"65" => LED_DISPLAY <= letter_e;
		WHEN x"66" => LED_DISPLAY <= letter_f;
		WHEN x"67" => LED_DISPLAY <= letter_g;
		WHEN x"68" => LED_DISPLAY <= letter_h;
		WHEN x"69" => LED_DISPLAY <= letter_i;
		WHEN x"6A" => LED_DISPLAY <= letter_j;
		WHEN x"6C" => LED_DISPLAY <= letter_l;
		WHEN x"6E" => LED_DISPLAY <= letter_n;
		WHEN x"6F" => LED_DISPLAY <= letter_o;
		WHEN x"70" => LED_DISPLAY <= letter_p;
		WHEN x"73" => LED_DISPLAY <= letter_s;
		WHEN x"75" => LED_DISPLAY <= letter_u;
		WHEN x"79" => LED_DISPLAY <= letter_y;
		WHEN x"7A" => LED_DISPLAY <= letter_z;
			--Clear 7 Seg When Others Pressed
		WHEN OTHERS => LED_DISPLAY <= "1111111";
END CASE;
------------« End Code »------------

           Since this is VHDL 'programming' the decoding is basically a look-up table, or as seen above, a case statement that matches one ascii code to one led display output code. This is a quick and easy way to match the two codes together.
           The second portion of code is an abridge version of the RS232 interface module. The code module has two modes ON or OFF, depending upon the state of START_STOP. The module is started when the start bit is detected on the RS232 input. After that a counter begins counting and everytime the counter hits 0 the data bit on the RS232 line is put into a shift register and saved. After 8 times of this, the RS232 communication is finished and the newly received ASCII code is displayed on the LED output.

RS232 Module Interface

------------« Begin Code »------------
--BAUD Rate Counter
CONSTANT BAUD		: INTEGER := 935;

--Shift Register
SIGNAL SHIFT_REG 	: STD_LOGIC_VECTOR(7 DOWNTO 0);

--Control Signal
SIGNAL START_STOP : STD_LOGIC := '0';

BEGIN

PROCESS
variable timer_cnt: integer range 0 to 100000;
variable char_cnt: integer range 0 to 10;
BEGIN

WAIT UNTIL(clk'EVENT) AND (clk = '1');

--IDLE State
IF(RS232_IN = '0' AND START_STOP = '0')THEN
	--Reset Counters
	char_cnt := 0;
	timer_cnt := 0;
	--Start RS232 Capture Process
	START_STOP <= '1';
ELSIF(RS232_IN = '1' AND START_STOP = '0')THEN

CASE SHIFT_REG is
	..
	...
	..
END CASE;
END IF;

--Start Getting Serial Data
IF(START_STOP = '1')THEN
		IF(timer_cnt = BAUD) THEN
				--Update Counter
			timer_cnt := 0;
			
				--Update Shift Register			
			SHIFT_REG <= RS232_IN & SHIFT_REG(7 DOWNTO 1);
			
				--Is 8th Bit?
			IF(char_cnt = 7)THEN				
				START_STOP <= '0';
			ELSE
				char_cnt := char_cnt + 1;
			END IF;
		ELSE
			timer_cnt := timer_cnt + 1;					
		END IF;
END IF;
END PROCESS;
------------« End Code »------------

           This second chunk of code is far more complicated (and not exactly neat and clean) so it will take some time to understand what is going on here if you're not familiar with VHDL. But be sure to download the project files above so that you can load the project into your computer and run simulations to see exactly how it works.



;