-2

C のシリアル回線を介してデータを送信しようとしています。設定したオプションに問題があると思われますが、それがわかりません。

次のプログラムでは、バイト 0x79、0x80、0x81 を送信していますが、相手側では 0x86、0x06、0x00 を受信して​​います。

#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */

/*
 * 'open_port()' - Open serial port 1.
 *
 * Returns the file descriptor on success or -1 on error.
 */
char SERIAL_DEVICE[] = {"/dev/ttyUSB0"};
struct termios options;

void open_port(int* fd)
{
    *fd = open(SERIAL_DEVICE, O_RDWR | O_NOCTTY | O_NDELAY);

    if (*fd == -1){
        /* Could not open the port. */
        perror("open_port: Unable to open serial port - ");

    } else 
        fcntl(*fd, F_SETFL, 0);

}

void send(int message[], size_t bytes_to_send, int* fd){
    int n,i;

    for(i=0;i<bytes_to_send;i++){
        printf("%x", message[i]);
    }
    n = write(*fd, message, bytes_to_send);
    if (n < 0)
      fputs("write() failed!\n", stderr);
}

int main(){

    int fd; /* File descriptor for the port */

    int message[] = {0x79, 0x80, 0x81};

    // load the options structure with the cuurent port options
    tcgetattr(fd, &options);        
    cfsetispeed(&options, B19200); // set in baudrate
    cfsetospeed(&options, B19200); // set out baudrate
    options.c_cflag |= (CLOCAL | CREAD);

    // No Parity 8N1
    options.c_cflag &= ~PARENB;
    options.c_cflag &= ~CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;
    options.c_iflag &= ~(IXON | IXOFF | IXANY);
    options.c_iflag |= (IGNPAR | ISTRIP);

    //raw input and output
    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    options.c_oflag &= ~OPOST;

    // Flush buffers and set new options
    tcsetattr(fd, TCSAFLUSH, &options);

    open_port(&fd);

    int array_length = sizeof(message) / sizeof(message[0]);    
    int i;
    for(i=0;i<array_length;i++){
        printf("%x", message[i]);
    }

    send(message, array_length, &fd);

    close(fd);
    return 0;
}
4

1 に答える 1

2

termios のものはすべて無効です。fd実行後にシリアルポートを開いているため、ランダムファイル記述子の端末特性を変更しています(初期化されていません) tcsetattrtcgetattrとのtcsetattr呼び出しでエラーをチェックしていれば、これをキャッチできたはずです。また、コンパイラが発行する警告に注意を払っていれば、それをキャッチできたでしょう。

send次に、関数には 2 つの問題があります。

  • sendシステムコールと同じ名前です。これは技術的には問題ありません。なぜなら、 libc からのsendオーバーライドsendですべてが機能するからです。ただし、混乱し (最初にコードを読んだとき、sendシステム コールを使用していると思いました)、危険です (プログラムの他の場所でシステム コールを使用している場合send)。
  • ints の配列を に渡しますがwritewriteバイトの配列が必要です。その結果、0x79 を書き込もうとすると、4 バイトの 0x00 0x00 0x00 0x79 (ビッグ エンディアン 32 ビット プラットフォームの場合) または 0x79 0x00 0x00 0x00 (リトル エンディアン 32 ビット プラットフォームの場合) を書き込むことになります。
于 2012-12-18T19:04:16.230 に答える