用C解析和读取数据帧?

2023-12-15

我正在编写一个从Linux上的串口读取数据的程序。 数据由另一台设备发送,帧格式如下:

|start | Command | Data               | CRC  | End |
|0x02  | 0x41    | (0-127 octets)     |      | 0x03|
----------------------------------------------------

数据字段包含 127 个八位位组,如图所示,八位位组 1,2 包含一种类型的数据;八位位组 3,4 包含另一个数据。我需要获取这些数据

我知道如何在Linux中向串行端口写入和读取数据,但这只是写入和读取一个简单的字符串(例如“ABD”)

我的问题是我不知道如何解析上述格式的数据帧,以便我可以:

  • 获取数据字段中八位字节 1,2 中的数据
  • 获取Data字段中八位字节3,4的数据
  • 获取CRC字段的值来检查数据的一致性

下面是在 Linux 中从串行端口读取和写入简单字符串的示例片段代码:

int writeport(int fd, char *chars) {
    int len = strlen(chars);
    chars[len] = 0x0d; // stick a <CR> after the command
    chars[len+1] = 0x00; // terminate the string properly
    int n = write(fd, chars, strlen(chars));
    if (n < 0) {
        fputs("write failed!\n", stderr);
        return 0;
    }
    return 1;                                                                                                           
}

int readport(int fd, char *result) {
    int iIn = read(fd, result, 254);
    result[iIn-1] = 0x00;
    if (iIn < 0) {
        if (errno == EAGAIN) {
            printf("SERIAL EAGAIN ERROR\n");
            return 0;
        } else {
            printf("SERIAL read error %d %s\n", errno, strerror(errno));
            return 0;
        }
    }                    
    return 1;
}

有人有什么想法吗?


result是一个数组chars,1 个八位位组宽。

读取八位字节n use:

char octet_n = result[n];

因此,要做你想做的事,你需要:

// skip the start and command fields
char *data_field = result + 2; 

int octet_1_2 = data_field[1] | (data_field[2] << 8);
int octet_3_4 = data_field[3] | (data_field[4] << 8);

// crc is at byte 128 + 2 = 130
int crc = result[130];

Edit:这一行的解释:

int octet_1_2 = data_field[1] | (data_field[2] << 8);

您想要将两个连续的八位字节读入一个 16 位字:

            1
       bits 5        8 7       0
            --------------------
octet_1_2 = | octet 2 | octet 1|
            --------------------

所以你想取出八位字节 1 的位 7:0 并将它们放入octet_1_2:

octet_1_2 = data_field[1];

然后你想取出八位位组 2 的位 7:0 并将它们放入八位位组 2 的位 15:8 中octet_1_2。您可以通过将八位字节 2 8 位向左移动来完成此操作,并且OR将结果代入octet_1_2:

octet_1_2 |= data_field[2] << 8;

这两行可以合并为一行,就像我上面所做的那样。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用C解析和读取数据帧? 的相关文章

  • 生成多个随机数

    我想生成 25 个唯一的随机数并将它们列在控制台中 数字的长度应至少为 10 个字符 有什么简单的方法可以做到这一点吗 尝试将数字构建为字符串 并使用 HashSet 确保它们是唯一的 Random random new Random Ha
  • 深拷贝和动态转换 unique_ptr

    假设我有一个如下所示的类 class A virtual A class B public A class C public A 我还有一个 unique ptr 向量 它是这样声明的 std vector
  • NDK 应用 onDestroy 清理 - 如何 DetachCurrentThread

    因此 如果我们连接 我们必须在完成后分离线程 对吗 JNIEnv get jni env JNIEnv res JAVA VM gt GetEnv void res JNI VERSION 1 6 Using cached JavaVM J
  • 将公历日期转换为儒略日期,然后再转换回来(随着时间)

    我正在编写一个程序 必须将当前的公历日期和时间转换为儒略日期 然后再转换回公历门 最终我需要添加能够添加年 月 日 小时 分钟和秒的功能 但我需要先解决这部分问题 现在我已经从公历日期转换为儒略日期 所以从逻辑上讲 我觉得我应该能够以某种方
  • 平滑手绘曲线

    我有一个允许用户绘制曲线的程序 但这些曲线看起来不太好 它们看起来摇摇欲坠 而且是手绘的 所以我想要一种能够自动平滑它们的算法 我知道平滑过程中存在固有的模糊性 因此它不会每次都完美 但这种算法似乎确实存在于多个绘图包中 并且它们工作得很好
  • PyPI 上的轮子平台约束有什么限制吗?

    是否有任何地方 PEP 或其他地方 声明关于 Linux 轮子上传范围的限制 PyPI http pypi io 应该有 具体来说 上传是否被认为是可接受的做法linux x86 64轮子到 PyPI 而不是manylinux1 x86 6
  • 使用 inotify 的正确方法是什么?

    我想使用inotifyLinux 上的机制 我希望我的应用程序知道文件何时aaa被改变了 您能给我提供一个如何做到这一点的示例吗 文档 来自监视文件系统活动 inotify https developer ibm com tutorials
  • ContentDialog 未与 UWP 中心对齐

    据我所知 ContentDialog的默认行为应该是使其在 PC 上居中并在移动设备上与顶部对齐 但就我而言 即使在 PC 上我也将其与顶部对齐 但我不明白发生了什么 我正在使用代码隐藏来创建它 这是我正在使用的代码片段 Creates t
  • 将 dataGridView 中选定的行作为对象检索

    我有一堂这样的课 public partial class AdressBokPerson public long Session get set public string F rnamn get set public string Ef
  • Monotouch全局异常处理

    我在野外发现了一只令人讨厌的虫子 但我无法确定它的具体情况 有没有办法拥有全局 Try Catch 块 或者有办法处理 Monotouch 中未处理的任何异常 我可以包起来吗UIApplication Main args 在 try cat
  • 如何将STL容器数据转储到gdb中?

    我无法在 gdb 中转储 STL 无序映射容器值 变量类型是 std unordered map var 我的 gdb 版本 7 7 1 GDB配置 configure host x86 64 linux gnu target x86 64
  • 应用程序处于中断模式。您的应用程序已进入中断状态,

    我发现自己遇到了同样的问题here https stackoverflow com questions 36204009 disable break mode page in vs2015 我在 dll 中使用 Windows 窗体 这是针
  • 调用异步方法在视图模型的构造函数中加载数据有警告

    我的视图包含一个 ListView 它显示来自互联网的一些数据 我创建一个异步方法来加载数据并在我的视图模型的构造函数中调用该方法 它有一个警告提示我现在使用await关键字 还有其他解决方案可以在构造函数中异步加载数据吗 有几种可以应用的
  • 如何从外语线程调用Python函数(C++)

    我正在开发一个程序 使用 DirectShow 来抓取音频数据 媒体文件 DirectShow 使用线程将音频数据传递给回调 我的程序中的函数 然后我让该回调函数调用另一个函数 Python 中的函数 我使用 Boost Python 来包
  • 在 C# 中使用命名空间别名有什么好处? [复制]

    这个问题在这里已经有答案了 使用命名空间别名有什么好处 仅仅是为了简化编码吗 仅当与类发生冲突时我才使用名称空间别名 对我来说 这根本没有简化 我的意见是 如果没有必要 就不要使用
  • Gremlin.net 文本包含等效项

    我正在使用 Gremlin net 库连接到 janus 图形服务器 我使用 cassandra 和弹性搜索进行数据存储和索引 在我使用的 gremlin 语言和 gremlin 控制台中文本包含在属性的文本中进行搜索 我正在使用混合索引
  • 选择合适的IDE

    您会推荐使用以下哪种 IDE 语言来在 Windows 下开发涉及识别手势并与操作系统交互的项目 我将使用 OpenCV 库来执行图像处理任务 之后 我将使用 win32 API 或 NET 框架与操作系统交互 具体取决于您建议的工具 性能
  • 卸载程序

    我正在尝试使用此代码卸载程序 但它似乎不起作用 我尝试过其他答案 但似乎也不起作用 有人可以帮助我吗 我正在尝试按给定名称 displayName 卸载该程序 例如 我给出 displayName Appname 那么此代码应该从我的计算机
  • 当我的进程被终止时到底会发生什么?

    我有一个包含本机代码和托管代码的混合进程 在 Windows Server 2003 上运行 当我从进程资源管理器中终止进程时 它会进入 100 cpu 的状态 并在消失之前保持这种状态一段时间 有时甚至 10 分钟 在此期间我无法 杀死
  • 实体框架代码首次日期字段创建

    我正在使用实体框架代码优先方法来创建我的数据库表 下面的代码 创建一个DATETIME数据库中的列 但我想创建一个DATE柱子 DataType DataType Date DisplayFormatAttribute ApplyForma

随机推荐

  • log4net.ThreadLogicalContext 和 log4net.ThreadContext 有什么区别

    不太明白官方文档的解释 逻辑线程可以从一个托管线程跳转到另一个托管线程 ThreadContext 和 ThreadLogicalContext 有什么区别 有人可以详细说明一下吗 Thanks 我应该回去并将其添加到我自己的问题中 Ste
  • 无法导入/配置 Qt 项目

    我已将以下 GitHub 项目克隆到我的硬盘上 https github com leozide leocad 我还安装了 Qt Creator 4 5 0 但是 当我尝试在 Qt Creator 中加载项目时 它说没有有效的 套件 并且不
  • 实现 PCIe Linux 设备驱动程序(想要从内核驱动程序访问我的卡寄存器)

    我正在编写一个设备驱动程序来访问 PCIe 卡上 FPGA 中的内存 该卡启动并被探测 发现 proc iomem 80000000 840fffff PCI Bus 03 80000000 83ffffff 0000 03 00 0 84
  • 也许使用 JOIN 选择 65 年内的日期范围?

    我正在尝试在 PHP 发布脚本上提取查询 该脚本将提取信息 SELECT id FROM leads WHERE status Passed AND campaign id 22d0cf4f 0f81 28b1 d8dc 4f046bd1d
  • 移动菜单打开和关闭按钮在 Chrome 中显示,但在 Safari 中不显示

    我们的移动菜单在 Pixel 5 上的 Chrome 和 Firefox 中运行良好 在 iPhone 5s 我唯一的 iPhone iPad Mini 2 和较旧的 iPad 上 汉堡菜单打开和关闭图标不显示 在 Chrome 和 Fir
  • 如何从 Android Studio 手动重启 ADB

    我之前在 Android Studio 上开发过 Android 应用程序 一切正常 我在真实设备上工作 Android Studio 可以毫无问题地识别它 突然 当我退出 android studio 并断开连接并重新连接我的设备时 它不
  • 使用鼠标位置旋转玩家的功能是基于鼠标距离而不是位置

    我遵循了 Unity 论坛上关于如何根据鼠标位置旋转对象的答案 该代码可用于更改旋转 但它使用一些其他参数来旋转对象 如您在本记录中看到的 这是我的鼠标检测和位置编辑代码 来自Game cs s update 功能 playerLocati
  • java.lang.illegalargumentexception url 中存在非法字符

    我想请求网络服务我的参数是这样的 urlString http ip autodownload andro php key apps apk 2 bla bla bla public void getRequest String Url T
  • 如何在不改变IGrouping类型的情况下对它进行排序?

    我有一个 IGrouping 类型的对象 并且希望在不更改对象类型的情况下对组内的元素进行排序 换句话说 我有 var tmp group OrderBy x gt x with group存在类型IGrouping
  • 从 Firebase 中删除特定用户

    有没有办法从 firebase 获取特定用户帐户然后将其删除 例如 I need a means of getting a specific auth user var user firebase auth getUser uid Note
  • Objective-C 中的鼠标按下事件

    我知道这个问题以前被问过很多次 但对我来说没有任何作用 下面的代码根本不会做任何事情 void mouseDown NSEvent event NSLog It worked 我尝试了很多不同的方法来使其发挥作用 包括创建自定义NSEven
  • typedef 模板声明的替代方案

    我正在努力实现 namespace NTL typedef std valarray vector 通过标准 C 我知道这是不允许的 但我需要一种快速且简单的方法 无需重新实现所有函数 运算符 重载等 来获取模板 typedef 我现在正在
  • 如何使用 C# 从 URL 下载 ZIP 文件?

    我想从某个网址下载 ZIP 文件 当我打开浏览器并输入 URL 时 浏览器会直接开始下载 ZIP 文件 但是我想要的是使用 C 代码自动执行此操作 我尝试过以下代码 private void btnDownload Click object
  • python 绘制多重图

    我尝试使用 graphviz 在 Python 中绘制多重图 现在我可以用 Python 绘制常用的图表 如下所示 import pygraphviz as pgv G pgv AGraph G add node a G add node
  • 空手道-如何仅在失败的情况下自动重新运行[重复]

    这个问题在这里已经有答案了 空手道中是否有任何方法可以在同一执行中自动仅重新运行 UI 测试自动化失败的场景 甚至在 API 中 我使用 gradle 作为构建工具 这是我这边的要求 如果任何测试失败 应该再次重试 如果我们可以在每个功能场
  • Firestore - 使用数组添加对象

    一整天都在这里用这个东西自杀 我正在上两门课 系和文章 export class Department articals Artical moms number id string constructor and export class
  • 如何使用 jQuery 获取、操作和替换文本节点?

    这是我的代码 li class det price a href designer customize 278258 dpid 1 Printing a from 10 li 我在任何给定页面上都有大约十五个这样的块 我想获取文本节点 来自
  • 从 ANT 启动 Eclipse 运行配置

    我正在将 Orion 服务器用于基于 Java 的 Web 应用程序 我有一个运行配置 可以使用正确的类路径和所有必要的配置启动 Orion 我还有几个 ANT 脚本用于将文件复制到构建路径 我想创建一个 ANT 脚本来关闭 Orion 复
  • 如何用Python从LDA模型生成词云?

    我正在对报纸文章进行一些主题建模 并使用 Python3 中的 gensim 实现了 LDA 现在我想为每个主题创建一个词云 使用每个主题的前 20 个单词 我知道我可以打印单词 并保存 LDA 模型 但是有没有办法只保存每个主题的顶部单词
  • 用C解析和读取数据帧?

    我正在编写一个从Linux上的串口读取数据的程序 数据由另一台设备发送 帧格式如下 start Command Data CRC End 0x02 0x41 0 127 octets 0x03 数据字段包含 127 个八位位组 如图所示 八