首页 文章

如何从C中读取串口设备

提问于
浏览
4

我试图弄清楚如何使用Linux C中的串行通信读取/写入我的Arduino . 目前我正在尝试阅读我的“触发”我的Arudino的回复

echo "g" > /dev/ttyACM0"

我尝试使用以下命令查看终端中Arduino的响应:

tail -f /dev/ttyACM0

这是应该的 . 现在我想在C应用程序中做同样的事情 . 所以我做了这个测试

void testSerialComm()
{

    std::string port = "/dev/ttyACM0";
    int device = open(port.c_str(), O_RDWR | O_NOCTTY | O_SYNC);

    std::string response;
    char buffer[64];

    do
    {
        int n = read(device, buffer, sizeof buffer);

        if (n > 0) {
            response += std::string(buffer);
            std::cout << buffer;
        }

    } while (buffer[0] != 'X'); // 'X' means end of transmission

    std::cout << "Response is: " << std::endl;
    std::cout << response << std::endl;

    close(device);

}

在几条“消息”之后,传输变得有些混乱 . 我的测试应用程序以随机顺序写入响应字符,而某些东西不正确 . 我尝试通过此命令配置/ dev / ttyACM0设备:

stty -F /dev/ttyUSB0 cs8 115200 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts

没有骰子 . 有人可以帮我理解如何在C中与我的Arduino进行通信吗?

1 回答

  • 8

    显示的代码打开 /dev/ttyACM0 ,试图寻找到"file"的结尾,并根据生成的文件位置分配一个老式的C风格的内存缓冲区,出于某些奇怪的原因,而不是使用 std::vectorstd::string ,尽管索赔根据问题的标签,这可能是一个C程序 .

    这种方法的问题在于,您只能通过常规,简单,花园种类的文件进行搜索 . /dev/ttyACM0 不是常规文件 . 它's a device. Although some devices are seekable, this one isn' t . 根据评论,你已经独立发现了 .

    串行端口设备是可读写的 . 他们不可寻求 . 在串口上没有“寻找”这样的东西 . 这是没有意义的 .

    要从串口读取,您只需阅读它即可 . 操作系统确实维护了一定大小的内部缓冲区,因此如果已经通过串行端口接收到某些字符,则初始读取将全部返回(假设 read() 缓冲区大小足够大) . 例如,如果传递1024个字符的缓冲区,并且已经从串行端口读取了5个字符 read() 将返回5,以相应地指示 .

    如果没有读取任何字符,并且您将串行端口作为阻塞设备打开, read() 将至少阻塞,直到从串行端口读取一个字符,然后返回 .

    所以,为了从串口读取所有你需要做的就是从它读取,直到你've decided that you'已读完所有要读取的内容 . 你是如何决定的?随你(由你决定 . 在读取换行符之前,您可能决定只读取 . 或者,您可能只读取您想要读取的内容,直到读取了固定的 #n 个字符 . 这完全取决于你 .

    当然,如果硬件配置合理,并且您使用串行端口设备进行必要的安排以遵守串行端口控制引脚,并且根据您的配置,DCD和/或DSR引脚会发出信号以指示串口设备不再可用, read() 将立即返回0,表示串口设备上的伪文件状态 . 这也是您需要实现必要的逻辑来处理的东西 .

    附:由于它们自己的内部缓冲算法,C风格的stdio和C风格的 iostream 都不能很好地与字符设备配合使用 . 使用串行端口时,使用 open(2)read(2)write(2)close(2) 会更好 . 但所有上述内容仍然适用 .

相关问题