mikrocontroller.net

Forum: FPGA, VHDL & Co. RS232 Kommandos auswerten


Autor: Frank S. (karnikel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tach tach,

ich möchte gern über die RS232 Schnittstelle Befehle von einem 
Terminalprogramm an die RS232 Schnittstelle senden und auswerten. So 
z.B. möchte ich Kanal 1 auf 200ns Zeitverzögerung setzen 
(Beispielbefehl: "ch1delay_200").
Meine Idee mithilfe einer State Machine sieht wie folgt aus:
Ich dachte mir dass ich die Bitfolge bis "_" auswerte, zum 
entsprechenden case springe, dort die folgende Zahl auswerte und diese 
dann im FPGA auf Kanal 1 angewendet wird.
Ist dies überhaupt im FPGA "on the fly" möglich, oder kann ich nicht so 
einfach wie ich mir das denke die Parameter für ein bereits im FPGA 
laufendes Programm ändern?
Gibts von euch nen besseren Vorschlag wie man diese Sache implementieren 
könnte?

Die Programmierung erfolgt in VHDL und zur verfügung steht ein Spartan 
3AN. RS232 Daten kann ich bereits empfangen. Es geht nur um die 
Auswertung dieser Daten.

Vielen Dank

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karnikel S. schrieb:
> Gibts von euch nen besseren Vorschlag wie man diese Sache implementieren
> könnte?
Nicht einen langen Bitstrom auswerten, denn was machst du, wenn du mal 
eine kleine Pause in der Übertragung hast?

Machs so, wie es alle Welt macht: Ein Zeichen nach dem anderen 
empfangen, und auswerten.

Karnikel S. schrieb:
> Ist dies überhaupt im FPGA "on the fly" möglich, oder kann ich nicht so
> einfach wie ich mir das denke die Parameter für ein bereits im FPGA
> laufendes Programm ändern?
Du kannst in deinem FPGA machen, was du willst. Und natürlich lassen 
sich irgendwelche Zähler und Vergleichswerte zur Laufzeit ändern...

Autor: Frank S. (karnikel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, danke für die schnelle Antwort.

Wie genau macht es denn "alle Welt"? Funktioniert es denn nur so:

if erstes Byte = "c" then
if zweites Byte = "h" then
if drittes Byte = "1" then
if usw.
else "mach nix"

oder gibt es da ne einfachere und kürzere Möglichkeit?

Wie bekomme ich denn raus ob das Kommando vollständig ist...es ist zwar 
möglich ein Symbol am ende anzuhängen das mir das ende anzeigt, oder ich 
könnte auch den Befehl auf genau z.b. 8 Byte beschränken aber irgednwie 
hätt ich gern was variables. Wahrscheinlich macht es am meisten sinn, 
wenn ich am Ende abfrage ob das Byte "11111111" ist oder?

Autor: MW (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine Statemachine, die auf ein eingehendes Zeichen wartet, das dann z.B. 
in ein Schieberegister schiebt und auf das nächste wartet ist eine 
Variante. Damit vermeidet man lange if-else-Abfolgen.

Dann eine Art "Ende-Zeichen", nach dem der ganze Befehl im 
Schieberegister ausgewertet werden kann, bei serieller Übertragung nimmt 
dafür meist das CR/LF- Symbol.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karnikel S. schrieb:
> Funktioniert es denn nur so:
Ja, wie denn sonst?
Uch wenn du z.B. in C einen schönen eleganten Funktionsaufruf wie 
strcmp() hinschreiben kannst, wird "ganz unten" nichts anderes 
gemacht...

Autor: Harald Flügel (hfl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auch Tach!

Ich bin ein großer Freund davon, Hardware-Aufgaben in Hardware (Verilog, 
VHDL) zu lösen und Software-Aufgaben in Software (C). Das, was Du da 
machen wills, ist die Interpretierung eines seriellen Byte-Protokolls 
und somit meines Erachtens eine Aufgabe für einen Prozessor. Der würde 
dann auch einen Timeout feststellen, oder ein nicht gültiges Zeichen 
etc. Ich finde, Du solltest darüber nachdenken, einen Prozessor ins FPGA 
zu holen.

Autor: Rene B. (themason) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also je nach Anzahl der Befehle wäre eine Statemachine am einfachsten.
Die Statemachine wird nur getriggert wenn ein neues Zeichen von der 
RS232 reinkommt und das nächste Zeichen verarbeitet. Wenn du die Befehle 
schön kurz hälst (2-3 Zeichen zum erkennen eines Befehls und) und statt 
Dezimal Hexadezimal verwendest sollte es auch nicht allzuviele 
Ressourcen verbrauchen. (Durch die Dezimale Schreibweise brauchst du 
evtl. einen Multiplizierer, bei Hexa schubst du einfach nur 4 Bit durch 
die gegend). Du könntest dir dann den erkannten Befehl und den 
dazugehörigen Parameter in einem Schattenregister speichern und wenn 
alles OK ist und Return gedrückt wird das Register dann zur Auswertung 
(bzw Befehlsausführung) in das Arbeitsregister kopiert.
Einen Timeout sollte man ebenfalls vorsehen, der die aktuelle Eingabe 
vewirft und die Statemachin zurücksetzt.

Ein Softcore-Prozessor ist da sicherlich auch eine denkbare Alternative, 
nur wenn es nur 2-3 Befehle sind die immer/annähernd gleich sind ist ein 
Softcore denke ich übertrieben. Oder wenn du wirklich eine richtige 
Eingabeaufforderung haben willst mit Zwischenspeicher, schöner Ausgabe 
usw., vielen Befehlen, Dezimale oder Hexa Schreibweise automatisch 
unterscheiden soll wäre ein Softcore geeignet.

Kommt halt immer auf den Zweck bzw die Komplexität an.

Autor: Frank S. (karnikel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, vielen dank für die Anregungen. Ich hätte da aber noch ne allgemeine 
VHDL Frage:

Bisher habe ich den time_delay-Wert fest eingestellt und mein Programm 
in der Top-entity wie folgt bekannt gemacht:
architecture Behavioral of main is
:
:
component Delay_1 is
  generic 
    (
    system_speed     : integer := 50000000;            
    bitrate         : integer := 1000000;            
    time_delay       : integer := 2000
    );
  port
    (
    RESET          : in std_logic;              
    clk_i          : in std_logic;              
    start_1        : in std_logic;
    valid_bitwise_1  : in std_logic;
    get_fifo_data_1  : out std_logic;
    not_save_1      : out std_logic;
    bitwise_delay_in_1: in std_logic_vector(21 downto 0);
    dat_delay_in_1    : in std_logic_vector(21 downto 0);
    dat_delay_out_1  : out std_logic_vector(21 downto 0)
    );
end component Delay_1;
:
:
begin
:
:
Delay_1_inst : Delay_1
  generic map
    (
    system_speed         => 50000000,            
    bitrate             => 1000000,            
    time_delay           => 2000
    )
  port map
    (
    RESET              => RESET_i,
    clk_i              => CLK_50M_i,
    start_1            => REC_1_TIMER_STARTxDELAY_1_START,
    valid_bitwise_1      =>  REC_1_VALID_BITWISExDELAY_1_VALID_BITWISE,
    get_fifo_data_1      => FIFO_1_RD_ENxDELAY_1_GET_FIFO_DATA,
    not_save_1          => DELAY_1_NOT_SAVExRECEIVE_1_NOT_SAVE,
    bitwise_delay_in_1    => REC_1_BW_DAT1xDELAY_1_BITWISE_IN,
    dat_delay_in_1        => FIFO_1_DOUTxDELAY_1_DAT_DELAY_IN,
    dat_delay_out_1      => DELAY_1_DATOUTxSEND_1_DAT_IN
    );

Wenn ich nun "time_delay" variabel machen möchte, muss dann time_delay 
in "port / port map" mit rein?Oder reicht es, wenn ich die 2000 durch 
eine Variable ersetze und diese dann mit meinen Werten die ich per RS232 
erhalte beschreibe?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karnikel S. schrieb:
> Oder reicht es, wenn ich die 2000 durch eine Variable ersetze
Nein.
Über Ports kommen veränderliche Werte/Signale.
Über Generics nur Konstanten...

> wenn ich die 2000 durch eine Variable ersetze
Variablen sind sowieso nur innerhalb eines Prozesses gültig. Und fang 
mir bloß nicht mit den Shared Variables an. Das sind solche 
nachgebastelten Kostrukte für Softwareprogrammierer, die jetzt Hardware 
machen müssen/wollen/sollen...

Karnikel S. schrieb:
> Wenn ich nun "time_delay" variabel machen möchte, muss dann time_delay
> in "port / port map" mit rein?
Ja.
Am besten (bzw. portabelsten) über einen Vektor, der danach wieder in 
einen integer konvertiert wird.

Autor: Frank S. (karnikel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen vielen Dank für eure Hilfe. Ich kann jetz jedem meiner 4 Kanäle 
einen Verzögerungswert per RS232 übergeben.

Ich hätt aber noch ne weiterführende Frage:
Ich kann ja mein Programm in den SPI Prom schreiben, so dass mein 
Programm geladen wird, sobald ich das Board einschalte. Jedoch lädt der 
FPGA jedes mal die Verzögerungszeiten mit den fest eingestellten 
Default-Werten. Wenn ich nun per RS232 diese Zeiten ändere übernimmt er 
diese zwar, "vergisst" diese aber wieder, sobald ich das Board 
ausschalte. Gibt es eine Möglichkeit, dass diese gespeichert werden? 
Wenn ja wie?
Ich hab zwar mehrere ROMs auf dem Board, kann diese aber jweils nur 
ansteuern, wenn ich Jumper umstecke (soweit ich weiß). Also kann es 
anscheinend nur so gehen, dass ich die Werte im gleichen Speicher ablege 
wo das Prog gespeichert ist, oder das komplette Programm immer wieder 
neu in den ROM geschrieben wird, wenn ein neuer Verzögerungswert 
eingegeben wird.
Oder gibt es da noch ne einfachere Möglichkeit?
Es handelt sich dabei um 4 integer Werte, jeweils im Bereich von 100 bis 
100000000.
PS: ich hab das Spartan 3AN eval Board mit einem xc3s700an FPGA.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karnikel S. schrieb:
> Gibt es eine Möglichkeit, dass diese gespeichert werden?
> Wenn ja wie?
Du brauchst irgendeinen externen Speicher (EEPROM/Flash)...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.