Forum: PC-Programmierung UART auslesen funktioniert nicht


von Dominik (Gast)


Lesenswert?

Hallo zusammen,
ich habe ein Zybo Z7 Board und möchte Daten, die ich per UART an den PC 
verschicke auf der Konsole (in einem ersten Schritt) und irgendwann 
später in eine Datei speichern, auslesen.
Leider funktioniert mein Code nicht.
Hat hier jemand Erfahrungen warum nicht?

Dieses open allein funktioniert schon nicht, wenn ich aber fd als FILE 
definiere und dann ein fopen verwende funktioniert es.
1
 #include <stdio.h>
2
 #include <fcntl.h>   /* File Control Definitions           */
3
 #include <termios.h> /* POSIX Terminal Control Definitions */
4
 #include <unistd.h>  /* UNIX Standard Definitions      */ 
5
 #include <errno.h>   /* ERROR Number Definitions           */
6
  
7
 void main(void)
8
 {
9
     int fd;/*File Descriptor*/
10
     fd = open ("/dev/ttyUSB1", 'r'); //fd = open("/dev/ttyUSB1",O_RDWR | O_NOCTTY);  
11
     if(fd == -1)            /* Error Checking */
12
       printf("\n  Error! in Opening ttyUSB1  ");
13
     else
14
       printf("\n  ttyUSB1 Opened Successfully ");
15
16
     struct termios SerialPortSettings;  /* Create the structure                          */
17
     tcgetattr(fd, &SerialPortSettings);  /* Get the current attributes of the Serial port */
18
19
     /* Setting the Baud rate */
20
     cfsetispeed(&SerialPortSettings,B115200); /* Set Read  Speed as 115200                       */
21
     cfsetospeed(&SerialPortSettings,B115200); /* Set Write Speed as 115200                       */
22
23
    /* 8N1 Mode */
24
    SerialPortSettings.c_cflag &= ~PARENB;   /* Disables the Parity Enable bit(PARENB),So No Parity   */
25
    SerialPortSettings.c_cflag &= ~CSTOPB;   /* CSTOPB = 2 Stop bits,here it is cleared so 1 Stop bit */
26
    SerialPortSettings.c_cflag &= ~CSIZE;   /* Clears the mask for setting the data size             */
27
    SerialPortSettings.c_cflag |=  CS8;      /* Set the data bits = 8                                 */
28
    
29
    SerialPortSettings.c_cflag &= ~CRTSCTS;       /* No Hardware flow Control                         */
30
    SerialPortSettings.c_cflag |= CREAD | CLOCAL; /* Enable receiver,Ignore Modem Control lines       */ 
31
    
32
    
33
    SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY);          /* Disable XON/XOFF flow control both i/p and o/p */
34
    SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);  /* Non Cannonical mode                            */
35
36
    SerialPortSettings.c_oflag &= ~OPOST;/*No Output Processing*/
37
    
38
    /* Setting Time outs */
39
    SerialPortSettings.c_cc[VMIN] = 10; /* Read at least 10 characters */
40
    SerialPortSettings.c_cc[VTIME] = 0; /* Wait indefinetly   */
41
42
43
    if((tcsetattr(fd,TCSANOW,&SerialPortSettings)) != 0) /* Set the attributes to the termios structure*/
44
        printf("\n  ERROR ! in Setting attributes");
45
    else
46
                    printf("\n  BaudRate = 115200 \n  StopBits = 1 \n  Parity   = none");
47
      
48
          /*------------------------------- Read data from serial port -----------------------------*/
49
50
    tcflush(fd, TCIFLUSH);   /* Discards old data in the rx buffer            */
51
52
    char read_buffer[32];   /* Buffer to store the data received              */
53
    int  bytes_read = 0;    /* Number of bytes read by the read() system call */
54
     int i = 0;
55
56
    bytes_read = read(fd,&read_buffer,32); /* Read the data                   */
57
      
58
    printf("\n\n  Bytes Rxed -%d", bytes_read); /* Print the number of bytes read */
59
    printf("\n\n  ");
60
61
    for(i=0;i<bytes_read;i++)   /*printing only the received characters*/
62
        printf("%c",read_buffer[i]);
63
  
64
    printf("\n +----------------------------------+\n\n\n");
65
66
    close(fd); /* Close the serial port */
67
68
}

: Verschoben durch User
von Gaensefueschen (Gast)


Lesenswert?

fd = open ("/dev/ttyUSB1", 'r'); //fd = open("/dev/ttyUSB1",O_RDWR | 
O_NOCTTY);

'r'? Mach da mal "r" drauss.

von Dominik (Gast)


Lesenswert?

Hab ich auch schon ausprobiert. Funktioniert hat es nicht.

von Ingo W. (uebrig) Benutzerseite


Lesenswert?

Dominik schrieb:
> fd = open ("/dev/ttyUSB1", 'r'); //fd = open("/dev/ttyUSB1",O_RDWR |
> O_NOCTTY);

Was da nach dem "//" (auskommentiert) steht, sieht für mein Gefühl 
besser aus, als das davor.
Der Filemodus "rw" ist für "fopen", also eine ganz andere Baustelle.

von Dominik (Gast)


Lesenswert?

Hi,
ich hab beides ausprobiert. Funktioniert aber beides nicht

von devzero (Gast)


Lesenswert?

Was heisst den ueberhaupt funktioniert nicht? Das steht nirgendwo.

Kommt open() mit -1 zurueck?
Schau auch mal, ob dmesg irgendwas sagt.

von Ingo W. (uebrig) Benutzerseite


Lesenswert?

Wie ist denn das Verhalten?
Keine Fehlermeldungen, nur Warten und keine Ausgaben?

Dominik schrieb:
> /* Setting Time outs */
>     SerialPortSettings.c_cc[VMIN] = 10; /* Read at least 10 characters
> */
>     SerialPortSettings.c_cc[VTIME] = 0; /* Wait indefinetly   */

bedeutet, das mindestens 10 Zeichen reinkommen müssen, bevor "read" 
zurückkommt.

von DPA (Gast)


Lesenswert?

Dominik schrieb:
> if(fd == -1)            /* Error Checking */
>        printf("\n  Error! in Opening ttyUSB1  ");

Wieso ist das newline am Anfang? Ausserdem ist die Fehlermeldung 
normalerweise noch aufschlussreich. perror oder strerror sind dazu gut 
geeignet.

Empfangen bestehende Tools, wie z.B. minicom denn etwas?

von Jack (Gast)


Lesenswert?

Dominik schrieb:
>
1
>      tcgetattr(fd, &SerialPortSettings);  /* Get the current attributes 
2
> of the Serial port */
3
>

Warum? Du willst doch eine spezielle Konfiguration, nicht irgendwas, was 
zufällig gesetzt ist. Daher:
1
// Set flags to a defined starting point
2
memset(&SerialPortSettings, 0, sizeof(SerialPortSettings));

Übrigens, der Variablenname SerialPortSettings nervt. Das ist eine 
temporäre Variable, die man kurzzeitig braucht, also warum der Roman?

>      /* Setting the Baud rate */
>      cfsetispeed(&SerialPortSettings,B115200); /* Set Read  Speed as
> 115200                       */
>      cfsetospeed(&SerialPortSettings,B115200); /* Set Write Speed as
> 115200                       */
>
>     /* 8N1 Mode */
>     SerialPortSettings.c_cflag &= ~PARENB;   /* Disables the Parity
> Enable bit(PARENB),So No Parity   */
>     SerialPortSettings.c_cflag &= ~CSTOPB;   /* CSTOPB = 2 Stop
> bits,here it is cleared so 1 Stop bit */
>     SerialPortSettings.c_cflag &= ~CSIZE;   /* Clears the mask for
> setting the data size             */
>     SerialPortSettings.c_cflag |=  CS8;      /* Set the data bits = 8
> */
>
>     SerialPortSettings.c_cflag &= ~CRTSCTS;       /* No Hardware flow
> Control                         */
>     SerialPortSettings.c_cflag |= CREAD | CLOCAL; /* Enable
> receiver,Ignore Modem Control lines       */
>
>
>     SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY);          /*
> Disable XON/XOFF flow control both i/p and o/p */
>     SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);  /*
> Non Cannonical mode                            */
>
>     SerialPortSettings.c_oflag &= ~OPOST;/*No Output Processing*/
>
>     /* Setting Time outs */
>     SerialPortSettings.c_cc[VMIN] = 10; /* Read at least 10 characters
> */
>     SerialPortSettings.c_cc[VTIME] = 0; /* Wait indefinetly   */

Alles viel zu kompliziert, da du mit tcgetattr arbeitest. Wenn du die 
Struktur ausgenullt hast, dann:
1
// 8N1
2
SerialPortSettings.c_cflag = CS8 | CREAD | CLOCAL;
3
SerialPortSettings.c_iflag = 0;
4
SerialPortSettings.c_oflag = 0;
5
SerialPortSettings.c_lflag = 0;
6
7
// Wait for a few min chars, and return once a "burst" of chars
8
// dies down.
9
SerialPortSettings.c_cc[VMIN] = 8;
10
SerialPortSettings.c_cc[VTIME] = 1;
11
12
// Configure speed
13
cfsetispeed(&SerialPortSettings,B115200);
14
cfsetospeed(&SerialPortSettings,B115200);


So, jetzt wird es ernst:
1
fd = open("/dev/ttyUSB1", O_RDWR | O_NONBLOCK);
2
if(fd < 0) {
3
    perror("open /dev/ttyUSB1");
4
    return;
5
}
6
if(tcsetattr(fd, TCSANOW, &SerialPortSettings)) {
7
    perror("tcsetattr");
8
    close(fd);
9
    return;
10
}

von Ingo W. (uebrig) Benutzerseite


Lesenswert?

Jack schrieb:
> Übrigens, der Variablenname SerialPortSettings nervt. Das ist eine
> temporäre Variable, die man kurzzeitig braucht, also warum der Roman?

Es ist dein Variablenname aus deinem Programm. Wenn er dir nicht mehr 
gefällt, dann einfach suchen/ersetzen.

von PittyJ (Gast)


Lesenswert?

Man kann nach einenm Fehlermit errno den Grund abfragen.
Und mit strerror den Code noch als String ausgeben.

Wäre doch mal praktisch nachzuschauen, warum es nicht geht.

von Rolf M. (rmagnus)


Lesenswert?

Jack schrieb:
> So, jetzt wird es ernst:fd = open("/dev/ttyUSB1", O_RDWR | O_NONBLOCK);

Warum O_NONBLOCK? Das führt dazu, dass read() sofort zurückkehrt, auch 
wenn es gar nix zu lesen gibt.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.