- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 8 von 8

Thema: UART-Empfang von PC: Wieviel Zeit bleibt zum Verarbeiten?

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    19.10.2006
    Ort
    Berlin
    Beiträge
    9

    UART-Empfang von PC: Wieviel Zeit bleibt zum Verarbeiten?

    Anzeige

    Praxistest und DIY Projekte
    Hallo Leute,

    ich empfange über den UART meines ATmega8 Daten vom PC mit 4800 Baud (asynchron via Interrupt). Der MC läuft mit 3,686MHz (externer Quartz).
    Wenn ich viele Bytes gleichzeitig schicke gehen leider welche verloren, der ATmega empfängt nur den Anfang des Streams. Wenn ich in der Client-Anwendung nach jedem Byte ein Delay von 5ms einfüge funktioniert alles wunderbar.
    Mein Verdacht ist nun, dass ich im Interrupt-Handler zu viele Zyklen verbrate. Frage: wie viele Zyklen stehen mir pro empfangenem Byte zur Verfügung? Bitte sagt mir, ob diese Rechnung richtig ist:
    4800 Baud: 4800 interrupts pro Sekunde, 3686000 Zyklen/s
    = ca. 768 Zyklen pro empfangenes Byte.
    Das sollte locker reichen. Ich brauche maximal 200!

    Fällt euch was dazu ein? Ich freue mich über jeden Hinweis!!!

    Danke schonmal und viele Grüße,
    Dennis

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    4800 Baud: 4800 interrupts pro Sekunde
    Bist Du Dir da sicher ?
    Ich meine ein UART_RX Interrupt wird ausgelöst, wenn ein Byte empfangen wurde.

    da Du 4800 Baud hast werden 4800 Bits in der Sekunde übertragen.
    Wenn Du jetzt ein Start und ein Stop Bit noch mitschickst müssen insgesammt 10 Bits übertragen werden, also 4800/10 ergibt 480 Interrupts in der Sekunde

    Tja mal schauen ob meine Rechnung stimmt

    Gruß Sebastian
    Software is like s e x: its better when its free.
    Linus Torvald

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    19.10.2006
    Ort
    Berlin
    Beiträge
    9
    Genau das war meine Frage: wie viele Interrupts habe ich pro Sekunde, unter den gegebenen Umständen? Ich würd es ja auch ausprobieren, kann aber kein on-device-debugging machen. Weiß es jemand sicher?

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    19.03.2006
    Beiträge
    44
    Die Rechnung von izaseba stimmt. In welcher Sprache programmierst du denn, bei meinem letzten Projekt hab ich mit 6MHz 38400 Baut empfangen ohne Probleme, allerdings in Assembler. Ich weis ja nicht was du machen willst, (lad dein Programm eventuell hoch), Wenn du nicht dauernd empfangen willst
    nehm dir ein Anfangs und ein End zeichen z.B "[" "]" und kontrolliere das empfangene Byte auf diesen Askiiwert wenn es das Anfangszeichen ist setze einen Zeiger auf ein Array und schreibe die empangenen Werte nacheinander hinein. erst wenn dein Endzeichen kommt führst du die Große Operation aus.
    villeicht hilfts ja.

    Uwe

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    19.10.2006
    Ort
    Berlin
    Beiträge
    9
    Danke für eure Hilfe!
    Das MC-Programm ist in Assembler geschrieben, deshalb kann ich sicher sagen, dass es zwischen 100 und 200 Zyklen braucht pro empfangenes Byte. Die Frage ist jetzt, warum ich clientseitig trotzdem ein Delay zwischen den Bytes brauche.
    @Uwe: das mit dem puffern werde ich mal ausprobieren!

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    19.03.2006
    Beiträge
    44
    Um die Kleine Assemblerfront zu stärken. Hi Hi
    Wenn du dirs etwas leichter machen willst, es ist sogar relatv gut dokumentiert. du musst die Variable Zeiger noch definieren Irgeneine Ram adresse die 0 als high byte hat (bei mir ist es ox70 gewesen). ind der steht dann der Wert an welcher Stelle des Strings er gerade ist, die länge ist glaub ich auf 15 begrenzt, dass nicht fer ganze Ram volgemüllt wird, wenn kein neues Startzeichen kommt. Musst du halt deinen Bedingungen anpassen ebenso wie das was er machen soll wenn er ein Abschlusszeichen empfängt.
    ich schreibs als Text da ich das mit dem Programmkästchen nicht kann.

    ;Interuproutine für Serielle Schnittstelle
    ;-----------------------------------------------------------------
    ; Interruptroutine: wird ausgeführt sobald ein Byte über das UART empfangen wurde
    ;----------------------- ------------------------------


    int_rxc:
    push Temp ; temp auf dem Stack sichern
    push temp1
    push temp2



    clr ZH
    ldi ZL, Zeiger ;zum Laden Des Zeigers
    ld temp2,Z
    ;-----------------------------------------------------------------
    ;Anfangszeichen Empfangen Pointer wird auf erste Stelle gesetzt
    ;-----------------------------------------------------------------
    in Temp, UDR
    cpi Temp, '['
    brne Zahl
    ldi temp2, 0x01 ;Wenn ein Klammer auf erkannt wird, wird der Zeiger auf 1 gesetz
    ;um die Klammer in 0x71 zu schreiben

    Zahl:
    cpi Temp, ']' ;die Position(im Programm) Zahl und Zahl1 bedeuten dass
    brne Zahl1 ; kein Steuerzeichen empfangen wurde
    ;-----------------------------------------------------------------
    ;Abschlusszeichen Empfangen Wert wird errechnet
    ;-----------------------------------------------------------------

    clr ZH
    ldi ZL,String1 ;Anfangswert des Zu Berechnenden Registers
    rcall Dezimalstring5 ;die Umrechnung wird 2x mit den jeweiligen Adressen aufgerufen

    sbrs Temp,0 ;Da Dezimalstring wenn die Umrechnung gültig ist eine 1
    rjmp ERROR_Konvert ;in Temp zurückgibt wird diese Überprüft
    ldi ZL,Wert1H ;wenn die eins nicht kommt wirde Error ausggeben
    st Z+,Erg1
    st Z,Erg0

    ldi ZL,String2 ;Anfangswert des Zu Berechnenden Registers
    rcall Dezimalstring5

    sbrs Temp, 0 ;Da Dezimalstring wenn die Umrechnung gültig ist eine 1
    rjmp ERROR_Konvert ;in Temp zurückgibt wird diese Überprüft
    ldi ZL,Wert2H ;wenn die eins nicht kommt wirde Error ausggeben
    st Z+,Erg1
    st Z,Erg0




    ; rcall Senden ;kann Zur Kontrolle aktiviert werden
    rcall Dig_out ;gibt den Empfangenen String mit errechneten werten zurück

    rjmp int_rxc_end ;wenn die Rechnung erfolgt ist, wird die Berechnung beendet

    ;-----------------------------------------------------------------
    ; Zahl Empfangen
    ;-----------------------------------------------------------------

    Zahl1: add ZL,temp2 ;Wenn kein Steuerzeichen erkannt Wurde, wird der Zeiger
    st Z,Temp ;zum Zpointer addiert und der empfangene
    ;Wert dort abgelegt
    inc temp2 ;dann Wird der Zeiger incrementier und wieder gesichert
    cpi temp2,0x0F ;Es wird Überprüft ob der Zeiger größer als 15 ist,
    brlo Zeiger_OK ;falls dies der Fall ist wird er wieder decrementiert
    dec temp2 ;um zu verhindern dass er den ganzen RAM beschreibt, ab dann
    ;wird nur noch die Speicherzelle String1+Zeiger Beschrieben
    Zeiger_OK: ;bis wieder ein "[" ankommt
    ldi ZL,Zeiger ;
    st Z,temp2


    int_rxc_end:
    pop temp2
    pop temp1
    pop temp


    reti

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    19.10.2006
    Ort
    Berlin
    Beiträge
    9
    Cool, danke! Ich werd das testen, um erstmal zu sehen, ob der Fehler überhaupt in meinem Assemblerprogramm steckt oder evtl. doch im PC-Programm.
    Grüße
    Dennis

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    19.10.2006
    Ort
    Berlin
    Beiträge
    9
    So, Fehler gefunden!
    Beim Abzählen der benötigten Prozessorzyklen habe ich mich verrechnet.
    Nach jedem empfangenen Byte habe ich erstmal eine Log-Message mit 5-10 Zeichen/Bytes auf die serielle ausgegeben - synchron!! Dass das Ausgeben auch abhängig von der Baudrate ist habe ich fröhlich unter den Teppich gekehrt. Deshalb ist alles durcheinandergekommen.
    Jetzt bin ich schlauer und gebe nur noch max. ein Byte aus

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen