mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVR32 Senden über USB via UART


Autor: Kossi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Liebe Leser,
ich übertrage Daten über USB an einen Host-PC. Durch den AVR Treiber 
wird an diesem ja ein virtueller COM-Port für die Übertragung 
eingerichtet. Als µC nutze ich den Atmel 32UC3A1512.

Hierzu benutze ich die Funktion in "uart_usb_lib.h"
uart_usb_putchar( SENDEWERT );
Alleine dieser Aufruf bringt kein Erfolg.
Erst durch folgenden Code ist das Senden an den virtuellen COM-Port 
möglich. Ich lasse es mir per Terminalprogramm hterm am PC anzeigen.
if ( TRUE == uart_usb_tx_ready() )
{
uart_usb_putchar( SENDEWERT );
uart_usb_flush(); // nicht warten bis Sendebuffer voll, sondern sofort senden
}

Meine Frage: Wenn ich nun kontinuierlich jede ms ein Wert an den Host-PC 
schicken möchte, dann könnte ich dies ja in eine ISR (Interrupt Service 
Routine)"verpacken". Der µC fungiert in dieser Kommunikation wohl eher 
als Slave bzw. Device. Der PC wird doch sicherlich die Host Funktion 
übernehmen. Also initiiert der PC ja die Datenübertragung?! Der µC 
pushed nun nicht die Daten zum Host, sondern der Host fragt 
kontinuierlich den Sendebuffer der µC ab, oder!? Wenn diese Abfrage aber 
nur beispielsweise alle 2ms erfolgen würde, dann wäre das Senden über 
die ISR, die jede ms aufgerufen wird, nutzlos?!

Hintergrund ist:
Mir ist nämlich aufgefallen, dass wenn ich in einer ISR jede ms einen 
Wert an den Host-PC sende, kann ich die Anzahl der empfangenen Werte 
übers Terminalprogramm Hterm zählen lassen.
10min = 600s = 600.000ms
Folglich müsste ich in 10min 600.000 Werte empfangen.
Nun habe ich beim Start der Übertragung die Stoppuhr loslaufen lassen. 
Als Hterm mir anzeigte, dass ich den 600.000sten Wert empfangen habe, 
stoppte ich die Zeit auf der Stoppuhr. Es müsste eine Zeit von 10min auf 
der Uhr zu lesen sein. Dies war aber nicht der Fall, sie zeigte nämlich 
10:07 min an. Ich finde, dass 7 Sekunden doch schon eine gewaltige 
Abweichung sind.

Autor: Potter S. (potter68)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Host polled regelmäßig den Slave, um zu sehen, ob neue Daten 
vorliegen. Aber dieses 'regelmäßig' hat eben eine gewisse Abweichung.

Wenn der Host nur alle 2 ms polled und Deine Interrupt-Routine alle ms 
aufgerufen wird, dann gibt die Funktion uart_usb_tx_ready() bei jedem 
zweiten Mal FALSE zurück.

Hast Du keinen Zugriff auf die Daten am PC? Werden die einfach so am 
Terminal ausgegeben und das wars?

Autor: Kossi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie gesagt ohne die if-Abfrage mit der Funktion uart_usb_tx_ready() 
funktioniert das Senden auch gar nicht.
Aber muss ich dann nun "genau diesen Zeitpunkt abpassen", wann 
uart_usb_tx_ready() TRUE ist, damit ich was senden kann?!

Kann sich jemand die 7 Sekunden Abweichung erklären, die ich im 1. Post 
beschrieben hatte?

Zurzeit lasse ich mir die Werte nur per Terminal anzeigen. Später 
erfolgt aber einer Weiterverarbeitung der Daten in MATLAB

Autor: Potter S. (potter68)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
uart_usb_tx_ready() gibt Dir TRUE zurück, sobald der 
Endpunkt-Datenpuffer frei ist. Es verhindert also das Überschreiben noch 
nicht gesendeter Daten.

Was ist eigentlich die Aufgabenstellung? Mir ist nicht ganz klar, was 
Dich an den 7 Sekunden stört. Wie gesagt, der USB ist für eine 
Zeitmessung ungeeignet, wegen der bereits erwähnten Ungenauigkeit.

Wenn du die Daten mit Matlab verarbeitest, dann hat das Ganze sowieso 
nichts mehr mit Echtzeit zu tun. Du könntest also hergehn und jedem 
Datensatz einen Zeitstempel spendieren, womit es dann auch keine Rolle 
mehr spielt, wann die Daten am PC ankomme

Autor: Kossi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es sollen damit EKG-Daten übertragen werden. Ansich hast du 
Recht..Zeitstempel o.ä. und fertig. Ich dachte mir nur, wenn man in 
Matlab den EKG-Monitor ausgibt - also sprichwörtliche Herzkurve, dann 
erscheint es mir blöd, wenn dieser Monitor nach 10min um 7 Sekunden 
hinterherhängt.

Ich habe scherzenshalber mal ein paar Messungen aufgenommen:
Wenn die den Timer-Ladewert dementsprechend auflade, dass die ISR jede 
ms aufgerufen wird, in welcher die Daten gesendet werden, dann gibt es 
die 7 Sekunden "Verzögerung".
Schreibe ich in der gleichen ISR eine Schleife, sodass die Sendefunktion 
nur jedes 100. Mal aufgerufen wird - sprich 100ms, dann ist noch eine 
"Verzögerungszeit" von 3 Sekunden zu verbuchen.
Hingegen, wenn ich den Timer-Ladewert für den Aufruf der ISR 
dementsprechend anpasse, dass sie nur alle 100ms aufgerufen wird und nun 
alle 100ms gesendet wird, dann gibt es KEINE "Verzögerungszeit".

Aber eventuell ist es besser, das Senden in die Hauptprogrammschleife zu 
programmieren, sodass in der aufgerufenen ISR nur die Abtastung mittels 
ADC erfolgt. Dessen Werte sollen ja anschließend weitergesendet werden.

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]
  • [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.