Forum: FPGA, VHDL & Co. RS232-Emfand ohne " rx_state_t is (IDLE, BUSY, READY)".


von peter (Gast)


Lesenswert?

Hallo, wie kann man den Empfang ohne:
type   rx_state_t is (IDLE, BUSY, READY);
signal rx_state : rx_state_t := IDLE;
durchführen.

Was kann man da noch dafür reinsetzen?

Danke.
GRuss
1
type   rx_state_t is (IDLE, BUSY, READY);
2
signal rx_state : rx_state_t := IDLE;
3
signal rxd_sr   : std_logic_vector (3 downto 0) := "1111";         
4
signal rxsr     : std_logic_vector (7 downto 0) := "00000000";    
5
signal rxbitcnt : integer range 0 to 9 := 9;
6
signal rxcnt    : integer range 0 to (Quarz_Taktfrequenz/Baudrate)-1; 
7
signal rx_en  : STD_LOGIC :='0';
8
9
 -- EMPFANGEN
10
  process
11
  begin
12
    wait until rising_edge(CLK);   
13
    rxd_sr <= rxd_sr(rxd_sr'left-1 downto 0) & RXD;
14
    RX_en  <= '0';
15
    
16
    case rx_state is
17
      when IDLE => -- warten auf Startbit
18
        if (rxd_sr(3 downto 2) = "10") then                 
19
          rxcnt    <= ((Quarz_Taktfrequenz/Baudrate)-1)/2; 
20
          rxbitcnt <= 0;
21
          rx_state <= BUSY;
22
        end if;
23
      when BUSY =>
24
        if (rxbitcnt<9) then  
25
          if(rxcnt<(Quarz_Taktfrequenz/Baudrate)-1) then 
26
            rxcnt    <= rxcnt+1;
27
          else
28
            rxcnt    <= 0; 
29
            rxbitcnt <= rxbitcnt+1;
30
            rxsr     <= rxd_sr(rxd_sr'left-1) & rxsr(rxsr'left downto 1); 
31
          end if;
32
        else
33
          rx_state <= READY;
34
        end if;
35
      when READY =>
36
        RX_Data  <= rxsr;
37
        rx_state <= IDLE;   
38
    end case;
39
  end process;

von Marius W. (mw1987)


Lesenswert?

Welchen Sinn sollte das haben?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

peter schrieb:
> Was kann man da noch dafür reinsetzen?
Wofür und wozu? Was soll das bringen? Warum stellst du die Frage?

von Gustl B. (-gb-)


Lesenswert?

Also das Prinzip:

Man wartet solange bis man das Startbit erkennt. Dann zählt die 
eingestellte anzahl an Bits die man empfangen möchte und dann wartet man 
wieder.

Wenn du 8 Bits empfangen möchtest, dann zählst du langsam z. B. von 0 
bis 7. Langsam bedeutet, dass die Dauer eines Bits vermutlich deutlich 
länger ist wie der Takt mit dem gearbeitet wird.

(Quarz_Taktfrequenz/Baudrate) ist die Zahl der Takte die ein Bit lang 
ist (Zeitlänge). Da man den Wert des Bits aber möglichst sicher erfassen 
möchte, übernimmt man das Bit in dessen Mitte, zählt also nur von 0 bis

((Quarz_Taktfrequenz/Baudrate)-1)/2;

Takte und übernimmt dann den jeweiligen Wert. Damit man nicht immer die 
Hälfte zählen muss, kann man auch nur einmal am Anfang die halbe 
Zeitlänge warten, dann ist man mittig im Bit, und wartet ab dann immer 
die volle Länge.

Ob du jetzt extra Signale für Busy, Idle und so verwendest ist deine 
Sache. Du kannst auch zwei Zähler nehmen, also einen für die Bitdauer 
und einen für die Bitanzahl und dann daraus Verknüpfungen bauen.

Also sowas wie

wenn Bitzähler < 8 und Bitdauerzähler = Maximum dann
   Bitzähler <= Bitzähler +1; Bitdauerzähler <= 0; Daten(Bitzähler) <= 
RX;
wenn Bitzähler < 8 und Bitdauerzähler < Maximum dann
   Bitdauerzähler <= Bitdauerzähler +1;
wenn Bitzähler = 8 und rxd_sr(3 downto 2) = "10" dann
   Bitzähler <= 0; Bitdauerzähler <= 0;
ende;

Ich hab auch eine RS232 gebastelt, das sind wirklich nur zwei Zähler und 
ein Schieberegister. Zu den Zeiten ist der Wikipediaartikel ganz gut.

-gb-

von Christian R. (supachris)


Lesenswert?

peter schrieb:
> Was kann man da noch dafür reinsetzen?

Wenn man es unbedingt unübersichtlich haben will, kann man dafür auch 
STATE_1, STATE_2...schreiben oder gleich einen Zähler nehmen und dessen 
Zählerstand als Zustand der FSM selber bemutteln. Aber wieso sollte man 
das tun? Das macht der Sythesizer doch viel besser und man kann´s dann 
auch noch lesen.

von Peter B. (funkheld)


Lesenswert?

Jup, danke für eure Antworten.


Gruss

von Gustl B. (-gb-)


Lesenswert?

Also hier meine RS232 die Daten:
50MHz Takt, 921600Baud/s, 8N1, empfangen wird ein Byte, gesendet werden 
9 Bytes, wenn start_in '1' ist, werden die 9 Bytes gesendet, wenn 
start_out '1' ist dann ist ein Byte empfangen worden (das ist nur einen 
Takt lang '1').
rdy wird immer mal kurz auf '1' gesetzt wenn gerade keine Daten gesendet 
werden.

Ja, das sieht kompliziert aus, aber vieles ist so weil ich das genau so 
brauche, geht aber vermutlich auch einfacher. Was nicht gebraucht wird, 
muss ja nicht angeschlossen werden. Im Prinzip habe ich hier für jedes 
Byte nur einen Zähler, also nicht einen für die Bitzeit und einen für 
die einzelnen Bits, sondern beim Senden einen für die Zeiten im Byte und 
einen für die Bytes selber. Klar ist umständlich mit den festen Zahlen, 
aber ist eben jetzt so, darf Jeder gerne selber umstricken und 
optimieren.

Jedenfalls es funktioniert und erreicht auch einen hohen Durchsatz.
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
5
entity rs232 is -- 921600 8N1
6
  port (CLK          : in std_logic;
7
      start_in ,Rx    : in std_logic:='0';
8
      rdy, Tx, start_out: out std_logic:='0';
9
      ser_Data        : in std_logic_vector(71 downto 0):=x"000000000000000000";
10
      receive_byte    : out std_logic_vector(7 downto 0));
11
end rs232;
12
architecture Behavioral of rs232 is
13
14
signal send_count : integer range 0 to 554:= 554;
15
signal receive_count : integer range 0 to 465:= 465;
16
signal bytecounter : integer range 0 to 8:= 8;
17
signal send_byte: std_logic_vector(7 downto 0):=x"00";
18
signal neu : std_logic:='0';
19
signal ready : std_logic:='0';
20
21
signal rdy_c : integer range 0 to 7:= 0;
22
23
begin
24
25
process
26
begin
27
  wait until rising_edge(CLK);
28
  
29
  if send_count = 554 and bytecounter = 8 then ready <= '1'; else ready <= '0'; end if;
30
  if bytecounter = 8 and send_count = 554 and start_in = '1' then send_count <= 0; bytecounter <= 0; end if; --FIFO_rc <= FIFO_rc +1; end if;
31
  if bytecounter < 8 and send_count = 554 then send_count <= 0; bytecounter <= bytecounter +1; end if;
32
  
33
  if rdy_c < 7 then rdy_c <= rdy_c +1; else rdy_c <= 0; end if;
34
  if ready = '1' and rdy_c = 7 then rdy <= '1'; else rdy <= '0'; end if;
35
36
  if send_count < 554 then
37
    send_count <= send_count + 1;
38
  end if;
39
  if send_count = 0 then 
40
    if    bytecounter = 0 then send_byte <= ser_Data(71 downto 64);
41
    elsif bytecounter = 1 then send_byte <= ser_Data(63 downto 56);
42
    elsif bytecounter = 2 then send_byte <= ser_Data(55 downto 48);
43
    elsif bytecounter = 3 then send_byte <= ser_Data(47 downto 40);
44
    elsif bytecounter = 4 then send_byte <= ser_Data(39 downto 32);
45
    elsif bytecounter = 5 then send_byte <= ser_Data(31 downto 24);
46
    elsif bytecounter = 6 then send_byte <= ser_Data(23 downto 16);
47
    elsif bytecounter = 7 then send_byte <= ser_Data(15 downto  8);
48
    elsif bytecounter = 8 then send_byte <= ser_Data( 7 downto  0);
49
    end if;
50
  end if;
51
  
52
  if send_count                  < 54  then Tx <=            '0'; end if;
53
  if send_count > 53  and send_count < 108 then Tx <=   send_byte(0); end if;
54
  if send_count > 107 and send_count < 162 then Tx <=   send_byte(1); end if;
55
  if send_count > 161 and send_count < 216 then Tx <=   send_byte(2); end if;
56
  if send_count > 215 and send_count < 270 then Tx <=   send_byte(3); end if;
57
  if send_count > 269 and send_count < 324 then Tx <=   send_byte(4); end if;
58
  if send_count > 323 and send_count < 378 then Tx <=   send_byte(5); end if;
59
  if send_count > 377 and send_count < 432 then Tx <=   send_byte(6); end if;
60
  if send_count > 431 and send_count < 486 then Tx <=   send_byte(7); end if;
61
  if send_count > 485                then Tx <=            '1'; end if;
62
  
63
  --capture
64
   
65
  if receive_count > 462 and neu = '1' then receive_count <= 0; end if;
66
  
67
  if receive_count < 465 then
68
      receive_count <= receive_count + 1;
69
  end if;
70
  
71
  if receive_count =  81  then receive_byte(0) <= Rx; end if;
72
  if receive_count = 136  then receive_byte(1) <= Rx; end if;
73
  if receive_count = 189  then receive_byte(2) <= Rx; end if;
74
  if receive_count = 244  then receive_byte(3) <= Rx; end if;
75
  if receive_count = 298  then receive_byte(4) <= Rx; end if;
76
  if receive_count = 353  then receive_byte(5) <= Rx; end if;
77
  if receive_count = 407  then receive_byte(6) <= Rx; end if;
78
  if receive_count = 461  then receive_byte(7) <= Rx; end if;
79
  if receive_count = 462  then start_out <= '1'; else start_out <= '0'; end if;
80
  
81
end process;
82
83
process
84
variable sr : std_logic_vector (3 downto 0) := "0000";
85
begin
86
  wait until rising_edge(CLK);
87
  
88
   neu <= not sr(2) and sr(3); --FALL
89
    sr := sr(2 downto 0) & Rx;
90
  
91
end process;
92
93
end Behavioral;

-gb-

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.