【问题标题】:Reading Serial Data From C (OSX /dev/tty)从 C (OSX /dev/tty) 读取串行数据
【发布时间】:2012-11-28 14:48:57
【问题描述】:

我正在尝试使用 C 从蓝牙条形码扫描仪 (KDC300) 读取数据。这是我到目前为止的代码,程序成功建立了与扫描仪的蓝牙连接,但是当扫描条形码时,没有输入显示在屏幕上(最终会对数据进行更多处理,但我们必须先让它工作,对吧)。

这是程序:

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

int main (int argc, const char * argv[]) {

    // define vars
    int STOP = 0;
    //char buf[255];

    if(argv[1])
    {
        int fd = open("/dev/tty.KDC1", O_RDONLY);
        if(fd == -1)
        {
            printf("%s", strcat("Unable to open /dev/tty.", argv[1]));
        }

        int res;
        while(STOP == 0)
        {
            while((res = read(fd,buf,255)) == 0);
            {
                if(res > 0)
                {
                    buf[res]=0;
                    printf("%s:%d\n", buf, res);
                    if(buf[sizeof(buf)]=='\n') break;   
                }
            }
        }
    }

    return 0;
}

如果有人有任何想法,到目前为止我对此一无所知。如果有任何帮助,我可以运行screen /dev/tty.KDC1,扫描仪上扫描的任何条形码都会出现在终端中,我无法对数据做任何事情。

贾德

【问题讨论】:

  • 为什么buf的声明被注释掉了?你有一个缓冲区溢出错误。将 buf 声明为 buf[256];如果读取返回 255,您将有空间用于终止 (char) 0。

标签: c serial-port bluetooth screen


【解决方案1】:

这一行:

        while((res = read(fd,buf,255)) == 0);

不做你认为它做的事。那是一个空主体的while 循环。

【讨论】:

    【解决方案2】:

    @tommieb75, strcat 语句来自程序的第一个“go”,我从 argv[1] 中获取了一个变量并将其附加到 /dev/tty.* 中,以便您可以选择要监视的设备。

    我不知道为什么我注释掉了buf,可能是因为看代码太多/尝试不同的方法而忘记了我在哪里(不是一个 C 程序员,这就是我迷路的原因30 行)。

    @caf,很好地抓住了 while 循环后多余的分号,不幸的是,即使在更正它之后,程序也不能正常运行。

    我正在进一步研究这个问题。我可以验证(使用 osx packetlogger)计算机正在获取数据,但是缓冲区中从来没有放置任何数据。

    -贾德

    ----------------编辑--------------

    经过反复试验,我解决了这个问题。添加以下代码来设置串行连接解决了一切:

    struct termios theTermios;
    
    memset(&theTermios, 0, sizeof(struct termios));
    cfmakeraw(&theTermios);
    cfsetspeed(&theTermios, 115200);
    
    theTermios.c_cflag = CREAD | CLOCAL;     // turn on READ
    theTermios.c_cflag |= CS8;
    theTermios.c_cc[VMIN] = 0;
    theTermios.c_cc[VTIME] = 10;     // 1 sec timeout
    ioctl(fileDescriptor, TIOCSETA, &theTermios);
    

    感谢其他答案让我明白这一点。

    【讨论】:

      【解决方案3】:

      Here 是我找到的最好的信息。

      那里的 C 程序使用 termios 只需添加

      #include<string.h>
      

      并更改波特率以满足我的需要。

      【讨论】:

        【解决方案4】:

        在您的代码中

        printf("%s", strcat("无法打开 /dev/tty.", argv[1]));

        你为什么这样做?这样做会更容易:

        printf("%s: 无法打开 /dev/tty.KDC1", argv[0]);

        为什么参数引用命令行?

        res = 读取(fd,buf,255)

        为什么上面注释掉了buf 声明?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-06-02
          • 1970-01-01
          • 1970-01-01
          • 2016-01-10
          • 1970-01-01
          • 2023-03-20
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多