Hinweis: Das Forum wird geschlossen! Neue Registrierungen sind nicht mehr möglich!

 Zurück zu Pro-Linux   Foren-Übersicht   FAQ     Suchen    Mitgliederliste
Serielle Schnittstelle - Burst einlesen

 
Neuen Beitrag schreiben   Auf Beitrag antworten    Pro-Linux Foren-Übersicht -> Programmieren - C
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
TS-Tec
Gast





BeitragVerfasst am: 21. Nov 2007 13:12   Titel: Serielle Schnittstelle - Burst einlesen

Hallo!

Ich ein Microcontroller der mir auf einen Befehl über die serielle Schnittstelle sofort eine Antwort zurück sendet.
Dies möchte ich in ein C-Programm einbinden. Das senden der Zeichen klappt auch gut, nur die Antwort wird nicht korrekt dargestellt. Wenn ich das ganze über ein Terminal-Programm simuiliere, also die Antwort Zeichen für Zeichen eingebe und mir \r abschließe, klappt alles wunderbar.
Die Sache ist aber scheinbar die, das der Controller einen Burst schickt. Obwohl am Ende auch ein \r [ASCII 13] kommt erkennt mein Programm das nicht. Auch die Ausgabe ist sehr seltsam. Es scheint eine Überlagerung der aktuellen mit vorherigen Antworten zu sein. Manchmal kommt die Antwort nur bruchstückhaft, manchmal mehrfach.
Wie muss ich den Port konfigurieren, um einen Burst korrekt einlesen zu können?

Hier mein Code:

Code:
   /* Öffnet den übergebenen Port und liefert den zugehörigen File-Descriptor zurück. -1 = Fehler*/
    int open_port(char Port[])
    {       
       int fd;
       fd = open(Port, O_RDWR);
       fcntl(fd, F_SETFL, 0);
       
       /*TODO Unterschied TCU/NFC-Portsettintgs proggen*/
       tcgetattr(fd,&oldtio); /* save current port settings */
       
       return (fd);
    }
   
   
    /* Stellt die Portparameter für einen übergenen File-Descriptor ein. -1 = Fehler */
    int setPortParam(int fd)
    {
       
       struct termios term_attr;
       
       if (tcgetattr(fd, &term_attr) != 0)
       {
           perror("terminal: tcgetattr() failed");
           return(-1);
       }
       
       
       
       
       bzero(&term_attr, sizeof(term_attr));
       term_attr.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
       term_attr.c_iflag = IGNPAR | ICRNL;
       term_attr.c_oflag = 0;//OPOST; //| ONLCR | OCRNL;
       term_attr.c_lflag = 0;
       term_attr.c_cc[VTIME]    = 0;   /* inter-character timer unused */
       //printf("setting flags");
       term_attr.c_cc[VMIN]     = 0;   /* blocking read until 8 chars received */
       
        tcflush(fd, TCIFLUSH);
          if (tcsetattr(fd, TCSANOW, &term_attr) != 0)
       {
          perror("terminal: tcsetattr() failed");
          return -1;
       }
       
       return 1;
    }
   
    void closePort(int fd){
       printf("Closing Port");
       tcsetattr(fd,TCSANOW,&oldtio);
       close(fd);
       
    }
   
    /*TODO Funktion WriteToPort programmieren!*/
    void WriteToPort(int fd){
   
    char buffer[255] = "";   
   
    int n = write(fd, "0av\r", 3);
    if (n < 0)
    fputs("write() of 4 bytes failed!\n", stderr);
    while (STOP==FALSE) {       /* loop for input */
             read(fd,buffer,64);   /* returns after 5 chars have been input */
             printf("%s", buffer);
             if (buffer[0]==10) STOP=TRUE;
           }

    closePort(fd);
    }
 

Janka



Anmeldungsdatum: 11.02.2006
Beiträge: 3569

BeitragVerfasst am: 22. Nov 2007 22:26   Titel:

Vermutlich sendet dein Controller immer, auch wenn der PC gar nichts verarbeiten kann -- der hat nämlich nur 16 Byte Puffer, und dann muss die Interruptroutine des Porttreibers eingegangene Zeichen erstmal wegarbeiten.

Du brauchst Flusskontrolle. Entweder dein Controller kann XON/XOFF, dann musst du mit tcsetattr() zusätzlich das Flag IXOFF setzen, oder dein Controller kann RTS/CTS, dann musst du eine mindestens 4-adrige Leitung verwenden (RTS am PC mit CTS am Controller verbinden) und der serielle Port wird dem Controller automatisch "Stop" signalisieren, sobald der Puffer kurz vor voll ist.

Janka
_________________
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.
 
Benutzer-Profile anzeigen Private Nachricht senden

TS-Tec
Gast





BeitragVerfasst am: 04. Dez 2007 14:16   Titel:

Mhh ich habe beides ausprobiert... ohne Erfolg!
Es hat sicher irgendetwas mit dem Puffer zu tun.
Wenn eine sehr lange Antwort kommt (ca. 1000 Zeichen) dann kommt beim Aufruf von read() nur ein Teil an. Der Rest kommt beim nächten Afruf von read() und vermischt sich mit der neuen Antwort (da ja inzwischen ein weiterer Befehl mit write()N gesendet wurde).
Was kann ich gegen dieses Phänomen tun? Den Eingangspuffer vergrößern???
 

Janka



Anmeldungsdatum: 11.02.2006
Beiträge: 3569

BeitragVerfasst am: 05. Dez 2007 15:41   Titel:

Der 16-Byte-Eingangspuffer ist Hardware. Wenn der Controller nicht auf Handshake-Signale reagiert, ist dessen Firmware *Mist* und gehört korrigiert.

Janka
_________________
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.
 
Benutzer-Profile anzeigen Private Nachricht senden

Beiträge vom vorherigen Thema anzeigen:   
     Pro-Linux Foren-Übersicht -> Programmieren - C Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehen Sie zu:  

Powered by phpBB © phpBB Group
pro_linux Theme © 2004 by Mandaxy