Pro-Linux

Pro-Linux Diskussions- und Hilfeforum
Aktuelle Zeit: 14. Nov 2018 17:21

Alle Zeiten sind UTC+01:00




Ein neues Thema erstellen  Auf das Thema antworten  [ 4 Beiträge ] 
Autor Nachricht
BeitragVerfasst: 21. Nov 2007 13:12 
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 &#40;n < 0&#41;
    fputs&#40;"write&#40;&#41; of 4 bytes failed!\n", stderr&#41;;
    while &#40;STOP==FALSE&#41; &#123;       /* loop for input */
             read&#40;fd,buffer,64&#41;;   /* returns after 5 chars have been input */
             printf&#40;"%s", buffer&#41;;
             if &#40;buffer&#91;0&#93;==10&#41; STOP=TRUE;
    		 &#125;

    closePort&#40;fd&#41;;
    &#125;


Nach oben
   
 Betreff des Beitrags:
BeitragVerfasst: 22. Nov 2007 22:26 
Offline
Benutzeravatar

Registriert: 11. Feb 2006 19:10
Beiträge: 3569
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.


Nach oben
   
 Betreff des Beitrags:
BeitragVerfasst: 04. Dez 2007 14:16 
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???


Nach oben
   
 Betreff des Beitrags:
BeitragVerfasst: 05. Dez 2007 15:41 
Offline
Benutzeravatar

Registriert: 11. Feb 2006 19:10
Beiträge: 3569
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.


Nach oben
   
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen  Auf das Thema antworten  [ 4 Beiträge ] 

Alle Zeiten sind UTC+01:00


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 0 Gäste


Sie dürfen keine neuen Themen in diesem Forum erstellen.
Sie dürfen keine Antworten zu Themen in diesem Forum erstellen.
Sie dürfen Ihre Beiträge in diesem Forum nicht ändern.
Sie dürfen Ihre Beiträge in diesem Forum nicht löschen.
Sie dürfen keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
Powered by phpBB® Forum Software © phpBB Limited
Deutsche Übersetzung durch phpBB.de