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

Serial read write with Baud rate 9600 , parity none, data bits 8 and stop bits 2. Unable to communicate with device

我正在做的项目需要使用设备设置以十六进制发送命令,如下所示: 波特率:9600,奇偶校验:None,停止位: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 步为此调用添加错误检查:

  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() return ssize_t 而不是 int.


最后,我怀疑在读取之前刷新输入缓冲区 (tcflush(fd, TCIFLUSH);) 是否有意义。