PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit dem Auslesen der seriellen Schnittstelle



sky-fox
11.02.06, 14:30
Hallo,
Ich habe hier ein Problem, und ich weiß nicht mehr wo ich nach der Lösung suchen soll,
und zwar kommuniziere ich über die Serielle Schnittstelle mit einem Mikrocontroller, und es ist mir aufgefallen, daß hin und wieder Fehler aufgetreten sind.
Un das Problem einzukreisen habe ich den Controller so programmiert, daß er mit im Abstand von mehreren Sekunden die Zahlen von 255 bis 1 an die Serielle Schnittstelle ausgibt.
Wenn ich mir jetzt die Daten in einem Terminalprogramm anschaue, kommen sie richtig an es gibt also keine Fehler, aber wenn ich sie mit meinem Programm ausgebe erscheinen sie auch richtig , bis auf dei 13 :mad: es erscheint keine 13 sondern eine 10 :confused: etwa so:
...15 14 10 12 11 10... damit hätte ich meinen Fehler gefunden, weiß aber nicht, warum das so ist, und vor allem wo ich was falsch gemacht habe und wie ich es wieder richtigbiege...

hier mein Programm:


#include <stdio.h>
#include <stdlib.h>
#include<sys/time.h>
#include<sys/types.h>
#include<unistd.h>
#include <termios.h>
#include <fcntl.h>
#define DEVICE "/dev/ttyS0"
#define BAUD B9600

int open_port(void){
int fd_ser;
struct termios terminal;
fd_ser = open(DEVICE, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
if (fd_ser == -1)
{
perror("Kann die Serielle nicht oeffnen");
exit(1);
}
fcntl(fd_ser, F_SETFL,FNDELAY);
terminal.c_cflag = BAUD | CS8 | CLOCAL | CREAD;
terminal.c_iflag = IGNPAR | ICRNL;
terminal.c_oflag = 0;
terminal.c_lflag &=~(ICANON);
tcflush(fd_ser,TCIOFLUSH);
tcsetattr(fd_ser,TCSANOW,&terminal);
return fd_ser;
}


int read_port(int *fd_ser,unsigned char* buffer) {
int a;
/*Variablen für select*/
fd_set rfds;
struct timeval tv;
int retval;

FD_ZERO(&rfds);
FD_SET(*fd_ser,&rfds);
tv.tv_sec = 1;
tv.tv_usec = 0;
retval = select(*fd_ser+1,&rfds,NULL,NULL,&tv);
if (retval) {
a=read(*fd_ser,buffer,255);
return a;
} else return 0;


}


int main(void){
int bytes;
int i;
int fd_ser;
unsigned char puffer[300];
fd_ser = open_port();
while(1){
bytes = read_port(&fd_ser,puffer);
if( bytes > 0){
for (i = 0;i< bytes;i++){
printf("%i\t",puffer[i]);
}
printf("\n");
}
}
return 0;
}



Ich bin für jede Hilfe sehr dankbar.

Gruß Sebastian

atomical
11.02.06, 15:17
Mach mal
stty -F /dev/ttyS0 rawbevor du die Schnitstelle benutzt.

Das mit der 10 und der 13 wird an den Terminaleinstellungen des TTYs liegen - unter Linux steht 10 (LF) für das Zeilenende, unter Dos/Win braucht man 13-10 (CRLF) - und in der Standardeinstellung wird das offenbar gleich gefiltert. Andere problematische Zeichen sind EOF und EOT ...

sky-fox
11.02.06, 17:01
Hallo,
danke für die Antwort.
Ich habe gerade nochmal die Serial Programming Guide
for POSIX Operating Systems (http://www.easysw.com/~mike/serial/serial.html#2_5) durchgelesen, und habe die Terminalflags abgeändert,
und schaue da, es klappt:


terminal.c_iflag = IGNPAR | ICRNL;
terminal.c_oflag = 0;
terminal.c_lflag &=~(ICANON);

habe ich durch


terminal.c_oflag &= ~OPOST;
terminal.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);


ersetzt.
Es waren doch etwas zu viele Einstellschrauben für mein kleines Köpfchen :rolleyes: .

Ich denke ich hab den raw Modus in c_lflag nicht sauber eingeschaltet.
Fazit:
Bevor man heult, nochmal alles in RUHE durchlesen.

Danke nochmals für Deine Hilfe.

Gruß Sebastian