1 | library IEEE;
|
2 | use IEEE.STD_LOGIC_1164.ALL;
|
3 | use IEEE.NUMERIC_STD.ALL;
|
4 |
|
5 | entity RS232 is
|
6 | Generic ( Quarz_Taktfrequenz : integer := 50000000; -- Hertz
|
7 | Baudrate : integer := 9600 -- Bits/Sec
|
8 | );
|
9 | Port ( RXD : in STD_LOGIC;
|
10 | TXD : out STD_LOGIC;
|
11 | CLK : in STD_LOGIC;
|
12 | LED : out STD_LOGIC_VECTOR (7 downto 0)
|
13 |
|
14 | );
|
15 | end RS232;
|
16 |
|
17 | architecture Behavioral of RS232 is
|
18 |
|
19 | signal txstart : std_logic;
|
20 | signal txsr : std_logic_vector (9 downto 0) := "1111111111"; -- Startbit, 8 Datenbits, Stopbit
|
21 | signal txbitcnt : integer range 0 to 10 := 10;
|
22 | signal txcnt : integer range 0 to (Quarz_Taktfrequenz/Baudrate)-1;
|
23 |
|
24 | signal rxd_sr : std_logic_vector (3 downto 0) := "1111"; -- Flankenerkennung und Eintakten
|
25 | signal rxsr : std_logic_vector (7 downto 0) := "00000000"; -- 8 Datenbits
|
26 | signal rxbitcnt : integer range 0 to 9 := 9;
|
27 | signal rxcnt : integer range 0 to (Quarz_Taktfrequenz/Baudrate)-1;
|
28 |
|
29 | ---------------------------------------------------------------------------
|
30 | signal counter: integer range 0 to 50000000 :=0;
|
31 | --
|
32 | --
|
33 | signal RX_Data : STD_LOGIC_VECTOR (7 downto 0);
|
34 | signal RX_Busy : STD_LOGIC;
|
35 | signal TX_Data : STD_LOGIC_VECTOR (7 downto 0):= "10101010";
|
36 | signal TX_Start : STD_LOGIC;
|
37 | signal TX_Busy : STD_LOGIC;
|
38 |
|
39 | ---------------------------------------------------------------------------
|
40 |
|
41 | begin
|
42 |
|
43 | process (CLK)begin
|
44 | If rising_edge(CLK) then
|
45 | If counter < Quarz_Taktfrequenz/2 then
|
46 | TX_Start <= '1';
|
47 | -- txstart <= '0';
|
48 |
|
49 | elsif counter = Quarz_Taktfrequenz then
|
50 | counter <= 0;
|
51 | else
|
52 | --LED(1) <= '1';
|
53 | TX_Start <= '0';
|
54 | -- txstart <= '1';
|
55 | end if;
|
56 | end if;
|
57 | end process;
|
58 |
|
59 | -- Senden
|
60 | process begin
|
61 | wait until rising_edge(CLK);
|
62 | txstart <= TX_Start;
|
63 | if (TX_Start='1' and txstart='0') then -- steigende Flanke, los gehts
|
64 |
|
65 | txcnt <= 0; -- Zähler initialisieren
|
66 | txbitcnt <= 0;
|
67 | txsr <= '1' & TX_Data & '0'; -- Stopbit, 8 Datenbits, Startbit, rechts gehts los
|
68 | --LED(0) <= '1';
|
69 | else
|
70 | if(txcnt<(Quarz_Taktfrequenz/Baudrate)-1) then
|
71 | txcnt <= txcnt+1;
|
72 | else -- nächstes Bit ausgeben
|
73 | if (txbitcnt<10) then
|
74 |
|
75 | txcnt <= 0;
|
76 | txbitcnt <= txbitcnt+1;
|
77 | txsr <= '1' & txsr(txsr'left downto 1);
|
78 | end if;
|
79 | end if;
|
80 | end if;
|
81 | end process;
|
82 |
|
83 | TXD <= txsr(0); -- LSB first
|
84 | TX_Busy <= '1' when (TX_Start='1' or txbitcnt<10) else '0';
|
85 | --LED(2) <= '1';
|
86 | -- Empfangen
|
87 | process begin
|
88 | wait until rising_edge(CLK);
|
89 | rxd_sr <= rxd_sr(rxd_sr'left-1 downto 0) & RXD;
|
90 | if (rxbitcnt<9) then -- Empfang läuft
|
91 | if(rxcnt<(Quarz_Taktfrequenz/Baudrate)-1) then
|
92 | rxcnt <= rxcnt+1;
|
93 | else
|
94 | rxcnt <= 0;
|
95 | rxbitcnt <= rxbitcnt+1;
|
96 | rxsr <= rxd_sr(rxd_sr'left-1) & rxsr(rxsr'left downto 1); -- rechts schieben, weil LSB first
|
97 | end if;
|
98 | else -- warten auf Startbit
|
99 | if (rxd_sr(3 downto 2) = "10") then -- fallende Flanke Startbit
|
100 | rxcnt <= ((Quarz_Taktfrequenz/Baudrate)-1)/2; -- erst mal nur halbe Bitzeit abwarten
|
101 | rxbitcnt <= 0;
|
102 | end if;
|
103 | end if;
|
104 | end process;
|
105 | RX_Data <= rxsr;
|
106 | LED <= RX_Data;
|
107 | RX_Busy <= '1' when (rxbitcnt<9) else '0';
|
108 |
|
109 | end Behavioral;
|