Последовательное чтение и запись со скоростью 9600 бод, без контроля четности, битами данных 8 и стоп-битами 2. Невозможно связаться с устройством - PullRequest
0 голосов
/ 28 января 2019

Я работаю над проектом, который требует отправки команды в шестнадцатеричном формате с настройкой устройства следующим образом: Скорость передачи данных: 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 голосов
/ 28 января 2019

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;

unsets.

Если вы хотите использовать 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, ...

Для некоторых из этих ошибок с write и read компилятор должен был предупредить вас.

Обратите также внимание, что read() и write() возвращают ssize_t не int.


Не в последнюю очередь я сомневаюсь, что очистка буфера ввода (tcflush(fd, TCIFLUSH);) передчтение имеет смысл.

...