linux c ++串口回显输出 [英] linux c++ serial port echoes output

查看:164
本文介绍了linux c ++串口回显输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的程序中,它发送字节到串行端口,我接收我发送的字节。我不想接收我发送的字节,我不知道该怎么做?

In my program which sends bytes to a serial port, I receive bytes which I send. I don't want to receive bytes which I send, and I don't know how to do this?

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


推荐答案

您必须在其他设备上禁用输入回声,或者在其他设备上执行回声消除你的接收逻辑。 I.E.创建echo FIFO。输出到串行端口的每个字节也写入echo FIFO。设置指示预期回声的标志。当接收到输入时,将其与echo FIFO进行比较,并在匹配时删除字符,并抛出接收字符。如果没有匹配,则接受receive char。当echo FIFO为空时清除回显标志。

You will either have to disable input echo at the other device, or perform "echo cancellation" in your receive logic. I.E. create an "echo FIFO". Each byte output to the serial port is also written to the "echo FIFO". Set a flag indicating that an echo is expected. As input is received, compare it to the "echo FIFO", and remove chars when it matches, and toss the receive char. If no match, then accept receive char. Clear the echo flag when the "echo FIFO" is empty.

代码显示将串口设置为原始或非规范模式。首选方法是使用

BTW the code appears to set the serial port to raw or non-canonical mode. The preferred method would be to use

cfmakeraw(&tio);

而不是

tio.c_iflag=IGNBRK;
tio.c_iflag &= ~(IXON|IXOFF|IXANY);
tio.c_lflag=0;
tio.c_oflag=0;

这篇关于linux c ++串口回显输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆