波特率9600,奇偶校验无,数据位8和停止位2的串行读写。无法与设备通信

时间:2019-01-28 05:23:34

标签: c posix embedded-linux termios

我正在研究需要以十六进制发送命令的设备设置项目,如下所示: 波特率:9600,奇偶校验:无,停止位:2,数据位:8(9600,8N2)。

我已通过将数据发送到带有minicom的设备进行了验证。我可以查看CRO上的数据。但是,当我通过C代码发送数据并且无法在CRO上看到数据并且无法始终以读取功能将程序输出为FFFFF时。

用于串行读写的源代码:

int32_t Read()
{
   printf("Entering Read function \n");
   int fd;
   fd = open("/dev/ttyS1", O_RDWR | O_NOCTTY | O_NDELAY);
   int j=0;

    if (fd == -1)
    {
        perror("open_port: Unable to open /dev/ttyS1\n");
        exit(1);
    }
    else
    {
        printf("Port /dev/ttyS1 opened successfully\n"); 
    }

    //---------- Setting the Attributes of the serial port using termios structure --------- 

        struct termios SerialPortSettings;  // Create the structure                          

        tcgetattr(fd, &SerialPortSettings); // Get the current attributes of the Serial port 

        cfsetispeed(&SerialPortSettings,B9600); // Set Read  Speed as 9600                       
        cfsetospeed(&SerialPortSettings,B9600); // Set Write Speed as 9600                       

        SerialPortSettings.c_cflag &= ~PARENB;   // Disables the Parity Enable bit(PARENB),So No Parity 
        SerialPortSettings.c_cflag &= ~PARODD; // added

        SerialPortSettings.c_cflag |=  CS8;      // Set the data bits = 8    
        SerialPortSettings.c_cflag &= CSTOPB;   // CSTOPB = 2 Stop bits
        SerialPortSettings.c_cflag &= ~CSIZE;    // Clears the mask for setting the data size            


        SerialPortSettings.c_cflag &= ~CRTSCTS;       // No Hardware flow Control                         
        SerialPortSettings.c_cflag |= (CREAD | CLOCAL); // Enable receiver,Ignore Modem Control lines       

        SerialPortSettings.c_lflag =0; /* RAW input */ // added

        SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY);          // Disable XON/XOFF flow control both i/p and o/p 
        SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);  // Non Cannonical mode   

        SerialPortSettings.c_cc[VMIN]  = 0; // added for testing // added 1 sec
        SerialPortSettings.c_cc[VTIME] = 5; // added for testing // added

        SerialPortSettings.c_iflag = 0;            /* SW flow control off, no parity checks etc */ // added

        SerialPortSettings.c_oflag &= ~OPOST;// No Output Processing

        if((tcsetattr(fd,TCSANOW,&SerialPortSettings)) != 0) // Set the attributes to the termios structure
            printf("\n  ERROR ! in Setting attributes");
        else
                    printf("\n  BaudRate = 9600 \n  StopBits = 2 \n  Parity   = None\n");

     //------------------------------- Write data to serial port -----------------------------

        unsigned char write_buffer[] = {0x28,0x11,0xDF,0xBC};   // Buffer containing characters to write into port       

        int  bytes_written  = 0;    // Value for storing the number of bytes written to the port 

        for(j=0;j<4;j++)
        {
            bytes_written = write(fd,write_buffer[j],sizeof(write_buffer));// use write() to send data to port                                           
                                             // "fd"                   - file descriptor pointing to the opened serial port 
                                            //  "write_buffer"         - address of the buffer containing data              
                                             // "sizeof(write_buffer)" - No of bytes to write  
                                             //
            printf("Byte written : %x\n",write_buffer[j]);                                   
            printf("\n  %d Bytes written to ttyS1", bytes_written);
            printf("\n +----------------------------------+\n\n");

        }

        sleep(2);   

        //------------------------------- Read data from serial port -----------------------------

        tcflush(fd, TCIFLUSH);  //  Discards old data in the rx buffer            

        unsigned char read_buffer[40];  //  Buffer to store the data received              
        int  bytes_read = 0;   //  Number of bytes read by the read() system call 
        int i = 0;


        bytes_read = read(fd,&read_buffer,40); // Read the data                  

        printf("\n\n  Bytes Rxed -%x", bytes_read); // Print the number of bytes read 
        printf("\n\n  ");

        for(i=0;i<bytes_read;i++)    //printing only the received characters
            printf("%x",(int)(*(unsigned char*)(&read_buffer[i])));

        printf("\n +----------------------------------+\n\n\n");

        close(fd); // Close the serial port 



  printf("Exiting Read function \n");   
}   

输出:

Entering Read function 

Port /dev/ttyS1 opened successfully

  BaudRate = 9600 
  StopBits = 2 
  Parity   = None
Byte written : 28

  -1 Bytes written to ttyS1
 +----------------------------------+

Byte written : 11

  -1 Bytes written to ttyS1
 +----------------------------------+

Byte written : df

  -1 Bytes written to ttyS1
 +----------------------------------+

Byte written : bc

  -1 Bytes written to ttyS1
 +----------------------------------+

  Bytes Rxed -ffffffff

 +----------------------------------+
Exiting Read function

1 个答案:

答案 0 :(得分:2)

首先在此呼叫中添加错误检查:

  tcgetattr(fd, &SerialPortSettings); 

喜欢

if (0 > tcgetattr(fd, &SerialPortSettings))
{
  /* log and handle error */ 
}

然后在这里

  SerialPortSettings.c_cflag |=  CS8;

您设置数据位。

下面两行将其清除

  SerialPortSettings.c_cflag &= ~CSIZE; 

反之亦然。

也是这个

  SerialPortSettings.c_cflag &= CSTOPB;

取消设置。

如果要使用2个停止位设置,请这样做

  SerialPortSettings.c_cflag |= CSTOPB;

不只是做

  SerialPortSettings.c_oflag &= ~OPOST;

  SerialPortSettings.c_oflag = 0;

该代码错误地调用了write()。这个

   for(j=0;j<4;j++)
   {
     bytes_written = write(fd,write_buffer[j],sizeof(write_buffer));

应该是

    for(j=0;j<4;j++)
    {
      bytes_written = write(fd, &write_buffer[j], 1)

或者只是放下循环并做

    bytes_written = write(fd, write_buffer, sizeof write_buffer);

调用read()也是错误的。

应该是

    bytes_read = read(fd, read_buffer, ...

对于writeread的某些错误,编译器应已警告您。

请注意,read()write()返回ssize_t而不是int


最后,我怀疑在读取有意义的输入之前先清空输入缓冲区(tcflush(fd, TCIFLUSH);)。