gpt4 book ai didi

c - 如何在C中转换从串口传入的十六进制值?

转载 作者:行者123 更新时间:2023-11-30 16:26:39 28 4
gpt4 key购买 nike

概述:我想使用 Visual Studio(C 语言)通过串行 COM 端口从传感器读取 24 字节数据包的小端十六进制值。每当新数据发送到端口时,我都需要更新串行读取,并将数据的某些字节解释为浮点值。当串行数据可用时,如何从 COM 端口读取数据、组织字节并将它们转换为 float /有用信息?

详细信息:传入数据包的长度已知为 24 字节,并且以已知字符(“{”和“}”)开始/结束,因此有助于了解要捕获多少字节以及如何捕获打破他们。字节 7-10 包含小端十六进制格式的气体 1 浓度数据,字节 11-14 包含小端十六进制格式的气体 2 浓度数据。示例数据包如下所示:

Example 24-byte HEX packet 1

类似数据包的另一个示例(由传感器数据表提供)如下所示:

Example 24-byte HEX packet 2

我为整个操作绘制的伪代码概述如下:

If serial data is available{

//read serial packet into char array
Char serialString[24] = read serial until newline character ()

startBracketHexChar = serialString[0] //”{“ part of packet
Gas1HexChar= serialString[6-9] //gas measurement 1 data from packet
Gas2HexChar = serialString[10-13] //gas measurement 2 data from packet
tempHexChar = serialString[14-17] //temp measurement from packet
endBracketHexChar = serialString[23] //”}” part of bracket

//if packet is as expected…
if (startBracketHexChar == ‘{‘ && endBrackHexChar == ‘}’){

Gas1Float = char.to.float(Gas1HexChar) //convert char to float type
Gas2Float = char.to.float(Gas2HexChar) //convert char to float type
tempFloat = char.to.float(tempHexChar) //convert char to float type
gas1textBox.Text = Gas1Float; //display gas 1 reading
gas2textBox.Text = Gas2Float; //display gas 2 reading
temptextBox.Text = tempFloat; //display temp reading
}
else {
ErrortextBox.Text = “Packet error”; //unexpected packet error
}
}

我认为我在伪代码中关于读取 Gas1HexChar 数组的假设是非常错误的(也许它需要逐个字符地读取并缝合在一起而不是在一个数组 block 中?)并转换它(调用 a 时出现问题) char string 一个十六进制值,然后将该十六进制值转换为 float ?) - 这是我的知识和经验非常有限的地方,非常感谢实现建议。

最佳答案

好吧,不用担心,这并不太难。

我已经修改了您的伪代码,因此它可以编译为 C 代码片段。我相信您问题的主要部分是关于如何提取和组装多字节值。在下面的代码块中,这是decode函数。

在处理像您这样的二进制数据包时,最好使用unsigned char,而不仅仅是char。这使得换档更容易/更正确。

您说数据包以换行符终止,但这没有显示在图中。而且,由于我们正在处理二进制数据[正如您在热门评论中所确认的那样],数据包数据部分中的任何有效字节都可能是 0x0A(即换行符),因此我们在看到换行符之前,不能逐个字符地读取。

如果末尾确实有换行符,我们可能需要读取 25 个字节并仅检查最后一个字符。

我不使用Windows :-),所以我不知道访问COM端口的细节,但我已经编写了您可以填写的函数。

<小时/>

无论如何,代码如下[请原谅无偿的样式清理]:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

typedef struct {
char Text[100];
} TextBox_t;

FILE *stream;

TextBox_t gas1textBox;
TextBox_t gas2textBox;
TextBox_t temptextBox;
TextBox_t ErrortextBox;

// serial_data_is_available -- check for data ready
int
serial_data_is_available(void)
{

return 1;
}

// serial_get -- get single byte from device
unsigned char
serial_get(void)
{

return rand();
}

// serial_buf -- assemble packet buffer
int
serial_buf(unsigned char *buf,int buflen)
{
int idx;

for (idx = 0; idx < buflen; ++idx)
buf[idx] = serial_get();

return idx;
}

// decode -- get a binary value
uint32_t
decode(unsigned char *buf,int beg,int end)
{
uint32_t acc = 0;

for (int idx = end; idx >= beg; --idx) {
acc <<= 8;
acc |= buf[idx];
}

return acc;
}

// floatget -- get a float value
float
floatget(unsigned char *buf,int beg,int end)
{
union {
float fval;
uint32_t val;
} join;

join.val = decode(buf,beg,end);

return join.fval;
}

// process_packet -- process a single packet
void
process_packet(void)
{
// for raw binary data, unsigned is better
unsigned char buf[24];

// read serial packet into char array
serial_buf(buf,sizeof(buf));

// "{" part of packet
char start = buf[0];

// "}" part of bracket
char end = buf[23];

//if packet is as expected…
if ((start == '{') && (end == '}')){
// gas measurement 1 data from packet
float Gas1Float = floatget(buf,6,9);

// gas measurement 2 data from packet
float Gas2Float = floatget(buf,10,13);

// temp measurement from packet
float tempFloat = floatget(buf,14,17);

sprintf(gas1textBox.Text,"%f",Gas1Float);
sprintf(gas2textBox.Text,"%f",Gas2Float);
sprintf(temptextBox.Text,"%f",tempFloat);
}
else {
strcpy(ErrortextBox.Text,"Packet error"); //unexpected packet error
}
}

void
loop(void)
{

while (1) {
if (serial_data_is_available())
process_packet();
}
}

关于c - 如何在C中转换从串口传入的十六进制值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52993785/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com