2012-10-16 12 views
5

Ho un semplice programma che imposta la velocità di trasmissione per una porta seriale (RS232). Sto impostando le velocità di input e output in modo indipendente usando le funzioni cfsetospeed() e cfsetispeed(). Come per la man page, questo dovrebbe essere possibile purché uso queste funzioni e una costante appropriata:Perché i baud rate di input e output sono sempre gli stessi?

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

mio problema è che, indipendentemente ho impostato secondo (ingresso o uscita) sembra essere il valore finale per entrambi. Sto provando a impostare due velocità indipendenti.

CODICE:

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; 
} 

La mia funzione getBRate() è solo un semplice (brutto) interruttore per restituire una versione di stringa del baud rate:

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; 
} 

L'output qui sarà:

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

Se inverto i due "s et" linee in questo modo:

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

La mia uscita cambierà:

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

Tutte le idee?

EDIT:
Poiché la questione si avvicinò, questo codice verrà eseguito su una tavola con un Coldfire 528X (sia 5280 o 5282). Indipendentemente da ciò, la RX e TX dovrebbero essere in grado di avere tassi differenti secondo il manuale di riferimento per l'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 tutti i chip con cui ho avuto a che fare, l'hardware della porta seriale ha in realtà solo un singolo generatore di baud rate e quindi non ha modo di gestire velocità di trasmissione Tx e Rx diverse. – TJD

+0

@TJD - Stranamente se questo è il caso in cui non vi è alcun errore nel tentativo di impostare due diverse velocità per Tx/Rx. _a_ la velocità ha richiesto, ma il comando (impostando due diverse velocità) tecnicamente non ha funzionato. – Mike

+0

ma non c'è esattamente un punto in cui si verifica un errore. Ogni volta che chiami per impostare la velocità, lo fa con successo (ma lo applica a entrambi). Quindi ti rimane il tasso che hai impostato per ultimo. – TJD

risposta

0

Per ora mi accetto @ risposta di TJD come dato di fatto 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.

Per quanto riguarda il fatto che non vedo errori, è perché almeno una delle operazioni richieste di tcsetattr() ha avuto successo come this page stati:

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.

Quindi, per ora, suppongo che l'hardware non sia in grado di supportarlo, ma sto ottenendo un ritorno positivo dalla funzione set perché ha impostato una delle due cose che ho richiesto.

+0

@ Risposta TJD è sicuramente corretta. Non ho mai visto implementazioni hardware UART con velocità di trasmissione tx/rx diverse. Se avete bisogno di questa funzionalità per qualche motivo oscuro, suggerisco due adattatori seriali USB <> e un cavo speciale che prende la linea tx da un adattatore e la linea rx dall'altra. Tx a una porta e rx dall'altra. –

Problemi correlati