2009-10-13 5 views
1

Dans mon programme, je lis depuis le périphérique série (Linux, 8N1) sans aucun problème. Mais dans le cas où je veux écrire un seul octet, je n'ai rien sur l'interface. Je suppose que mes paramètres de sortie série sont erronés. Mais il n'y a pas que beaucoup de façons comment mettre c_oflag ...Périphérique série: Lecture 8N1 fonctionne, mais l'écriture d'un seul octet échoue

Mon code:

#define TTYDEVICE "/dev/ttyS0" 
#define BAUDRATE B9600 

int openSerialDevice(const char* devTTY, struct termios oldTio) { 
//----< Open serial device >---------------------------------- 
int fileDescriptor; 
// fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY); 
fileDescriptor = open(devTTY, O_RDWR | O_NOCTTY); 
//fileDescriptor = open(devTTY, O_RDWR | O_NOCTTY /*| OPOST*/); 
if (fileDescriptor == -1) { 
    perror("Error while opening serial interface occurred!"); 
    return -99; 
} 

// set new parameters to the serial device 
struct termios newtio; 
bzero(&newtio, sizeof(newtio)); 
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD; 

// set to 8N1 
newtio.c_cflag &= ~PARENB; 
newtio.c_cflag &= ~CSTOPB; 
newtio.c_cflag &= ~CSIZE; 
newtio.c_cflag |= CS8; 

newtio.c_iflag = IGNPAR; 

// output mode to 
//newtio.c_oflag = 0; 
newtio.c_oflag |= OPOST; 

/* set input mode (non-canonical, no echo,...) */ 
newtio.c_lflag = 0; 

newtio.c_cc[VTIME] = 10; /* inter-character timer 1 sec */ 
newtio.c_cc[VMIN] = 0; /* blocking read disabled */ 

tcflush(fileDescriptor, TCIFLUSH); 
if (tcsetattr(fileDescriptor, TCSANOW, &newtio)) { 
    perror("could not set the serial settings!"); 
    return -99; 
} 

//----</Open serial device >---------------------------------- 
return fileDescriptor; 
} 

int ACK[1] = { 6 }; 

int main() { 
// old termios to restablish 
struct termios oldTIO; 
// filedescriptor 
int fd; 

fd = openSerialDevice(TTYDEVICE, oldTIO); 

if ((fd == -1) | (fd == -99)) { 
    perror("Could not open TTY-Device. Exit on failure!"); 
    return EXIT_FAILURE; 
} 

write(fd, ACK, 1); // Problem !! 


    return 0: 
} 

Maintenant, si j'utilise

écran/dev/ttyS1 9600 8N1

pour vérifier ce qui sort sur/dev/ttyS0. Je ne peux rien voir. Pareil si je renifle avec Docklight 1.8.

Des suggestions? merci

Répondre

2

Comment vérifiez-vous que rien ne sort?

Vous pouvez essayer de supprimer le RTSCTS et réessayer. Enfait, si vous voulez un minimum d'interférence de la couche TTY, vous devez configurer votre terminal brute, en utilisant ceci:

cfmakeraw(&newtio); 
+0

convenu. RTSCTS signifie établissement de liaison de matériel, qui n'est normalement pas utilisé pour 9600n81. Cela ne fonctionne que si les lignes sont également déclenchées par la partie compteur. La connexion de RTS et de CTS dans le matériel devrait également faire fonctionner le même programme, ou le connecter avec un câble (null-modem) approprié à un autre PC, et n'oubliez pas de configurer aussi le handshake RTS/CTS. – Adriaan

2

Vous donnez write() l'argument de données de ACK, qui est un pointeur vers int. Ce n'est probablement pas ce que vous voulez dire. En fonction du endianness de l'ordinateur sur lequel vous vous trouvez, cela signifie que write() va "voir" un tampon contenant les caractères { 6, 0, 0, 0 } (little-endian) ou { 0, 0, 0, 6 } (big-endian). Cela suppose que sizeof (int) == 4 est vrai, ajustez pour d'autres tailles si nécessaire, le problème persiste.

Vous devriez très probablement créer le tampon unsigned char à la place. En outre, si vous aviez fait l'appel comme ceci:

int wrote = write(fd, ACK, sizeof ACK); 
printf("Wrote %d bytes\n", wrote); 

Vous auriez reçu des commentaires directs. Vous devriez tester quelque chose comme ça, pour voir que l'écriture réussit réellement.

0

Le contrôle de flux de matériel activé (CRTSCTS) a été la raison pour laquelle write() a été bloqué et finalement rien n'est apparu sur la sortie série.

merci!

Code de pression qui fonctionne:

int openSerialDevice(const char* devTTY, struct termios oldTio) { 

    //----< Open serial device >---------------------------------- 
    int fileDescriptor; 
    // fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY); 
    fileDescriptor = open(devTTY, O_RDWR | O_NOCTTY); 
    //fileDescriptor = open(devTTY, O_RDWR | O_NOCTTY /*| OPOST*/); 
    if (fileDescriptor == -1) { 
     perror("Error while opening serial interface occurred!"); 
     return -99; 
    } 

    // set new parameters to the serial device 
    struct termios newtio; 

    fcntl(fileDescriptor, F_SETFL, 0); 
    // set everything to 0 
    bzero(&newtio, sizeof(newtio)); 

    // again set everything to 0 
    bzero(&newtio, sizeof(newtio)); 

    newtio.c_cflag |= BAUDRATE; // Set Baudrate first time 
    newtio.c_cflag |= CLOCAL; // Local line - do not change "owner" of port 
    newtio.c_cflag |= CREAD; // Enable receiver 

    newtio.c_cflag &= ~ECHO; // Disable echoing of input characters 
    newtio.c_cflag &= ~ECHOE; 

    // set to 8N1 
    newtio.c_cflag &= ~PARENB; // no parentybyte 
    newtio.c_cflag &= ~CSTOPB; // 1 stop bit 
    newtio.c_cflag &= ~CSIZE; // Mask the character size bits 
    newtio.c_cflag |= CS8; // 8 data bits 

    // output mode to 
    newtio.c_oflag = 0; 
    //newtio.c_oflag |= OPOST; 


    // Set teh baudrate for sure 
    cfsetispeed(&newtio, BAUDRATE); 
    cfsetospeed(&newtio, BAUDRATE); 

    newtio.c_cc[VTIME] = 10; /* inter-character timer */ 
    newtio.c_cc[VMIN] = 0; /* blocking read until */ 

    tcflush(fileDescriptor, TCIFLUSH); // flush pending data 

    // set the new defined settings 
    if (tcsetattr(fileDescriptor, TCSANOW, &newtio)) { 
     perror("could not set the serial settings!"); 
     return -99; 
    } 

    //----</Open serial device >---------------------------------- 
    return fileDescriptor; 
} 
Questions connexes