将Windows串行程序移植到Linux

时间:2018-07-28 09:58:41

标签: c linux serial-port

我之前的问题(Usb-serial writing and reading data issue in Debian Gnu/Linux)没有得到任何答案,所以我现在正在尝试另一种方法。

我将仪表插入Windows,运行专有程序并检查了COM端口设置settings are here

然后我根据this文章写了一些代码。这是我所拥有的

#include <sys/stat.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include <termios.h> 

#define DEVICE "/dev/ttyUSB0"
#define WRITE_SPEED B1200  
#define READ_SPEED B1200 
#define PARITY ~PARENB  
#define STOPBITS ~CSTOPB  
#define DATASIZE CS8 
#define HARDWARE_FLOW_CONTROL ~CRTSCTS 
#define RECEIVER CREAD 
#define MODEM_CONTROL_LINES CLOCAL
#define START_STOP_INPUT_CONTROL IXON 
#define START_STOP_OUTPUT_CONTROL IXOFF 
#define ANY_CHARACTER_RESTORE_STOPPED_OUTPUT ~IXANY 
#define CANONICAL_MODE ~ICANON 
#define PRINT_ECHO ECHO 
#define ECHO_NEW_LINE ECHONL
#define ERASE_CHARACTER ECHOE 
#define APPLICATION_DEFINED_CHARACTER IEXTEN  
#define GENERATE_SIGNALS ISIG 
#define OUTPUT_PROCESSING OPOST 
#define SEND_TIMES_COUNT  1
#define SLEEP_TIME 0

unsigned int HEX_DATA_INPUT[] = {0xFF, 0x3A, 0x32, 0x34, 0x31, 0x3B, 0x30, 0x3B, 0x36, 0x35, 0x34, 0x30, 0x35, 0x0D};
unsigned int HEX_DATA_OUTPUT[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
int HEX_DATA_SIZE = 14;


/*setup terminal

  fd - terminal file descriptor
  returns 0 if everything fine and
  not 0 otherwise

*/
int setupTerminal(int fd) {

    int ret = 0;

    struct termios SerialPortSettings;     
    tcgetattr(fd, &SerialPortSettings);
    cfsetispeed(&SerialPortSettings, WRITE_SPEED);   
    cfsetospeed(&SerialPortSettings, READ_SPEED);     
    SerialPortSettings.c_cflag &= STOPBITS;
    SerialPortSettings.c_cflag &= ~CSIZE;
    SerialPortSettings.c_cflag |= DATASIZE;
    SerialPortSettings.c_cflag &= HARDWARE_FLOW_CONTROL;
    SerialPortSettings.c_cflag |= RECEIVER | MODEM_CONTROL_LINES;
    SerialPortSettings.c_iflag &=  (START_STOP_INPUT_CONTROL | START_STOP_OUTPUT_CONTROL | ANY_CHARACTER_RESTORE_STOPPED_OUTPUT);
    SerialPortSettings.c_iflag &= (CANONICAL_MODE | PRINT_ECHO | ECHO_NEW_LINE | ERASE_CHARACTER| APPLICATION_DEFINED_CHARACTER | GENERATE_SIGNALS);
    SerialPortSettings.c_oflag &= OUTPUT_PROCESSING;

    if((tcsetattr(fd, TCSANOW, &SerialPortSettings)) != 0) {

        /*Error while changing port settings*/
        printf("Error in setting attributes. Error text:%s\n", strerror(errno));
        ret = errno;
    }
}

int main(int argc, char **argv)
{
    int ret = 0;

    /*We are opening serila-usb port here*/
    int fd = open(DEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK | O_NDELAY);
    if(fd != -1) {

        /*port has been opened successfully*/
        if(setupTerminal(fd) == 0)  {

            /*Terminal has been st up correctly*/

            /*discard old data in the buffer*/
            tcflush(fd, TCIFLUSH);

            /*writing data to the port*/
            int writeRet = -1;
            int i = 0;
            for(i = 0; i < SEND_TIMES_COUNT; ++i) {

                writeRet = write(fd, HEX_DATA_INPUT, HEX_DATA_SIZE * sizeof(unsigned int));
                printf("writeRet=%d\n", writeRet);  
            }

            if(writeRet != -1) {

                /*writing to the port succeffull*/          

                /*Delay before reading data*/
                sleep(SLEEP_TIME);

                int readRet = read(fd, HEX_DATA_OUTPUT, HEX_DATA_SIZE * sizeof(unsigned int));
                if(readRet != -1) {

                    /*reading from the port successfully*/
                    printf("readRet=%d\n", readRet);

                }
                else {

                    /*Error while reading from the port*/
                    printf("error while reading from the port. Error code:%d; Error message:%s\n", errno, strerror(errno));
                    ret = errno;      
                }
            }
            else {

                /*Error while writing data to the port*/
                printf("writing to the port failed. Error text: %\n", strerror(errno));
                ret = errno;
            }
        }
        else {

            printf("error opening %s. Error message:%s\n", DEVICE, strerror(errno));
            ret = errno;
        }
    }    
    else {

        printf("error opening port. Error number: %d; error text: %s\n", errno, strerror(errno));
        ret = errno;
    }    

    int cdf = close(fd);
    printf("cdf=%d\n", cdf);

    printf("press any key to exit\n");
    getchar();

    return ret;
}

此代码使我能够成功地将56 bytes写入端口,但是尝试读取却使我error 11 “资源临时不可用” 。我猜这是因为我对termios结构进行了错误的设置,但我不知道是哪个。在Windows中,我使用软件“串行端口监视器”来跟踪设备与专有程序之间的数据交换,位于跟踪文件here under the nameexchange.xlsx中,我试图按照专有程序中的信息以与专有程序相同的方式在程序中设置端口这个文件,但没有运气。您能帮我找出我的错误在哪里吗?

0 个答案:

没有答案