我的linux c应用程序无法从arduino接收字节 [英] My linux c application cannot receive bytes from arduino

查看:60
本文介绍了我的linux c应用程序无法从arduino接收字节的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的Linux C应用程序无法从Arduino接收字节



大家好,我打算使用Arduino Mega 2560作为AT89S52(8051系列微处理器)的编程器。 Arduino板通过USB串口线连接到PC。



首先,我需要在我的Ubuntu中编写一个程序来与Arduino板通信。我的程序可以正常打开连接并将字节写入Arduino(我通过打开/关闭led测试),但问题是Linux程序无法从Arduino接收数据。

我已经搜索了很多教程和论坛但仍然无法解决问题,所以我在这里发帖提问,希望有人可以帮助我。



- 以下是我用来打开设备连接的功能

 AT89S_EID 
usbserial_open( char * dev_name,
UsbSerialDevice * dev_ptr,
int 波特率,
int config)
{
speed_t io_baudrate = B9600;

if (dev_name == NULL || dev_ptr == NULL)
{
return AT89S_EID_ARG_NULL;
}

如果(波特率!= US_BAUDRATE_9600
||波特率!= US_BAUDRATE_19200
||波特率!= US_BAUDRATE_115200)
{
return AT89S_EID_SERIAL_BAUDRATE_INVALID;
}

if (config!= US_CONFIG_8N1
|| config!= US_CONFIG_7E1
|| config != US_CONFIG_7O1)
{
return AT89S_EID_SERIAL_CONFIG_INVALID;
}

// 商店设备名称
strcpy(dev_ptr-> name,dev_name);

// 打开设备
dev_ptr-> fd = open(dev_ptr-> name,
O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
if (dev_ptr-> fd< 0
{
return AT89S_EID_SERIAL_OPEN;
}

// 获取当前的termios设置
if (tcgetattr(dev_ptr-> fd,& dev_ptr-> tios)< 0
{
return AT89S_EID_SERIAL_GET_ATTR;
}

// 设置输入/输出baudrdate
if (baudrate == US_BAUDRATE_9600)
io_baudrate = B9600;
else if (baudrate == US_BAUDRATE_19200)
io_baudrate = B19200;
else if (baudrate == US_BAUDRATE_115200)
io_baudrate = B115200;

if (cfsetispeed(& dev_ptr-> tios,io_baudrate)!= 0
|| cfsetospeed(& dev_ptr-> tios,io_baudrate)!= 0
{
return AT89S_EID_SERIAL_SET_IOSPEED;
}

// 启用接收器,忽略状态行
dev_ptr-> tios.c_cflag | =(CREAD | CLOCAL);
// set config
if (config == US_CONFIG_8N1)
{
dev_ptr-> tios.c_cflag& = ~PARENB;
dev_ptr-> tios.c_cflag& = ~CSTOPB;
dev_ptr-> tios.c_cflag& = ~CSIZE;
dev_ptr-> tios.c_cflag | = CS8;
}
else if (config == US_CONFIG_7E1)
{
dev_ptr-> tios.c_cflag | = PARENB;
dev_ptr-> tios.c_cflag& = ~PARODD;
dev_ptr-> tios.c_cflag& = ~CSTOPB;
dev_ptr-> tios.c_cflag& = ~CSIZE;
dev_ptr-> tios.c_cflag | = CS7;
}
else if (config == US_CONFIG_7O1)
{
dev_ptr-> tios.c_cflag | = PARENB;
dev_ptr-> tios.c_cflag | = PARODD;
dev_ptr-> tios.c_cflag& = ~CSTOPB;
dev_ptr-> tios.c_cflag& = ~CSIZE;
dev_ptr-> tios.c_cflag | = CS7;
}

// 无硬件流量控制
dev_ptr-> tios.c_cflag& = ~CRTSCTS;

// 无输入处理(原始输入)
dev_ptr - > tios.c_iflag& =〜(IXON | IXOFF | IXANY);
// 其他输入设置
dev_ptr-> tios.c_iflag& =〜(ICANON | ECHO | ECHOE | ISIG);

// 无输出处理(原始输出)
dev_ptr - > tios.c_oflag& = ~OPOST;

// 控制字符设置
dev_ptr-> tios .c_cc [VMIN] = 1 ; // 等待收到最少1个字符
dev_ptr-> tios.c_cc [VTIME] = 0 ; // 等待字符时没有超时

// 提交新设置
if (tcsetattr(dev_ptr) - > fd,TCSANOW,& dev_ptr-> tios)< 0
{
返回 AT89S_EID_SERIAL_SET_ATTR;
}

// 等待设备重置&同步
usleep( 1500 * 1000 );

return AT89S_EID_OK;
} / * usbserial_open * /





- 这是接收函数:

 AT89S_EID 
usbserial_recv(UsbSerialDevice * dev_ptr,
unsigned char * data_ptr,
int data_len)
{
int read_byte = 0 ;
char b [ 1 ];

if (dev_ptr == NULL
|| data_ptr == NULL)
{
return AT89S_EID_ARG_NULL;
}

// 块读取
fcntl (dev_ptr-> fd,F_SETFL, 0 );

// 开始接收数据
while (read_byte< data_len)
{
if (read(dev_ptr-> fd,b , 1 )> 0
{
data_ptr [read_byte ++] = * b;
}
else
{
if (错误号码== EAGAIN)
继续;
else if (errno == ETIMEDOUT)
断裂;
else
return AT89S_EID_SERIAL_RECV;
}
}

return AT89S_EID_OK;
} / * usbserial_recv * /





很抱歉发布了长代码:)



我尝试了什么:



我已经搜索了很多教程和论坛,但仍然无法解决问题。我相信Arduino代码工作正常,因为我使用了一些其他工具来测试它(例如:minicom)

解决方案

我解决了我的问题。只需在打开与设备的连接时添加刷新功能,一切都可以正常工作。

 tcflush(fd,TCIOFLUSH); 


My Linux C application cannot receive bytes from Arduino

Hi all, I intend to use Arduino Mega 2560 as a programmer for AT89S52 (a family of 8051 microprocessor). The Arduino board connects to PC via USB Serial cable.

At first I need to write a program in my Ubuntu to communicate with Arduino board. My program can open connection and write bytes to Arduino properly (I tested by turning led on/off), but the problem is that the Linux program cannot receive data from Arduino.
I already searched through many tutorials and forums but still cannot resolve the problem, so I post question here and hope that someone can help me.

- Below is my functon used to open connection to device

AT89S_EID
usbserial_open ( char* dev_name,
                 UsbSerialDevice* dev_ptr,
                 int baudrate,
                 int config )
{
    speed_t io_baudrate = B9600;

    if (dev_name == NULL || dev_ptr == NULL)
    {
        return AT89S_EID_ARG_NULL;
    }

    if (baudrate != US_BAUDRATE_9600
        || baudrate != US_BAUDRATE_19200
        || baudrate != US_BAUDRATE_115200)
    {
        return AT89S_EID_SERIAL_BAUDRATE_INVALID;
    }

    if (config != US_CONFIG_8N1
        || config != US_CONFIG_7E1
        || config != US_CONFIG_7O1)
    {
        return AT89S_EID_SERIAL_CONFIG_INVALID;
    }

    // store device name
    strcpy(dev_ptr->name, dev_name);

    // open device
    dev_ptr->fd = open (dev_ptr->name,
                        O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
    if (dev_ptr->fd < 0)
    {
        return AT89S_EID_SERIAL_OPEN;
    }

    // get current termios settings
    if (tcgetattr(dev_ptr->fd, &dev_ptr->tios) < 0)
    {
        return AT89S_EID_SERIAL_GET_ATTR;
    }

    // set input/output baudrdate
    if (baudrate == US_BAUDRATE_9600)
        io_baudrate = B9600;
    else if (baudrate == US_BAUDRATE_19200)
        io_baudrate = B19200;
    else if (baudrate == US_BAUDRATE_115200)
        io_baudrate = B115200;

    if (cfsetispeed(&dev_ptr->tios, io_baudrate) != 0
        || cfsetospeed(&dev_ptr->tios, io_baudrate) != 0)
    {
        return AT89S_EID_SERIAL_SET_IOSPEED;
    }

    // enable receiver, ignore status line
    dev_ptr->tios.c_cflag |= (CREAD | CLOCAL);
    // set config
    if (config == US_CONFIG_8N1)
    {
        dev_ptr->tios.c_cflag &= ~PARENB;
        dev_ptr->tios.c_cflag &= ~CSTOPB;
        dev_ptr->tios.c_cflag &= ~CSIZE;
        dev_ptr->tios.c_cflag |= CS8;
    }
    else if (config == US_CONFIG_7E1)
    {
        dev_ptr->tios.c_cflag |= PARENB;
        dev_ptr->tios.c_cflag &= ~PARODD;
        dev_ptr->tios.c_cflag &= ~CSTOPB;
        dev_ptr->tios.c_cflag &= ~CSIZE;
        dev_ptr->tios.c_cflag |= CS7;
    }
    else if (config == US_CONFIG_7O1)
    {
        dev_ptr->tios.c_cflag |= PARENB;
        dev_ptr->tios.c_cflag |= PARODD;
        dev_ptr->tios.c_cflag &= ~CSTOPB;
        dev_ptr->tios.c_cflag &= ~CSIZE;
        dev_ptr->tios.c_cflag |= CS7;
    }

    // no HW flow control
    dev_ptr->tios.c_cflag &= ~CRTSCTS;

    // no input processing (raw input)
    dev_ptr->tios.c_iflag &= ~(IXON | IXOFF | IXANY);
    // other input settings
    dev_ptr->tios.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);

    // no output processing (raw output)
    dev_ptr->tios.c_oflag &= ~OPOST;

    // control character settings
    dev_ptr->tios.c_cc[VMIN]  = 1; // wait for 1 minimum chacacter received
    dev_ptr->tios.c_cc[VTIME] = 0; // no timeout when waiting for charater

    // commit new settings
    if (tcsetattr(dev_ptr->fd, TCSANOW, &dev_ptr->tios) < 0)
    {
        return AT89S_EID_SERIAL_SET_ATTR;
    }

    // wait for device reset & sync up
    usleep(1500 * 1000);

    return AT89S_EID_OK;
} /* usbserial_open */



- And this is the receiving function:

AT89S_EID
usbserial_recv ( UsbSerialDevice* dev_ptr,
                 unsigned char* data_ptr,
                 int data_len )
{
    int read_byte = 0;
    char b[1];

    if (dev_ptr == NULL
        || data_ptr == NULL)
    {
        return AT89S_EID_ARG_NULL;
    }

    // block reading
    fcntl(dev_ptr->fd, F_SETFL, 0);

    // start receiving data
    while (read_byte < data_len)
    {
        if (read(dev_ptr->fd, b, 1) > 0)
        {
            data_ptr[read_byte++] = *b;
        }
        else
        {
            if (errno == EAGAIN)
                continue;
            else if (errno == ETIMEDOUT)
                break;
            else
                return AT89S_EID_SERIAL_RECV;
        }
    }

    return AT89S_EID_OK;
} /* usbserial_recv */



So sorry for posting a long code :)

What I have tried:

I already searched through many tutorials and forums but still cannot resolve the problem. I believe that the Arduino code is working fine because I used some other tools to test it (e.g.: minicom)

解决方案

I resolved my problem. Just add flush function when open the connection to device, everything can be working fine.

tcflush(fd, TCIOFLUSH);


这篇关于我的linux c应用程序无法从arduino接收字节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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