4

シリアル ポートにバイトを送信するプログラムで、送信したバイトを受信します。送信したバイトを受信したくありませんが、これを行う方法がわかりません。

#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <sys/select.h>
#include <sys/ioctl.h>

int fd;
struct termios tio, old_tio;

time_t SubTime_mSec(timeval val1, timeval val2)
{
    timeval tv;
    if (val1.tv_sec > val2.tv_sec) return (0);
    if (val1.tv_sec == val2.tv_sec)
        if (val1.tv_usec > val2.tv_usec) return (0);
    tv.tv_sec = val2.tv_sec - val1.tv_sec;
    if (val1.tv_usec < val2.tv_usec) {
        tv.tv_usec = val2.tv_usec - val1.tv_usec;
    } else {
        tv.tv_sec --;
        tv.tv_usec = 1000000 + val2.tv_usec - val1.tv_usec;
    }

    return(tv.tv_sec*1000 + tv.tv_usec/1000);
}


void RTUOutMessage(int cnt1, int cnt2)
{
    unsigned char msg[13] = {0x01, 0x10, 0x00, 0x2F, 0x00, 0x02, 0x04, 0x4B, 0x64, 0x3D, 0xD9, 0x36, 0xC6};
    int Len = 13;
    int status, i, j;
    ioctl(fd, TIOCMGET, &status);

    status = status | TIOCM_RTS | TIOCM_DTR;
    ioctl(fd, TIOCMSET, &status);
    write(fd, msg, Len);
    for (j = 0; j < cnt1; j ++)
        for (i = 0; i < cnt2; i ++);
    ioctl(fd, TIOCMGET, &status);
    status &= ~TIOCM_RTS;
    status &= ~TIOCM_DTR;
    ioctl(fd, TIOCMSET, &status);

    timeval start_t, curr_t;
    char Buff[80];
    int l;

    gettimeofday(&start_t, NULL);
    curr_t = start_t;
    while (SubTime_mSec(start_t, curr_t) < 1000) {
        l = read(fd, Buff, 80);
        if (l > 0) {
            printf("BUFFER=");
             for(i = 0; i < l; i++) {
                 printf(" %x", Buff[i]);
             }
             //printf("\n");
        }
        gettimeofday(&curr_t, NULL);
    }
}

void  InitPort(void)
{
    int StopBits = 2;
    if ((fd = open("/dev/ttyAM2", O_RDWR | O_NDELAY)) < 0) {
        printf("Couldn't open //dev//ttyAM2\n");
    }
    tcflush(fd, TCIOFLUSH);
    int n = fcntl(fd, F_GETFL, 0);
    fcntl(fd, F_SETFL, n & ~O_NDELAY);
    tcgetattr(fd, &old_tio);
    tcgetattr(fd, &tio);
    cfsetospeed(&tio, (speed_t)B9600);
    cfsetispeed(&tio, (speed_t)B9600);
    tio.c_cflag = (tio.c_cflag & ~CSIZE) | CS8;
    tio.c_cflag |= CLOCAL | CREAD ;
    tio.c_cflag &= ~OFILL; 
    //parity
    tio.c_cflag &= ~(PARENB | PARODD);
    tio.c_cflag &= ~CRTSCTS;
    if (StopBits == 2) tio.c_cflag |= CSTOPB;
    else tio.c_cflag &= ~CSTOPB;
    tio.c_iflag=IGNBRK;
    tio.c_iflag &= ~(IXON|IXOFF|IXANY);
    tio.c_lflag=0;
    tio.c_oflag=0;
    tio.c_cc[VTIME]=0;
    tio.c_cc[VMIN]=0;
    if (tcsetattr(fd, TCSANOW, &tio)!=0) printf("tcsetattr() 1 failed\n");

    int mcs=0;
    ioctl(fd, TIOCMGET, &mcs);
    mcs |= TIOCM_RTS;
    ioctl(fd, TIOCMSET, &mcs);

    if (tcgetattr(fd, &tio)!=0) printf("tcgetattr() 4 failed\n");
    tio.c_cflag &= ~CRTSCTS;
    if (tcsetattr(fd, TCSANOW, &tio)!=0) printf("tcsetattr() 2 failed\n");
}

int main(int argc, char **argv)
{
    InitPort();
    int cnt1, cnt2;
    cnt1 = 3;
    cnt2 = 20000;
    cnt1 = atoi(argv[1]);
    cnt2 = atoi(argv[2]);
    for(;;) {
    RTUOutMessage(cnt1, cnt2);
    usleep(1000000);
    }
    tcsetattr(fd, TCSANOW, &old_tio);
    close(fd);
    printf("End\n");

    return 0;
}
4

1 に答える 1

4

送信した文字を受信して​​いる場合は、リモートのシリアル ポートが入力をエコーし​​ているようです。

他のデバイスで入力エコーを無効にするか、受信ロジックで「エコー キャンセル」を実行する必要があります。IEは「エコーFIFO」を作成します。シリアルポートへの各バイト出力も「エコー FIFO」に書き込まれます。エコーが予想されることを示すフラグを設定します。入力が受信されると、それを「echo FIFO」と比較し、一致した場合に文字を削除し、受信した文字を投げます。一致しない場合は、受信文字を受け入れます。「エコー FIFO」が空の場合、エコー フラグをクリアします。

ところで、コードはシリアルポートを生または非標準モードに設定するように見えます。好ましい方法は、

cfmakeraw(&tio);

それよりも

tio.c_iflag=IGNBRK;
tio.c_iflag &= ~(IXON|IXOFF|IXANY);
tio.c_lflag=0;
tio.c_oflag=0;
于 2012-09-21T08:10:02.437 に答える