2012-10-16 20 views
5

Ich habe ein einfaches Programm, das die Baudrate für einen seriellen (RS232) Anschluss einstellt. Ich setze die Eingangs- und Ausgangsraten unabhängig voneinander mit den Funktionen cfsetospeed() und cfsetispeed(). Gemäß den man page, soll dies möglich sein, sofern ich diese Funktionen zu nutzen und eine entsprechende Konstante:Warum sind die Eingangs- und Ausgangs-Baudraten immer gleich?

cfsetispeed() sets the input baud rate stored in the termios structure to speed, which must be specified as one of the Bnnn constants listed above for cfsetospeed(). If the input baud rate is set to zero, the input baud rate will be equal to the output baud rate.

cfsetospeed() sets the output baud rate stored in the termios structure pointed to by termios_p to speed, which must be one of these constants: ... B600 ... B19200

hier Mein Problem ist, dass alles, was ich Sekunde eingestellt (Eingang oder Ausgang) scheint zu sein, der Endwert für beide. Ich versuche zwei unabhängige Geschwindigkeiten einzustellen.

Code:

int main() { 
    int fd, ret; 
    char buf[100] = {0}; 
    char buf2[100] = {0}; 
    struct termios options; 

    // Open the serial-USB device driver 
    fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY); 
    if(fd < 0){ 
     perror("open_port: Unable to open port - "); 
     return 1; 
    } 

    tcgetattr(fd, &options); //Get the current settings 

    cfsetospeed(&options, B9600); //Set input speed as 9600 Baud Rate 
    cfsetispeed(&options, B19200); //Set output speed as 19200 Baud Rate 

    ret= tcsetattr(fd, TCSANOW, &options); //Get the return to make sure it worked 

    sleep(3); // Just for kicks, let it "settle" 

    tcgetattr(fd, &options); //Read back the values 

    getBRate(buf, cfgetispeed(&options)); 
    getBRate(buf2, cfgetospeed(&options)); 

    printf("return code was: %d, ispeed %s, ospeed %s\n", ret, buf, buf2); 

    //Clean up 
    memset(buf, '0', 100); 
    memset(buf2, '0', 100); 
    close(fd); 

    return 0; 
} 

Meine getBRate() Funktion ist nur ein einfaches (hässlich) Schalter einen String-Version der Baudrate zurück:

void getBRate(char rate[], speed_t brate) 
{ 

    switch(brate) { 
     case B0: strcpy(rate,"none"); break; 
     case B50: strcpy(rate,"50 Baud");break; 
     case B110: strcpy(rate,"110 Baud");break; 
     case B134: strcpy(rate,"134 Baud");break; 
     case B150: strcpy(rate,"150 Baud");break; 
     case B200: strcpy(rate,"200 Baud");break; 
     case B300: strcpy(rate,"300 Baud");break; 
     case B600: strcpy(rate,"600 Baud");break; 
     case B1200: strcpy(rate,"1200 Baud");break; 
     case B1800: strcpy(rate,"1800 Baud");break; 
     case B2400: strcpy(rate,"2400 Baud");break; 
     case B4800: strcpy(rate,"4800 Baud");break; 
     case B9600: strcpy(rate,"9600 Baud");break; 
     case B19200: strcpy(rate,"19200 Baud");break; 
     default: strcpy(rate, "No valid baud found\n");break; 
    } 
    return; 
} 

Die Ausgabe hier wird sein:

return code was: 0, ispeed 19200 Baud, ospeed 19200 Baud 

Wenn ich die zwei "s et“Zeilen wie so:

cfsetispeed(&options, B19200); //Set output speed as 19200 Baud Rate 
cfsetospeed(&options, B9600); //Set input speed as 9600 Baud Rate 

Meine Ausgabe wird sich ändern:

return code was: 0, ispeed 9600 Baud, ospeed 9600 Baud 

Irgendwelche Ideen?

EDIT:
Da die Frage aufkam, wird dieser Code auf einem Brett ausgeführt wird unter Verwendung eines Coldfire 528X (entweder 5280 oder 5282). Unabhängig davon, sollte der RX und TX können unterschiedliche Preise haben, wie pro Referenzhandbuch für den UART:

23.3.4 UART Clock Select Registers (UCSRn)
The UCSRs select an external clock on the DTIN input (divided by 1 or 16) or a prescaled internal bus clock as the clocking source for the transmitter and receiver. See Section 23.4.1, “Transmitter/Receiver Clock Source.” The transmitter and receiver can use different clock sources.

+6

In all den Chips, die ich behandelt habe, hat die Hardware des seriellen Ports eigentlich nur einen einzigen Baudratengenerator und hat daher keine Möglichkeit, verschiedene Tx- und Rx-Baudraten zu verarbeiten. – TJD

+0

@TJD - Seltsam, wenn dies der Fall ist, dass beim Versuch, zwei verschiedene Raten für Tx/Rx einzustellen, kein Fehler auftritt. _a_ Rate nahm, aber der Befehl (Einstellung von zwei verschiedenen Raten) technisch fehlgeschlagen. – Mike

+0

aber es gibt nicht genau einen Punkt, an dem ein Fehler auftritt. Jedes Mal, wenn Sie anrufen, um die Rate zu setzen, wird dies erfolgreich durchgeführt (gilt aber nur für beide). Sie bleiben also mit der Rate, die Sie zuletzt festgelegt haben. – TJD

Antwort

0

Vorerst I @ Antwort des TJD akzeptieren werde als Tatsache In all the chips I have dealt with, the serial port hardware actually only has a single baud rate generator, and therefore has no possible way to handle different Tx and Rx baud rates.

in Bezug auf die Tatsache, dass ich keine Fehler zu sehen bin, ist es, weil mindestens einer der angeforderten Operationen von tcsetattr() hat als this page Staaten gelingen:

The tcsetattr() function returns successfully if it was able to perform any of the requested actions, even if some of the requested actions could not be performed.

Also jetzt, ich denke, die Hardware hat nicht die Fähigkeit, dies zu unterstützen, aber ich bekomme eine erfolgreiche Rückkehr von der Set-Funktion, weil es eines der beiden Dinge, die ich angefordert habe.

+0

@ TJD Antwort ist sicherlich richtig. Ich habe auch nie irgendwelche UART-Hardware-Implementierungen gesehen, die unterschiedliche TX/RX-Baudraten haben. Wenn Sie diese Funktion aus irgendeinem obskuren Grund benötigen, empfehle ich zwei USB <> serielle Adapter und ein spezielles Kabel, das die TX-Leitung von einem Adapter und die RX-Leitung von der anderen nimmt. Tx zu einem Port und rx von dem anderen. –