2011-12-22 22 views
11

Próbuję odczytać surowe bajty z portu szeregowego wysłanego przez symulator protokołu WIN32 IEC 870-5-101 z programem napisanym w języku C działającym pod kontrolą systemu Linux 32bit.Czytanie surowych bajtów z portu szeregowego

Działa poprawnie dla wartości bajtów, takich jak 0x00 - 0x7F. Ale dla wartości począwszy od 0x80 do 0xAF wysokiej bit jest nie tak, np .:

0x7F -> 0x7F //correct 
0x18 -> 0x18 //correct 
0x79 -> 0x79 //correct 
0x80 -> 0x00 //wrong 
0xAF -> 0x2F //wrong 
0xFF -> 0x7F //wrong 

Po wykopaniu około dwóch dni, nie mam pojęcia, co jest przyczyną tego.

To jest mój config portu szeregowego:

cfsetispeed(&config, B9600); 
    cfsetospeed(&config, B9600); 

    config.c_cflag |= (CLOCAL | CREAD); 

    config.c_cflag &= ~CSIZE;        /* Mask the character size bits */ 
    config.c_cflag |= (PARENB | CS8);      /* Parity bit Select 8 data bits */ 

    config.c_cflag &= ~(PARODD | CSTOPB);     /* even parity, 1 stop bit */ 


    config.c_cflag |= CRTSCTS;        /*enable RTS/CTS flow control - linux only supports rts/cts*/ 


    config.c_iflag &= ~(IXON | IXOFF | IXANY);    /*disable software flow control*/ 

    config.c_oflag &= ~OPOST;        /* enable raw output */ 
    config.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);  /* enable raw input */ 

    config.c_iflag &= ~(INPCK | PARMRK);     /* DANGEROUS no parity check*/ 
    config.c_iflag |= ISTRIP;        /* strip parity bits */ 
    config.c_iflag |= IGNPAR;        /* DANGEROUS ignore parity errors*/ 

    config.c_cc[VTIME] = 1;         /*timeout to read a character in tenth of a second*/ 

Czytam z portu szeregowego z:

*bytesread = read((int) fd, in_buf, BytesToRead); 

Zaraz po tej operacji „in_buf” zawiera niewłaściwy bajt, więc Chyba coś jest nie tak z moją konfiguracją, która jest portem ze struktury DC32 dla win32.

Dzięki za wszelkie pomysły!

+0

Zauważam, że powiedziałeś: "Drugi 4 bit jest błędny ...", ale twoje dane wydają się pokazywać tylko, że wysoki bit jest czyszczony. (& 0x7f) – BRFennPocock

+0

Jestem nieco zdezorientowany konwencjami nazewnictwa. Oczywiście wysoki bit jest błędny. W celu wyjaśnienia. – punischdude

Odpowiedz

14

W oparciu o twoje przykłady, tylko ósmy bit (wysoki bit) jest błędny, a to źle, ponieważ zawsze jest 0. Ustawiasz ISTRIP w swojej liniowej dyscyplinie po stronie Linuksa, a to by spowodowało to. ISTRIP nie, jak twierdzi komentarz w kodzie C, usuwa bity parzystości. Usuwa 8 bit danych.

Jeśli ISTRIP jest ustawiony, ważne bajty wejściowe muszą być najpierw usunięte do siedmiu bitów; w przeciwnym razie przetwarzane będą wszystkie osiem bitów. IEEE Std 1003.1, 2004 Edition, chapter 11, General Terminal Interface

+0

Dzięki za informacje na 8E1. Nigdy o tym nie wiedziałem. –

+0

Dzięki! 'config.c_iflag & = ~ ISTRIP;' zrobił lewę. – punischdude

+0

Muszę uwielbiać te mylące komentarze. –

Powiązane problemy