【问题标题】:read from serial port fails when called twice调用两次时从串口读取失败
【发布时间】:2015-11-14 23:42:56
【问题描述】:

解决了以下问题:读/写字符数错误

我正在尝试读取和写入串行端口,但我在 C/C++ 方面没有太多经验。

我的端口连接到需要以下设置的运动控制器/驱动器:

  • 波特率:57600
  • 数据位:8
  • 奇偶校验:无
  • 停止位:1
  • 流控制:Xon/Xoff
  • 终结者 CRLF

问题:代码将写入和读取我的第一个命令,但它挂在第二个读取调用上。我目前正在阻止,直到我收到至少一个字符,但每个书面命令都应该生成一个返回。

附加信息:如果我首先拔下遥控器并重新插入,我只能运行第一次写入/读取。或者,我可以打开一个很酷的术语窗口,设置我的串行端口并运行一些命令。当我关闭酷术语窗口时,我将能够写/读一次。

当前代码:

#include <stdio.h>
#include <string.h>
#include <unistd.h> 
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <time.h>
#include <iostream>
using namespace std;

int open_port(void)
{
        int fd;

     // open file descriptor
        fd = open("/dev/cu.USA19H41P1.1", O_RDWR | O_NOCTTY);

     // if unsucessful
        if (fd == -1)
        {
                printf("open_port: unable to open port. \n");
        }
        else
        {
             // remains open across executables
                fcntl(fd, F_SETFL, 0);
                printf("port is open. \n");
        }
        return (fd);
 }

int configure_port(int fd)
{

     // store terminal port settings
        struct termios port_settings;
        memset(&port_settings, 0, sizeof port_settings);
        if(tcgetattr(fd, &port_settings) !=0)
        {
                printf("error tcgetattr \n");
                cout << errno;
        }

        port_settings.c_iflag = 0;
        port_settings.c_oflag = 0;
        port_settings.c_lflag = 0;
        port_settings.c_cflag = 0;

     // flush
        tcflush(fd, TCIOFLUSH);

     // set baud rate
        cfsetispeed(&port_settings, B57600);
        cfsetospeed(&port_settings, B57600);

     // xon/xoff requirment
        port_settings.c_iflag |= IXON;
        port_settings.c_iflag |= IXOFF;

     // no parity requirement
        port_settings.c_cflag &= ~PARENB;

     // one stop bin requirement
        port_settings.c_cflag &= ~CSTOPB;

     // turn on read
        port_settings.c_cflag |= CREAD;
        port_settings.c_cflag |= CLOCAL;

     // no character processing and 8 bit input
        port_settings.c_cflag &= ~CSIZE;
        port_settings.c_cflag |= CS8;

     // one character blocking 
        port_settings.c_cc[VMIN]  = 1;
        port_settings.c_cc[VTIME] = 5;

     // apply above settings
       if(tcsetattr(fd,TCSANOW, &port_settings) != 0)
        {
                printf("error tcsetattr \n");
                cout << errno;
        }

     // flush buffers one more time
        tcflush(fd, TCIOFLUSH);

        return(fd);
}

int read_write(int fd)
{
        // write to serial port
        ssize_t size=write(fd, "1va?\r\n", 8);
        // wait until output is transmitted
        tcdrain(fd);

        // read from serial port
        char buf[100];
        memset(buf, '\0', sizeof buf);
        ssize_t size2=read(fd, &buf, sizeof(buf));
        cout << buf << endl;
        return(fd);
 }


int main(void)
{
 // open port
 int fd = open_port();

// store old settings
struct termios old_settings;
memset(&old_settings, 0, sizeof old_settings);
tcgetattr(fd,&old_settings);

// configure port
configure_port(fd);

// write/read first command ("1va?\r\n")
read_write(fd);

// write read second command ("1pa?\r\n")
ssize_t size=write(fd, "1pa?\r\n", 8);
tcdrain(fd);
char buf[100];
memset(buf, '\0', sizeof buf);
ssize_t size3=read(fd, &buf, sizeof(buf));
cout << buf;

//close serial port
close(fd);
tcsetattr(fd, TCSANOW, &old_settings);
return 0;
}

【问题讨论】:

  • 你做了什么?
  • 请出示代码
  • 没有C/C++语言!
  • 抱歉,我在编辑完帖子之前按了回车

标签: c linux unix serial-port


【解决方案1】:

Here 是一些使用串行端口设置正确标志和波特率的示例代码:

提供您的代码和更详尽的解释,以便我们解决您的问题。写和读我的第一个命令是什么意思?执行此命令后您的设备是否仍有响应?第二条命令不是发送了吗?

【讨论】:

  • 第二个写命令似乎发送了。如果我执行 'cout
  • ssize_t size=write(fd, "1va?\r\n", 8);如果我没记错字符串“1va?\r\n”的长度为6。也许那里有问题。 \r 和 \n 是 1 个字符
  • 我想你刚刚解决了!我已经盯着它看了 2 天了。
  • 请记住 \ 是一个转义字符。这是一种编写一些 ASCII 字符(如回车和制表符)的方法。所以 \r 实际上是 0x0d (十六进制)并且只有 1 个字节长。如果这解决了您的问题,请您接受我的回答。
猜你喜欢
  • 2023-03-30
  • 2014-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-18
  • 1970-01-01
  • 2016-09-27
相关资源
最近更新 更多