mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik RS232 Daten übertragung


Autor: Achim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi.

Ich will über eine rs232 schittstelle daten übertragen.
Um dem AVR ein kommando zu senden, sende ich einfach ein byte. nun muss
ich aber auch in manchen fällen werte (von mehreren bytes) zum AVR
übertragen.
Jetzt wollte ich fragen, wie ich das am besten mache. Da müsst ich ja
ein kommando voraus senden, das mir eine mehr byte übertragung
initialisiert. oder wär es besser, jedes kommando aus 3 bytes bestehen
zu lassen? Das erste byte wäre dann immer das kommando und die 2
anderen die (optimalen) parameter.

Gibts dazu ein beispiel, wie ich sowas machen kann ?

MfG Achim

Autor: Hubert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In C gibt es für so was Librarys

Autor: Dieter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"In C gibt es für so was Librarys"
Prima sinnfreie Aussage. Hättest auch schreiben können:
"In Assembler gibt es für so was Librarys".

Über die Rechtschreibung und das gute Deutsch schreibe ich jetzt mal
lieber nichts.

Zum Thema:

Wie Du das am besten machst, hängt von der Anwendung ab.
In mittleren bis grossen Applikationen ist es sinnvoll, das Ganze über
eine Zustandsmaschine mit (Ring-)Puffer und Interrupt zu lösen.

Was muss denn der MC alles machen?

Autor: Achim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der µC mus folgendes machen:

- Messwerte von sensor erfassen (jede 3 Sekunden)
- Ein 4x 27 Text-Display ansteuern (mit menü)
- Werte in EEprom speichern und auslesen
- 3 Taster Pollen
- und halt den UART ansteuern

bis jetzt habe ich den µC nur per Interrupt auf 1 Byte-Befehle
reagieren lassen:


SIGNAL (SIG_UART_RECV) {
  unsigned char data = UDR;
  switch (data) {
      case '1': uart_puts("Test\n"); break;
      case 'i': uart_puts("Text\n"); break;
      default: uart_puts("Befehl nicht erkannt");break;
  }
}

Bis jetzt hats so auch immer gereicht, aber jetzt muss der AVR auch
daten (einstellungen) empfangen können.
Das mit dem Ring-Puffer verstehe ich nicht ganz.
Ich hab mal überlegt das so zu lösen:

unsigned int char_index;
unsigned char puffer[3];

SIGNAL (SIG_UART_RECV) {
  unsigned char data = UDR;
        if (char_index > 0)
        {
            puffer[char_index] = data;
            if (char_index >= 3)
            {
               char_index = 0;
               bearbeite_befehl(&puffer);
            }
        }
        else
   switch (data) {
      case '1': uart_puts("Test\n"); break;
      case 'i': uart_puts("Text\n"); break;
      case 's': char_index=1;puffer[0] = data;break;
      default: uart_puts("err");break;
    }
}

(nur ein beispiel aus dem kopf)
aber wenn meine datenübertragung mittden drin abbricht, dann hab ich
ein Problem (mein µC denkt, es kommen noch einstellungsbytes und
übernimmt somit falsche daten)

Gruß

Autor: Dieter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die komplette Datenverarbeitung solltest Du aus dem Interrupt
rausnehmen. Deshalb auch der Ringpuffer: Das ist nichts anderes als ein
(virtuell) ringförmiger Speicherbereich, der kein Ende und keinen Anfang
hat, es gibt halt zwei Zeiger, einer zeigt auf die nächste zu
beschreibende Speicherstelle, der andere auf das letzte, nicht
bearbeitete Datum. Immer, wenn ein Receive-IRQ kommt, wird das Datum in
den Puffer geschrieben und der Zeiger eins hochgesetzt.
Die Auswertung machst Du dann in einem Interrupt niederer Priorität
oder im Hauptprogramm.
Das Problem, dass Deine Routine hängenbleiben kann, löst Du, indem Du
einen TimeOut einbaust, z.B. bei Beginn der Auswertung ein Flag setzen
und dann im Timer-IRQ nach einer gewissen Zeit zurücksetzen.

Autor: Achim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Dieter:
Wie meinst du das, die komplette datenverarbeitung raus nehmen ?
Soll ich in der Interrupt Routine nur noch der datenempfang realisieren
oder wie ?
soll ich dann sobald der puffer voll ist, erst zu einer
datenverarbeitungsroutine wechseln und dort das empfangene (puffer
inhalt) verarbeiten.

Das mit dem zurücksetzen habe ich verstanden.
wo stehen denn die interrupt prioritäten ?

MfG

Autor: Dieter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das mit der Verarbeitung siehst Du richtig.
Den Puffer kannst Du im Prinzip jederzeit verarbeiten, natürlich aber
so, dass er nicht überläuft (abhängig von der UART-Geschwindigkeit).
Am besten in Form einer Zustandsmaschine, d.h. nach jedem verarbeitetem
Zeichen wird der Zustand gewechselt und gegebenfalls die Maschine
zurückgesetzt. Das würde ich dann aber mit einer Start- und
Stopp-sequenz machen, das spart den Timeout.
Bei mir habe ich etwas Ähnliches laufen (Freisprecheinrichtung für das
Telefon im Auto samt SMS, etc.), also auch UART, Display, Tasten.
Da der AVR ja unverständlicherweise keine Hardware-IRQ-Level wie andere
MCs hat, habe ich das in Software implementiert, d.h. UART hat hohe
Priorität und ist nicht unterbrechbar. Dazu zwei Timer-IRQs, von denen
der eine unterbrechbar ist und in diesem IRQ findet bei mir die
Verarbeitung des Empfangspuffers statt. Im anderen Timer-IRQ dann so
etwas wie Echtzeituhr, Tastatur-Entprellen, LEDs, etc.
In der Hauptschleife läuft dann das User-Interface, also die
Menüsteuerung.

Autor: Achim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Dieter.
Klingt ja mega interessant !
könntest du mir evtl. deinen code zuschicken, damit ich mir das alles
mal anschauen kann ? Wär echt nett !
(hab leider grad keine eigene email (wegen providerwechsel) nehm
einfach die: simonfr [at] web.de )

Vielen Dank schonmal im voraus!
Gruß Achim

Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe so was bei mir bereitgestellt:
http://www.blafusel.de/misc/atmega8_io.html#6
Vielleicht hilft ja ein Studium der (einfachen) Sourcen Dir weiter.

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.