从串口读取HEX值(Posix)

时间:2021-08-27 15:09:30

I wrote a class to handle data coming from a module to the serial port. The goal is having the port always listening and when it's needed transmit some messages. The module communicates using hexadecimal tokens. Here is my code for the receiving part:

我写了一个类来处理从模块到串口的数据。目标是让端口始终监听,并在需要时传输一些消息。模块使用十六进制令牌进行通信。这是接收部分的代码:

int serial::serial_receive (string &s_buffer, int &rcp)
{
  struct pollfd fds[1];
  fds[0].fd = ptr;
  fds[0].events = POLLIN ;
  int pollrc = poll( fds, 1, 1000);
  if (pollrc < 0)
  {
    perror("poll");
  }
  else if( pollrc > 0)
  {
    if( fds[0].revents & POLLIN )
    {
      char buff[1024];
      ssize_t rc = read(ptr, buff, sizeof(buff) );
      if (rc > 0)
      {
        s_buffer = buff;
        rcp = rc;
       }
        else {cout << "error reading fd";}
    }

}
return pollrc;
}

In my test main:

在我的测试主要:

using namespace std;
char test[] = {0xAA,0x34,0x00,0x22};

int main(void) {
    stringstream ss;
    const char* mybuff;
    string serial_buffer;
    int rcl;

    serial mymodule ("/dev/ttymxc5",115200, 0);  //port configuration

    ss << std::hex << setfill('0');
    mymodule.serial_send(test,4);                //send method
    usleep(2000);

    mymodule.serial_receive(serial_buffer,rcl);  //receive method

    mybuff = serial_buffer.c_str();
        for (int i = 0; i < 8; ++i)
        {
            ss << std::setw(2) << static_cast<unsigned>(mybuff[i]);
        }
    cout << ss.str() << endl;

return 0;
}

My serial port configuration is:

我的串口配置是:

int serial::serial_set()
{
  struct termios options;
  if (tcgetattr (ptr, &options) != 0)
              {
                      return EXIT_FAILURE;
              }
   cfsetospeed (&options, B115200);
   cfsetispeed (&options, B115200);
   options.c_cflag = (options.c_cflag & ~CSIZE) | CS8;
   options.c_iflag &= ~IGNBRK;
   options.c_lflag = 0;
   options.c_oflag = 0;
   options.c_cc[VMIN]  = 0;
   options.c_cc[VTIME] = 5;
   options.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR |    ICRNL | IXON);
   options.c_cflag |= (CLOCAL | CREAD);
   options.c_cflag &= ~(PARENB | PARODD);
   options.c_cflag |= serial_parity;
   options.c_cflag &= ~CSTOPB;
   options.c_cflag &= ~CRTSCTS;
   if (tcsetattr (ptr, TCSANOW, &options) != 0)
      {
       return EXIT_FAILURE;
      }
return EXIT_SUCCESS;
 }

Please note that ISTRIP bit is set as 0, not to lose the 8th bit.

请注意,ISTRIP位设置为0,不会丢失第8位。

The resoult i get is "almost" correct. I'm aspecting a AA B4 04 01 00 00 00 94 sequence but instead i get a AA B4 04 01 00 A8 4A F0 sequence. This mistake is repeatable, every time I send given command to the module.

我得到的结果“几乎”正确。我正在考虑AA B4 04 01 00 00 00 94序列,但我获得了AA B4 04 01 00 A8 4A F0序列。每次我向模块发送给定命令时,这个错误都是可重复的。

Do you possible have some ints or suggestions ?

你有可能有一些注意或建议吗?

1 个解决方案

#1


0  

After some thinking, I found out that i can't simply cast string = char*.

经过一番思考,我发现我不能简单地转换string = char *。

I used a string method instead to build my string:

我使用字符串方法来构建我的字符串:

std::string check(reinterpret_cast<char*>(buff), 8);

Where buff is the char array to convert and 8 is the number of elements.

其中buff是要转换的char数组,8是元素的数量。

Thanks to Neil Butterworth who pointed out the unsafe casting.

感谢Neil Butterworth指出了不安全的铸件。

#1


0  

After some thinking, I found out that i can't simply cast string = char*.

经过一番思考,我发现我不能简单地转换string = char *。

I used a string method instead to build my string:

我使用字符串方法来构建我的字符串:

std::string check(reinterpret_cast<char*>(buff), 8);

Where buff is the char array to convert and 8 is the number of elements.

其中buff是要转换的char数组,8是元素的数量。

Thanks to Neil Butterworth who pointed out the unsafe casting.

感谢Neil Butterworth指出了不安全的铸件。