RS-232 Port Lecture L9.3
Loop feedback RS-232 voltage levels: +5.5 V (logic 0) -5.5 V (logic 1)
Spartan-3 board: DCE male connector PC: DTE female connector Straight-through cable
Note: TxD (pin 2) on Spartan-3 DCE connector is connected to RD (pin 2) on the PC DTE connector
UART clock frequency = 16 x Baud rate or 64 x Baud rate
Standard ASCII Codes
RS-232 Interface to the WC16
\ A software UART for the Spartan-3 board HEX : CYCLES( n -- )\ delay 2n+5 FOR NEXT ; : KEY( -- n ) 0\ byte to read BEGIN\ wait for start bit 80 XOR UNTIL 797\ 3900 = 1.5 bit times 8 FOR\ 2*797 + E = $F3C = 3900 CYCLES\ delay U2/ OR\ get next bit 50E\ 2*50E + C = $A28 = 2600 NEXT\ = 1 bit time BEGIN\ wait for stop bit UNTIL DROP ;
: bit_time( n -- )\ 9600 baud bit time 511 FOR NEXT ; : TX!( n -- ) 0 >tx DROP\ start bit bit_time 8 FOR\ 8 data bits >tx bit_time U2/ NEXT DROP 1 >tx DROP\ stop bit bit_time ;
: MAIN( -- ) BEGIN KEY\ receive byte DUP DIG! \ display it TX! AGAIN ;
when rxfetch =>-- read uart in E2 tload <= '1'; nload <= '1'; tsel <= "101"; dpush <= '1'; when totx =>-- latch T(0) to txreg txload <= '1'; Add to wc16_control.vhd
How would you make the following hardware UART? 8-bit asynchronous serial data comes in RxD and fills up the shift register data_rx. When data_rx is full, rdrf is set to 1. rdrf is cleared to zero by bringing clrflg high. The framing error flag FE is set to 1 if the stop bit is not 1.
UART Receive State Diagram
entity uart_rx is port( RxD : in STD_LOGIC; clk : in STD_LOGIC; clr : in STD_LOGIC; rdrf_clr : in STD_LOGIC; rdrf : out STD_LOGIC; FE : out STD_LOGIC; rx_data : out STD_LOGIC_VECTOR(7 downto 0) ); end uart_rx;
architecture uart_rx of uart_rx is type state_type is (mark, start, delay, shift, stop); signal state: state_type; signal rxbuff: STD_LOGIC_VECTOR (7 downto 0); signal baud_count: STD_LOGIC_VECTOR (11 downto 0); signal bit_count: STD_LOGIC_VECTOR (3 downto 0); signal rdrf_set, fe_set, cclr, cclr8, rxload: STD_LOGIC; constant bit_time: STD_LOGIC_VECTOR (11 downto 0) := X"A28"; constant half_bit_time: STD_LOGIC_VECTOR (11 downto 0) := X"514"; begin 9600 baud
uart2: process(clk, clr, rdrf_clr) begin if clr = '1' then state <= mark; rxbuff <= " "; baud_count <= X"000"; bit_count <= "0000"; FE <= '0'; elsif rdrf_clr = '1' then rdrf <= '0'; elsif (clk'event and clk = '1') then case state is when mark =>-- wait for start bit if RxD = '1' then state <= mark; else baud_count <= X"000"; bit_count <= "0000"; rxbuff <= " "; FE <= '0'; state <= start; -- go to start end if;
when start =>-- check for start bit if baud_count >= half_bit_time then baud_count <= X"000"; state <= delay; else baud_count <= baud_count + 1; state <= start; end if; when delay => if baud_count >= bit_time then baud_count <= X"000"; if bit_count < 8 then state <= shift; else state <= stop; end if; else baud_count <= baud_count + 1; state <= delay; end if;
when shift =>-- get next bit rxbuff(7) <= RxD; rxbuff(6 downto 0) <= rxbuff(7 downto 1); bit_count <= bit_count + 1; state <= delay; when stop => rdrf <= '1'; if RxD = '0' then FE <= '1'; else FE <= '0'; end if; state <= mark; end case; end if; end process uart2; rx_data <= rxbuff; end uart_rx;
\ Test of uart HEX : key( -- n ) BEGIN 8000 AND UNTIL ; : main( -- ) BEGIN clr_rdrf key DIG! AGAIN ;