Чтение шестнадцатеричных значений uart игнорирует определенные байты / символы - PullRequest
0 голосов
/ 06 апреля 2020

Я новичок в C / C ++ и пытаюсь установить связь с помощью UART, используя значения HEX.

Порт устройства: / dev / ttyS2. Скорость передачи: 38400

Я использую redis для подписки на сообщения. И для тестирования я использую «Termite», терминал RS232 для имитации.

Я нашел руководство, которое работало очень хорошо, проблема в том, что когда я пытаюсь прочитать сообщение, некоторые байты / символы связываются с ним .

Вот мой код для соединения :

    this->fd = open(device,O_RDWR | O_NOCTTY);

    /*---------- Setting the Attributes of the serial port using termios structure --------- */
    tcgetattr(this->fd, &SerialPortSettings);   /* Get the current attributes of the Serial port */

    /* Setting the Baud rate */
    cfsetispeed(&SerialPortSettings,B38400); /* Set Read  Speed as 38400 */
    cfsetospeed(&SerialPortSettings,B38400); /* Set Write Speed as 38400 */

    /* 8N1 Mode */
    SerialPortSettings.c_cflag &= ~PARENB;   /* Disables the Parity Enable bit(PARENB),So No Parity   */
    SerialPortSettings.c_cflag &= ~CSTOPB;   /* CSTOPB = 2 Stop bits,here it is cleared so 1 Stop bit */
    SerialPortSettings.c_cflag &= ~CSIZE;    /* Clears the mask for setting the data size             */
    SerialPortSettings.c_cflag |=  CS8;      /* Set the data bits = 8                                 */

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

    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_oflag &= ~OPOST; /*No Output Processing*/
    SerialPortSettings.c_oflag = 0;

    /* Setting Time outs */
    SerialPortSettings.c_cc[VMIN] = 1;  /* Read at least X characters */
    SerialPortSettings.c_cc[VTIME] = 0; /* Wait indefinetly */

    tcflush(this->fd, TCIFLUSH);

    if((tcsetattr(this->fd,TCSANOW,&SerialPortSettings)) != 0) { /* Set the attributes to the termios structure*/
        printf("\n  ERROR ! in Setting attributes");
    }
    else {
        tcsetattr(fd, TCSANOW, &SerialPortSettings);
        printf("\n  BaudRate = 38400 \n  StopBits = 1 \n  Parity   = none\n\n");
    }

А вот код для чтения :

        char read_buffer[32];
        int bytes_read;

        while(true) {
            bytes_read = read(serialport.fd, &read_buffer, sizeof(read_buffer)); /* Read the data */

            printf("bytes read: %d", bytes_read);

            if (bytes_read < 0) {
                printf("Error reading: %s", strerror(errno));
            }
            else if (bytes_read > 0) {
                //read_buffer[bytes_read] = '\0';

                printf("\n");
                printf("HEX:");
                for (int i=0; i<bytes_read; i++) {   /*printing only the received characters*/
                    printf(" %02x",read_buffer[i]);
                }
                printf("\n");
                printf("+----------------------------------+\n");


                /*#if defined(MODULE_REDIS) || defined(MODULE_ALL)
                    //redis.publish("channel:uart:ack", read_buffer);
                    redis.publish("channel:uart:ack", vectorUint8toHex(read_data).c_str());
                #endif*/
            }

            std::this_thread::sleep_for(std::chrono::milliseconds(1));
        }

Когда я отправляю сообщение 0x2401010203040506070809af23 , оно показывает только 8 байтов. (байты 0x03 и 0x04 портятся с сообщением)

OUTPUT:

bytes read: 0bytes read: 8
HEX: 05 06 07 08 09 af 23 0a
+----------------------------------+

Но когда я отправляю 0x2401010200000506070809af23 , он отлично работает

OUTPUT:

bytes read: 14
HEX: 24 01 01 02 00 00 05 06 07 08 09 af 23 0a
+----------------------------------+

Что я делаю не так? И еще кое-что. При использовании Termite необходимо включить настройку «append LF», иначе я не смогу прочитать сообщение, но это добавляет « 0a » к моему сообщению, связано ли это с настройками последовательный порт?

1 Ответ

0 голосов
/ 08 апреля 2020

Хорошо, поэтому проблема заключалась в том, что некоторые двоичные байты были 0x03 и 0x04, которые находятся в ASCII «конец текста» и «конец передачи». И пропустил эту строку в конфигурациях:

SerialPortSettings.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);

Благодаря комментариям я искал некоторые недостающие конфигурации и нашел ее.

Есть еще один пост для моей проблемы, который я не сделал найдено в то время: двоичный последовательный порт считал пропущенные байты в c

...