Hallo!
Ich möchte nacheinander die Daten (data_0 bis data_3) über den UART am
PC ausgeben.
Hat jemand eine Idee, wie man das elegant und einfach lösen könnte.
Vielen Dank!
Gruss
Anfäng schrieb:> [vhdl]> data_0 <= "1111100001010101"> data_1 <= "0100101101001111"> data_3 <= "0001101010101010">> Ich möchte nacheinander die Daten (data_0 bis data_3) über den UART am> PC ausgeben.> Hat jemand eine Idee, wie man das elegant und einfach lösen könnte.
Hallo Anfänger,
also elegant wäre wenn man das gar nicht möchte, drei Daten seperater
Typen auszugeben.
Elegant wäre es wenn die Daten bereits als Array vorliegen würden.
Dazu musst Du Dir einen Datentyp definierien, bsp:
type data_03_typ is array (2 downto 0,15 downto 0) of std_logic;
signal data_03 : data_03_typ := ("1111100001010101", "0100101101001111"
, "0001101010101010"
);
Anschließend kannst Du die Daten mit Hilfe einer kleinen Statemaschine
dann durch deinen UART tackern.
Gruß
Vanilla
Hallo, vielleicht findest du auch mal eine Lösung mit "RX" um Daten in
ein Array zu schreiben:
Type Ram128x8 is ARRAY (0 to 127) OF unsigned(7 downto 0);
signal speicher_ram : Ram128x8;
oder:
Type Ram128x8 is ARRAY (0 to 127) of STD_LOGIC_VECTOR (7 downto 0);
signal speicher_ram : Ram128x8;
Gruss
Hallo Peter,
vielen Dank für deinen Bsp-Code. Ich habe das ganze mal implementiert
und versuche es zum Laufen zu bekommen.
Was realisierstu du auf deinem DE1 mit:
sw : in std_logic_vector(1 downto 0);
bzw.
sw0 und sw1
?
Gruss
Anfäng schrieb:> nur wie übergebe ich dann das Gesamtarray an TX_Data?
Gar nicht. Du musst ein Zeichen nach dem anderen übergeben und
dazwischen warten, bis die vorige Übertragung fertig ist. Für dieses
Warten ist eine FSM sinnvoll. Eigentlich läuft alles, was irgendwelche
zeitlichen Abläufe darstellt ("nacheinander", "erst das, dann das",
"solange", "während", "bis"...), in FPGAs über Zustandsautomaten.
Anfäng schrieb:> Was realisierstu du auf deinem DE1 mit:> sw : in std_logic_vector(1 downto 0);
Das ist ein zwei Bit breiter Eingangsvektor vom Typ std_logic. Das
findest du in deinem VHDL Buch ganz weit vorne...
Lothar Miller schrieb:> Das ist ein zwei Bit breiter Eingangsvektor vom Typ std_logic. Das> findest du in deinem VHDL Buch ganz weit vorne...
Das habe ich schon verstanden.
Nutzt er diese beiden Eingänge zum Ein- und Ausschalten des UARTs?
Gruss
sw(0) und sw(1) sind Schiebeschalter (switch).
Mit dem sw(0) gebe ich den Start zur Ausgabe nach Ablauf einer
bestimmten Zeit. Wenn ich den Schiebeschalter betätige , werden 6 Byte
ausgegeben dann ist Feierabend. Mit dem sw(1) setze ich die Adresse
wieder zum Anfang und es kann mit sw(0) wieder auegegeben werden.
GRuss
Peter Bierbach schrieb:> sw(0) und sw(1) sind Schiebeschalter (switch).> Mit dem sw(0) gebe ich den Start zur Ausgabe nach Ablauf einer> bestimmten Zeit. Wenn ich den Schiebeschalter betätige , werden 6 Byte> ausgegeben dann ist Feierabend. Mit dem sw(1) setze ich die Adresse> wieder zum Anfang und es kann mit sw(0) wieder auegegeben werden.>> GRuss
Hi,
hab es jetzt soweit hinbekommen.
Wie machst du das mit der Ausertung am PC?
Ich nutze HTerm.
Daten kommen zwar an, jedoch ist die Darstellgung bei mir falsch.
Gruss
Ich habe mir selber ein Programm geschrieben in Purebasic, weil ich den
Pc und das DE1 dann nach belieben kommunizieren lassen kann.
Für Testzwecke reicht aber der Hterm.
Was heisst falsch. Vielleicht stimmt die Baurate beim FPGA nicht überein
mit der vom Hterm? Oder der AScii stimmt nicht überein?
Nimm mal "Terminal" von hier :
http://hw-server.com/terminal-terminal-emulation-program-rs-232 der ist
nicht so aufgeblasen.
Gruss
Die übertragen Binärvektoren stimmen überhaupt nicht mit denen im
VHDL überein.
Baudrate und Qurarzfrequenz sind richtig eingestellt.
Wenn ich mit dem Oszi den Datenstrem anschaue, werden 7 Blöcke anstatt 6
übertragen.
????
Gruss
Ich weiss ja nicht, was du für eineFPGA-Platine hast?
Wenn 7 ankommen, stimmt deine Zählschleife nicht, aber trotzdem müssten
6 richtige im Lotto ankommen.
Gruss
Die Simulation kannste als Neuling vergessen, da werden teilweise
Zustände reingezaubert die noch unerklärlicher für eine Neuling sind.
Verlass dich erstmal auf deine Gedankenlogik und in die einer VHDL.
Dein Oszi ist schon eine Bereicherung zum Prüfen.
Gruss
Peter Bierbach schrieb:> Die Simulation kannste als Neuling vergessen, da werden teilweise> Zustände reingezaubert die noch unerklärlicher für eine Neuling sind.>> Verlass dich erstmal auf deine Gedankenlogik und in die einer VHDL.
Eine Simulation ist auch als Anfänger absolut empfehlenswert und gehört
zu den Dingen, die man so schnell wie möglich lernen sollte.
Eine Simulation ist wie der Debugger für ein PC-Programm.
Man kann damit alle Signale beobachten und entdeckt Gedankenfehler.
Die eigene Gedankenlogik kann zaubert nämlich noch viel unerklärlichere
Zustände als der Simulator. Dieser zaubert nämlich auch nur dann
unerklärliche Zustände, wenn die Gedankenlogik und das VHDL nicht
stimmen.
@ Peter,
der Unterschied zu meiner Hardware liegt darin,
dass mein FPGA mit 100 MHz läuft.
Ich glaube der Fehler liegt bei mir am Timining.
Wie müsste ich folgende Zeilen ändern, dass sie zu meinen 100 MHz
passen:
signal c : integer range 0 to 10000000 := 0;
if (c<10000000 ) then
Gruss
Robert S. schrieb:> Oder vielleicht das bereits vorhandene, aber dort nicht verwendete> Generic verwenden...
Hallo Robert,
kannst du mir das vll. genauer erklären?
---------------------------
Peter, läuft dein Simulator eigentlich schon?
--------------------------
Nein , Quartus unterbricht beim starten der Simu und das Win7 hat dann
stillstand.
Ich progge jetzt nach Logik und Aufbau.
Meine Programme sind nicht so weltbewegend.
Gruss
Die hat damit nichts zu tun:
signal c : integer range 0 to 10000000 := 0;
Das ist nur eine Zeitbremse für die Datenübertragung pro Byte zum PC.
Du musst hier deine 100.000.000 reinsetzen im Programm :
Quarz_Taktfrequenz : integer := 50000000;
Dann stimmt auch die Teilung nachher wieder zur Baud.
Im RS232 von Miller ist es eigentlich wurscht , ich glaube nur an die
115.000 Baud-Grenze scheitert ee ab und zu wenn der USB-Dongle am PC ein
billigprodukt ist.
Gruss
Peter Bierbach schrieb:> Du musst hier deine 100.000.000 reinsetzen im Programm :
Es ist nach wie vor kein "Programm", sondern eine Beschreibung (@Anfäng:
kleiner Running-Gag von Peter)...
> Du musst hier deine 100.000.000 reinsetzen
Dann wird jede Sekunde ein Zeichen gesendet...
------------------------------------------------
> Du musst hier deine 100.000.000 reinsetzen
Dann wird jede Sekunde ein Zeichen gesendet...
------------------------------------------------
Es geht hier um die Taktfrequenz und die Baud .... keine
Zeitverzögerung.
Gruss
Peter Bierbach schrieb:> Es geht hier um die Taktfrequenz und die Baud .... keine> Zeitverzögerung.
Es geht hier um die zeitliche Verzögerung zwischen den Startsignalen
zweier Zeichen:
1
if(c<5000000)then-- bei 50MHz werden ca. 10 Zeichen pro Sekunde gesendet (50MHz/5Mio)=10Hz
Guten Morgen,
@ Lothar Miller:
Ich habe gestern nochmals dein RS232 Beispiel implementiert und
getestet.
Im VHDL weise ich TX_Data <= "10101010"; zu.
Das Terminal spuckt mir jedoch immer 00010101 00000000 aus???????
Muss man das verstehen?
Gruss
Anfäng schrieb:> Ich habe gestern nochmals dein RS232 Beispiel implementiert
Wie und auf welcher Hardware?
> und getestet.
Mit einer Simulation?
> Das Terminal
Welches?
> spuckt mir jedoch immer 00010101 00000000 aus???????
Warum?
> Im VHDL weise ich TX_Data <= "10101010"; zu.
Wie oft wird tx_start aktiviert?
Und was passiert mit anderen Bitmustern?
> Muss man das verstehen?
Es wäre gut. Der Weg dorthin nennt sich "Lernen".
Die gute Nachricht: meine Beschreibung wurde schon zigfach verwendet und
auf einige FPGAs implementiert. Die Schlechte: irgendwas ist in deiner
Implementierung oder deiner Hardware noch faul.
Das Sendemodul habe ich wie oben dargestellt implementiert.
TX_Start wird über einen externen Schalter (Eingangspin) ausgelöst.
Müsste doch so in Ordnung sein.
Gruss
Lothar hatte dir 6 einfache Fragen gestellt und du beantwortet keine
davon. Erwartet du ernsthaft, dass man dir jetzt noch hilft?
Eine serielle Schnittstelle ist noch eher einfach, ich beschreibe mal
das Senden.
Wie seriell schon sagt wird immer nur ein Bit übertragen. Man liefert
die Bits intern aber oft als Byte an. Also hat man dieses Bit Array,
dieses Byte, und gibt davon nacheinander die Einträge auf die
Sendeleitung. Was man braucht ist etwas um die Baudrate einzustellen und
etwas um die Einträge des Bytes zu zählen, einen Laufindex quasi. Beides
geht mit Zählern. Dann gibt es noch das Start- und Stoppbit das man noch
setzt. Mehr ist das nicht.
Aber aller Anfang ist hart, daher würde ich mit blinkenden LEDs und so
anfangen um VHDL etwas zu verstehen.
Anfäng schrieb:> TX_Start wird über einen externen Schalter (Eingangspin) ausgelöst.> Müsste doch so in Ordnung sein.
Externe Signale müssen einsynchronisiert werden. Sonst hast du evtl. das
Problem der FSM mit asynchronem Eingang (das hier aber nicht die Ursache
ist!):
http://www.lothar-miller.de/s9y/categories/35-Einsynchronisieren> Müsste doch so in Ordnung sein.
Es kommt darauf an, wie und ob der unbekannte Schalter prellt.
> Müsste doch so in Ordnung sein.
Ich hatte 6 Fragen gestellt. Mindestens die Antwort für die erste wäre
hochinteressant...
(edit: Gustl Buheitel war schneller ;-)
---------------------------------------
X_Start wird über einen externen Schalter (Eingangspin) ausgelöst.
---------------------------------------
Da wird dann immer nur 1 Byte gesendet.
So kannst du es in einer Schleife einbinden.
Funktioniert bei meinem DE1 wunderbar:
1
ifc<5000000then
2
c<=c+1;
3
tx_start<='0';
4
elsifsw(0)='1'and(ramaddr<130)then
5
c<=0;
6
tx_start<='1';
7
TX_Data<=std_logic_vector(Speicher_ram(RamAddr));-- Daten von mein RAM-Bereich
8
led_r<=std_logic_vector(Speicher_ram(RamAddr));-- LED zur Kontrolle
-----------------------------------
begin
-- Senden
process begin
TX_Data <= "10101010";
wait until rising_edge(CLK);
-------------------------------------
Dein TX_Data kannst du nicht so wild nach Processbegin hinschmeissen.
Da kommt dann nur Kauderwelsch an am PC. Das muss mit im Takt
eingebunden werden damit es einen sychronen Lauf hat für die
Senderoutine.
Gruss
Hallo zusammen,
schon mal vielen Dank für die ganzen nützlichen Hilfestellungen.
Ich versuche nochmal alles neu aufzusetzen, hier eine kurze Beschreibung
was mein Ziel ist:
- Eval-Kit: DE0 nano
- FTDI UART - USB - Kabel
Würde gern die Sende- und Empfangsroutine von Lothar Miller auf dem DE0
nano implementieren.
Dazu möchte ich hintereinander mehrere 18 - bit lange std_logic_vector
an
mein Terminalprogramm übertragen und auswerten.
Der ganze Datenübertragung soll mit einstellbarem Taktzyklus ablaufen
(z.B. alle 2 Sekunden Übertragung der Datenpakete)
Wie ihr schon gemerkt habt, stecke ich VHDL-technisch noch in den
Kinderschuhen ;), aber vll. kann mir doch jemand spezifische
Hilfestellung geben.
Viel DANK!
Gruss
Holger
---------------------------
Dazu möchte ich hintereinander mehrere 18 - bit lange
----------------------------
Die musst du schon in Byte aufteilen wenn du von Miller die Routine
nutzen möchtest. oder überträgst die als Textstring 18Bit sind dann
18Ascii zum PC wenn es nicht so auf Geschwindigkeit ankommt wie du
schreibst ca alle 2 Sekunden.
Gruss
Anfäng schrieb:> Dazu möchte ich hintereinander mehrere 18 - bit lange std_logic_vector
Kann dein PC mit 18 Datenbits umgehen? Meiner kann nur 7 oder 8
Datenbits...
Du erkennst das Problem? Du wirst also die 18 Bits in 3 Bytes aufteilen
müssen. Das letzte Byte kann dann noch Zusatzinformationen beinhalten.
Oder jedes einzelne Byte seine Position im Wort mitbringen. Oder ein Bit
den Start markieren...
Lothar Miller schrieb:> Du erkennst das Problem? Du wirst also die 18 Bits in 3 Bytes aufteilen> müssen.
Ja, das habe ich erkannt.
Kann das UART-Design von dir einfach 1:1 auf dem FPGA implementieren
werden, wenn man NUR 8-Datenbit an das Terminal senden will?
Oder muss man zusätzlich (außer passende CLK und Baud) noch etwas
beachten und den Code erweitern?
Es müsste doch ausreichend sein, am Eval-Kit nur die UART/USB-Leitungen
TXD, GND und 5V anzuschließen, um die Daten empfangen zu können?
Gruß
Holger
Hmmm..., denk dran du brauchst auch noch Minus(Masse) ausser TXD RXD zum
FPGA sonst funktioniert es nicht. Da du deine Schnittstelle mit 5 Volt
betreibst pass auf dein FPGA auf , nicht das er sich in Luft auflöst.
5 Volt kann ihn schlecht bekommen am Port.
Gruss
Anfäng schrieb:> Oder muss man zusätzlich (außer passende CLK und Baud) noch etwas> beachten und den Code erweitern?
Nein, das geht so. Nur die Pins müssen noch zugeorndet werden.
> Es müsste doch ausreichend sein, am Eval-Kit nur die UART/USB-Leitungen> TXD, GND und 5V anzuschließen, um die Daten empfangen zu können?> - Eval-Kit: DE0 nano> - FTDI UART - USB - Kabel
Die Pegel passen da zusammen? Ist da irgendwo ein Pegelwandler
dawischen?
Hallo,
wenn ich TX_Data direkt TX_Data <= "10101010"; zweisen möchte, bekomme
ich den Fehler:
Error (10568): VHDL error at DCDC_UART_COM.vhd(57): can't write to
interface object "TX_Data" of mode IN
Wie kann man hier eine korrekte Zuweisung durchführen?
Gruss
Anfäng schrieb:> Wie kann man hier eine korrekte Zuweisung durchführen?
Wenn du innerhalb des RS232 Moduls etwas TX_Data zuweisen willst, dann
musst du TX_Data aus der Port-Liste herausnehmen und als Signal
deklarieren...
Oder andersrum: mein UART ist nicht geeignet als Top-Level-Modul, das
direkt an IO-Pins angeschlossen wird. Es ist eigentlich ein Modul, das
als Komponente in dein Top-Level-Modul integriert und angesteuert
wird. Und dieses Top-Level-Modul bekommt an seinen Ports Anschlüsse des
FPGAs zugewiesen...