Download - RS-232 Port Discussion D7.1. Loop feedback RS-232 voltage levels: +5.5 V (logic 0) -5.5 V (logic 1)
RS-232 Port
Discussion D7.1
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
9 Pin Connector on a DTE device (PC connection)
Male RS232 DB9
Pin Number Direction of signal:
1 Carrier Detect (CD) (from DCE) Incoming signal from a modem
2 Received Data (RD) Incoming Data from a DCE
3 Transmitted Data (TD) Outgoing Data to a DCE
4 Data Terminal Ready (DTR) Outgoing handshaking signal
5 Signal Ground Common reference voltage
6 Data Set Ready (DSR) Incoming handshaking signal
7 Request To Send (RTS) Outgoing flow control signal
8 Clear To Send (CTS) Incoming flow control signal
9 Ring Indicator (RI) (from DCE) Incoming signal from a modem
Note: TxD (pin 2) on Spartan-3 DCE connector is connected to RD (pin 2) on the PC DTE connector
MARK
SPACESTART
STOP
PARITY
D0 D1 D2 D3 D4 D5 D6 D7
ASCII code 54H = 1010100 ("T") sent with odd parity
Common Asynchronous Serial Baud Rates
Baud rate Bit time (msec)
No. of STOP bits
Char. time (msec.)
Char./sec.
110 9.09 2 100.00 10 300 3.33 1 33.3 3 30 600 1.67 1 16.67 60
1200 0.833 1 8.33 120 2400 0.417 1 4.17 240 4800 0.208 1 2.08 480 9600 0.104 1 1.04 960
14400 0.069 1 0.69 1440 19200 0.052 1 0.52 1920 28800 0.035 1 0.35 2880 38400 0.026 1 0.26 3840
UART clock frequency = 16 x Baud rate or 64 x Baud rate
Standard ASCII CodesTable 9.2
Standard ASCII codesDec 0 16 32 48 64 80 96 112
Hex 0 1 2 3 4 5 6 7
0 0 NUL DLE blank 0 @ P p1 1 SOH DC1 ! 1 A Q a q2 2 STX DC2 " 2 B R b r3 3 ETX DC3 # 3 C S c s4 4 EOT DC4 $ 4 D T d t5 5 ENQ NAK % 5 E U e u6 6 ACK SYN & 6 F V f v7 7 BEL ETB ' 7 G W g w8 8 BS CAN ( 8 H X h x9 9 HT EM ) 9 I Y i y10 A LF SUB * : J Z j z11 B VT ESC + ; K [ k {12 C FF FS , < L \ l |13 D CR GS - = M ] m }14 E SO RS . > N ^ n ~15 F SI US / ? O _ o DEL
How would you make the following hardware Tx UART?
8-bit parallel data comes in tx_data(7:0) and is loaded into a transmit buffer txbuff when tdre is high.When ready goes high the contents of txbuff is sent out TxD as asynchronous serial data. When txbuff is empty, tdre is set to 1.
uart_tx
TxD
ready tdre
tx_data(7:0)
clk clr
mark
startstop
delay
shift
!ready
ready
baud_count < bit time
baud_count >= bit timeand
bit_count < 8
baud_count >= bit timeand
bit_count >= 8
tdre <= ‘1’
tdre <= ‘0’;
TxD <= ‘1’;tdre <= ‘0’;
bit_count <= "0000";
tdre <= '0';TxD <= txbuff(0);txbuff(6 downto 0) <= txbuff(7 downto 1);bit_count <= bit_count + 1;
baud_count < bit time baud_count <= X"000";TxD <= '0';tdre <= '0';
baud_count <= X"000";
UART Transmit State Diagram
VHDLCanonical Sequential Network
Sta
te R
egis
ter
Com
bina
tion
alN
etw
ork
x(t)
s(t+1) s(t)
z(t)clk
init
present state
present input
nextstate
present output
process(clk, init)
process(present_state, x)
VHDLMealy Machine
Sta
te R
egis
ter
C1
x(t)
s(t+1)
s(t)z(t)
clk
init
present state
present input
nextstate
C2
process(clk, init)
process(present_state, x)
process(present_state, x)
VHDLMoore Machine
Sta
te R
egis
ter
C1
x(t)
s(t+1)
s(t)
z(t)
clk
init
present state
present input
nextstate
C2
process(present_state, x) process(present_state)
process(clk, init)
VHDLCanonical Sequential Network
Sta
te R
egis
ter
Com
bina
tion
alN
etw
ork
x(t)
s(t+1) s(t)
z(t)clk
init
present state
present input
nextstate
present output
process(clk, init)
process(present_state, x)
Combine into a single process
mark
startstop
delay
shift
!ready
ready
baud_count < bit time
baud_count >= bit timeand
bit_count < 8
baud_count >= bit timeand
bit_count >= 8
tdre <= ‘1’
tdre <= ‘0’;
TxD <= ‘1’;tdre <= ‘0’;
bit_count <= "0000";
tdre <= '0';TxD <= txbuff(0);txbuff(6 downto 0) <= txbuff(7 downto 1);bit_count <= bit_count + 1;
baud_count < bit time baud_count <= X"000";TxD <= '0';tdre <= '0';
baud_count <= X"000";
UART Transmit State Diagram
entity uart_tx is port(
clk : in STD_LOGIC; clr : in STD_LOGIC; tx_data : in STD_LOGIC_VECTOR(7 downto 0); ready : in STD_LOGIC; tdre : out STD_LOGIC; TxD : out STD_LOGIC
);end uart_tx;
uart_tx
TxD
ready tdre
tx_data(7:0)
clk clr
architecture uart_tx of uart_tx istype state_type is (mark, start, delay, shift, stop);signal state: state_type;signal txbuff: STD_LOGIC_VECTOR (7 downto 0);signal baud_count: STD_LOGIC_VECTOR (11 downto 0);signal bit_count: STD_LOGIC_VECTOR (3 downto 0);constant bit_time: STD_LOGIC_VECTOR (11 downto 0) := X"A28";
begin
9600 baud
uart2: process(clk, clr, ready) begin if clr = '1' then
state <= mark;txbuff <= "00000000";baud_count <= X"000";bit_count <= "0000";TxD <= '1';
elsif (clk'event and clk = '1') thencase state is
when mark => -- wait for readybit_count <= "0000";tdre <= '1';
if ready = '0' then state <= mark;
txbuff <= tx_data; else
baud_count <= X"000"; state <= start; -- go to start end if;
mark
startstop
delay
shift
!ready
ready
baud_count < bit time
baud_count >= bit timeand
bit_count < 8
baud_count >= bit timeand
bit_count >= 8
tdre <= ‘1’
tdre <= ‘0’;
TxD <= ‘1’;tdre <= ‘0’;
bit_count <= "0000";
tdre <= '0';TxD <= txbuff(0);txbuff(6 downto 0) <= txbuff(7 downto 1);bit_count <= bit_count + 1;
baud_count < bit time baud_count <= X"000";TxD <= '0';tdre <= '0';
baud_count <= X"000";
when start => -- output start bit baud_count <= X"000";TxD <= '0';tdre <= '0';
state <= delay; -- go to delay when delay => -- wait bit time
tdre <= '0'; if baud_count >= bit_time then
baud_count <= X"000"; if bit_count < 8 then -- if not done
state <= shift; -- go to shift else -- else
state <= stop; -- go to stop end if;else baud_count <= baud_count + 1;
state <= delay; -- stay in delay end if;
mark
startstop
delay
shift
!ready
ready
baud_count < bit time
baud_count >= bit timeand
bit_count < 8
baud_count >= bit timeand
bit_count >= 8
tdre <= ‘1’
tdre <= ‘0’;
TxD <= ‘1’;tdre <= ‘0’;
bit_count <= "0000";
tdre <= '0';TxD <= txbuff(0);txbuff(6 downto 0) <= txbuff(7 downto 1);bit_count <= bit_count + 1;
baud_count < bit time baud_count <= X"000";TxD <= '0';tdre <= '0';
baud_count <= X"000";
when shift => -- get next bit tdre <= '0'; TxD <= txbuff(0);
txbuff(6 downto 0) <= txbuff(7 downto 1); bit_count <= bit_count + 1; state <= delay;
when stop => -- stop bit tdre <='0'; TxD <= '1';
if baud_count >= bit_time then baud_count <= X"000";
state <= mark; else
baud_count <= baud_count + 1; state <= stop; end if; end case; end if; end process uart2; end uart_tx;
mark
startstop
delay
shift
!ready
ready
baud_count < bit time
baud_count >= bit timeand
bit_count < 8
baud_count >= bit timeand
bit_count >= 8
tdre <= ‘1’
tdre <= ‘0’;
TxD <= ‘1’;tdre <= ‘0’;
bit_count <= "0000";
tdre <= '0';TxD <= txbuff(0);txbuff(6 downto 0) <= txbuff(7 downto 1);bit_count <= bit_count + 1;
baud_count < bit time baud_count <= X"000";TxD <= '0';tdre <= '0';
baud_count <= X"000";
wtbtndn
wttdrewtbtnup
load
!btn
btn
!tdre
tdre
ready <= ‘0’
ready <= ‘0’
ready <= ‘0’
ready <= ‘1’
btn
!btn
Test Transmit UART
Set slide switches to some ASCII code and then press button 0 to send ASCII code out serial port.
uart_txTxD
ready tdre
tx_data(7:0)
clk clr
SW
BTN(0)Test_tx_ctrl
btn
ready
tdre
clk clr
entity tx_tst_ctrl is port(
clk : in STD_LOGIC; clr : in STD_LOGIC; btn : in STD_LOGIC; tdre : in STD_LOGIC; ready : out STD_LOGIC
);end tx_tst_ctrl;
Test_tx_ctrl
btn
ready
tdre
clk clr
architecture tx_tst_ctrl of tx_tst_ctrl istype state_type is (wtbtndn, wttdre, load, wtbtnup);signal state: state_type;
begin ctrl: process(clk, clr, btn, tdre) begin if clr = '1' then
state <= wtbtndn;ready <= '0';
elsif (clk'event and clk = '1') then case state is when wtbtndn => -- wait for btn if btn = '0' then -- if bnt up state <= wtbtndn; -- stay in wtbtndo
ready <= '0'; else
ready <= '0'; state <= wttdre; -- else go to wttdre end if;
wtbtndn
wttdrewtbtnup
load
!btn
btn
!tdre
tdre
ready <= ‘0’
ready <= ‘0’
ready <= ‘0’
ready <= ‘1’
btn
!btn
when wttdre => -- wait for tdre = 1 if tdre = '0' then -- if tdre = 0 state <= wttdre; -- stay in wtdone
ready <= '0'; else state <= load; -- else go to load
ready <= '0'; end if; when load => -- output ready ready <= '1'; state <= wtbtnup; -- go to wtbtnup
wtbtndn
wttdrewtbtnup
load
!btn
btn
!tdre
tdre
ready <= ‘0’
ready <= ‘0’
ready <= ‘0’
ready <= ‘1’
btn
!btn
when wtbtnup => -- wait for btn up if btn = '1' then -- if btn down state <= wtbtnup; -- stay in wtbtnup
ready <= '0'; else
ready <= '0'; state <= wtbtndn; -- else go to wtbtndn end if; end case; end if; end process ctrl; end tx_tst_ctrl;
wtbtndn
wttdrewtbtnup
load
!btn
btn
!tdre
tdre
ready <= ‘0’
ready <= ‘0’
ready <= ‘0’
ready <= ‘1’
btn
!btn
Test Transmit UARTTop-level design
entity uart_tx_test is port (
mclk : in STD_LOGIC; SW : in STD_LOGIC_VECTOR(7 downto 0); BTN : in STD_LOGIC_VECTOR(3 downto 0); LD : out STD_LOGIC_VECTOR(7 downto 0); TxD : out STD_LOGIC
);end uart_tx_test;
Pin "R13"
architecture uart_tx_test_arch of uart_tx_test is
component uart_tx port(
clk : in STD_LOGIC; clr : in STD_LOGIC; tx_data : in STD_LOGIC_VECTOR(7 downto 0); ready : in STD_LOGIC; tdre : out STD_LOGIC; TxD : out STD_LOGIC
);end component;
component tx_tst_ctrl port(
clk : in STD_LOGIC; clr : in STD_LOGIC; btn : in STD_LOGIC; tdre : in STD_LOGIC; ready : out STD_LOGIC
);end component;
uart_txTxD
ready tdre
tx_data(7:0)
clk clr
Test_tx_ctrl
btn
ready
tdre
clk clr
component debounce isport (
inp, clk, clr: in std_logic;outp: out std_logic
);end component;
signal clr, clk, cclk: std_logic;signal tdre, ready, BTN0: std_logic;signal clkdiv : std_logic_vector(23 downto 0);
begin
inp
delay1 delay3delay2
outp
cclk
inp
delay1 delay2
outp
inp
delay1 delay2
outp
-- Divide the master clock (50Mhz) down to a lower frequency.
process (mclk)begin
if clr = '1' thenclkdiv <= "000000000000000000000000";
elsif mclk = '1' and mclk'Event then clkdiv <= clkdiv + 1;
end if;end process;
clk <= clkdiv(0); -- 25 MHzcclk <= clkdiv(17); -- 190 Hz
LD(7) <= BTN(1); LD(6) <= BTN(2); LD(5) <= BTN(1); LD(4) <= BTN(2); LD(3) <= BTN(1); LD(2) <= BTN(2); LD(1) <= BTN(1); LD(0) <= tdre; clr <= BTN(3);
U1: uart_tx port map (TxD => TxD, clk => clk, clr => clr, ready => ready,
tx_data => SW,tdre => tdre);
U2: tx_tst_ctrl port map (clk => clk, clr => clr, btn => BTN0, tdre => tdre,
ready => ready);
U3: debounce port map (inp => BTN(0), clr => clr, clk => cclk, outp => BTN0);
end uart_tx_test_arch;
uart_tx
TxD
ready tdre
tx_data(7:0)
clk clr
SW
BTN(0) inp
delay1 delay3delay2
outp
cclk
inp
delay1 delay2
outp
inp
delay1 delay2
outp
Test_tx_ctrl
btn
ready
tdre
clk clr
uart_rx
RxD
clrflg rdrf
FE
data_rx(7:0)
How would you make the following hardware Rx 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.
MARK
SPACESTART
STOP
PARITY
D0 D1 D2 D3 D4 D5 D6 D7
ASCII code 54H = 1010100 ("T") sent with odd parity
Common Asynchronous Serial Baud Rates
Baud rate Bit time (msec)
No. of STOP bits
Char. time (msec.)
Char./sec.
110 9.09 2 100.00 10 300 3.33 1 33.3 3 30 600 1.67 1 16.67 60
1200 0.833 1 8.33 120 2400 0.417 1 4.17 240 4800 0.208 1 2.08 480 9600 0.104 1 1.04 960
14400 0.069 1 0.69 1440 19200 0.052 1 0.52 1920 28800 0.035 1 0.35 2880 38400 0.026 1 0.26 3840
UART clock frequency = 16 x Baud rate or 64 x Baud rate
mark
startstop
delay
shift
RxD
!RxD
baud_count < 0.5 bit time
baud_count < bit time
baud_count >= 0.5 bit time
baud_count >= bit timeand
bit_count < 8
baud_count >= bit timeand
bit_count >= 8
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;
uart_rxRxD
rdrf_clr
rdrf
FE
rx_data(7:0)
clr
clk
architecture uart_rx of uart_rx istype 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 <= "00000000";baud_count <= X"000";bit_count <= "0000";FE <= '0';
elsif rdrf_clr = '1' thenrdrf <= '0';
elsif (clk'event and clk = '1') thencase state is
when mark => -- wait for start bit baud_count <= X"000";
bit_count <= "0000"; if RxD = '1' then state <= mark; else
FE <= '0'; state <= start; -- go to start end if;
mark
startstop
delay
shift
RxD
!RxD
baud_count < 0.5 bit time
baud_count < bit time
baud_count >= 0.5 bit time
baud_count < bit timeand
bit_count < 8
baud_count >= bit timeand
bit_count >= 8
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;
mark
startstop
delay
shift
RxD
!RxD
baud_count < 0.5 bit time
baud_count < bit time
baud_count >= 0.5 bit time
baud_count < bit timeand
bit_count < 8
baud_count >= bit timeand
bit_count >= 8
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;
mark
startstop
delay
shift
RxD
!RxD
baud_count < 0.5 bit time
baud_count < bit time
baud_count >= 0.5 bit time
baud_count < bit timeand
bit_count < 8
baud_count >= bit timeand
bit_count >= 8
Test of UART
uart_rxRxD
rdrf_clr
rdrf
FE
rx_data(7:0)
clr
clk
uart_tx
TxD
ready tdre
tx_data(7:0)
clk clr
Test_tx_ctrl
btn
ready
tdre
clk clr
Test_rx_ctrl rdrf_clrrdrf
clk clr
Test Receive UART
Receive ASCII code sent from terminal program on PC when key is pressed and display on LEDs.
uart_rxRxD
rdrf_clr
rdrf
FE
rx_data(7:0)
clr
clk
Test_rx_ctrl rdrf_clrrdrf
clk clr
wtrdrf
load
!rdrf
rdrf
rdrf_clr <= ‘1’
rdrf_clr <= ‘0’
wtbtndn
wttdrewtbtnup
load
!btn
btn
!tdre
tdre
ready <= ‘0’
ready <= ‘0’
ready <= ‘0’
ready <= ‘1’
btn
!btn
Test Transmit UART
Echo back ASCII code sent from PC.
uart_txTxD
ready tdre
tx_data(7:0)
clk clr
rdrf_clrTest_tx_ctrl
btn
ready
tdre
clk clr
entity test2_rx_ctrl is port(
clk : in STD_LOGIC; clr : in STD_LOGIC; rdrf : in STD_LOGIC; rdrf_clr : out STD_LOGIC
);end test2_rx_ctrl;
Test_rx_ctrl rdrf_clrrdrf
clk clr
architecture test2_rx_ctrl of test2_rx_ctrl istype state_type is (wtrdrf, load);signal state: state_type;
begin ctrl: process(clk, clr, rdrf) begin if clr = '1' then
state <= wtrdrf;rdrf_clr <= '0';
elsif (clk'event and clk = '1') thencase state is
when wtrdrf =>rdrf_clr <= '0';
if rdrf = '0' then state <= wtrdrf; else state <= load; end if; when load =>
rdrf_clr <= '1'; state <= wtrdrf; end case; end if; end process ctrl; end test2_rx_ctrl;
wtrdrf
load
!rdrf
rdrf
rdrf_clr <= ‘1’
rdrf_clr <= ‘0’
entity uart_test2 is port (
mclk : in STD_LOGIC; BTN3 : in STD_LOGIC; RxD : in STD_LOGIC; LD : out STD_LOGIC_VECTOR(7 downto 0); TxD : out STD_LOGIC
);end uart_test2;
architecture uart_test2_arch of uart_test2 is
component uart_tx port(
clk : in STD_LOGIC; clr : in STD_LOGIC; tx_data : in STD_LOGIC_VECTOR(7 downto 0); ready : in STD_LOGIC; tdre : out STD_LOGIC; TxD : out STD_LOGIC
);end component;
Top-level test of UART
uart_txTxD
ready tdre
tx_data(7:0)
clk clr
component tx_tst_ctrl port(
clk : in STD_LOGIC; clr : in STD_LOGIC; btn : in STD_LOGIC; tdre : in STD_LOGIC; ready : out STD_LOGIC
);end component;
component uart_rx 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 component;
uart_rxRxD
rdrf_clr
rdrf
FE
rx_data(7:0)
clr
clk
Test_tx_ctrl
btn
ready
tdre
clk clr
component test2_rx_ctrl port(
clk : in STD_LOGIC; clr : in STD_LOGIC; rdrf : in STD_LOGIC; rdrf_clr : out STD_LOGIC
);end component;
signal clr, clk, cclk: std_logic;signal tdre, rdrf, rdrf_clr, FE, ready, btn: std_logic;signal clkdiv : std_logic_vector(23 downto 0);signal data : std_logic_vector(7 downto 0);
Test_rx_ctrl rdrf_clrrdrf
clk clr
begin
-- Divide the master clock (50Mhz) down to a lower frequency.process (mclk)begin
if clr = '1' thenclkdiv <= "000000000000000000000000";
elsif mclk = '1' and mclk'Event then clkdiv <= clkdiv + 1;
end if;end process;
clk <= clkdiv(0); -- 25 MHzcclk <= clkdiv(17); -- 190 Hz
LD <= data; clr <= BTN3;
btn <= rdrf_clr; Test_tx_ctrl
btn
ready
tdre
clk clr
Test_rx_ctrl rdrf_clrrdrf
clk clr
U1: uart_tx port map (TxD => TxD, clk => clk, clr => clr, ready => ready,
tx_data => data,tdre => tdre);
U2: uart_rx port map (RxD => RxD, clk => clk, clr => clr, rdrf_clr => rdrf_clr,
rx_data => data,rdrf => rdrf, FE => FE);
U3: tx_tst_ctrl port map (clk => clk, clr => clr, tdre => tdre, btn => btn,
ready => ready);
U4: test2_rx_ctrl port map (clk => clk, clr => clr, rdrf => rdrf, rdrf_clr => rdrf_clr);
end uart_test2_arch;
uart_rxRxD
rdrf_clr
rdrf
FE
rx_data(7:0)
clr
clk
uart_tx
TxD
ready tdre
tx_data(7:0)
clk clr
Test_tx_ctrl
btn
ready
tdre
clk clr
Test_rx_ctrl rdrf_clrrdrf
clk clr