24位ADC数据转换,保存为hex文件,并利用python解析hex文件画图

 目前有许多ADC芯片都是24位精度的,这个位数稍显尴尬,因为在常用的变量类型中,有8bit、16bit、32bit,唯独没有24bit,这就导致我们在很多情况下,需要自己敲代码去处理这个24bit的有符号数据。

十六进制 -> 十进制

 在开始之前,需要清楚计算机中是如何表示负数的。

 对于有符号24位整型值,0x000001~0x7FFFFF是对应十进制的正数区间0~8388607,达到正的最大值之后,再往后加1,就来到了负数的地盘。负数有些不同,0x800000表示的是负的最大值,~0xFFFFFF则对应十进制的负数区间~-1。如下表:

 十六进制数从0x000000开始逐渐增大,表示的十进制也是从0开始逐渐增大。一直增大到0x7FFFFF时,来到了正负数的分界点。0x7FFFFF是正数的最大值,再往后+1,就变成了0x800000,这是负数的最小值。十六进制数继续增大,表示的十进制负数也随之增大,一直增大到0xFFFFFF时,这个十六进制数的范围到了尽头,对应十进制的值也到了负数区间的尽头:-1。具体值见下表:

十六进制十进制
00 00 000
00 00 011
…………………………………
7F FF FF8388607
80 00 00-8388608
80 00 01-8388607
…………………………………
FF FF FF-1

 以上是对24bit有符号数据的描述,32bit有符号数据的正负区间规律类似,只不过正负分界点多了8位,变成了0x7F FF FF FF和0x80 00 00 00。

 在大部分编译器中,并没有24bit这样一个尴尬的数据类型,因此我们需要用一个32bit的变量来将就一下,比如在大部分X86、X64的PC,以及32位单片机中的int,下面我们就以int为例。

 int是32位(XX XX XX XX),而我们的数据是24位(XX XX XX),最高位缺了一个字节(XX),而这个字节恰恰决定了数据的正负号。因此,我们在用32位变量来装24位数据时,为了确保不把符号弄丢,要进行补位:

  • 如果24位数据的最高位大于等于0x80,表明这是一个负数,要在前面补上一个8个1(0xFF)构成32位变量。
  • 如果24位数据的最高位小于0x80,表明这是一个正数,在前面补上一个8个0(0x00)即可。

十进制 -> 实际电压

 将十六进制转换到我们熟悉的十进制后,还需要将其转换成实际的电压值。一些24位AD芯片的手册上是这样写的:

在这里插入图片描述

 读上表,可以看到该芯片的测量范围Vrang是单倍参考电压(有些芯片可能是二倍参考电压,或者参考电压减去几伏,需要注意),不难得到换算公式:实际电压 =十进制原始值* 测量范围/0x7FFFFF

参考代码

 以下代码是在STM32上通过SPI实现24位AD数据的采集,并将其转换为实际值(单位mV)的过程。

//AD_DEC的数据类型应定义为32位有符号型。
//int对于大部分X86、X64的PC,以及32位单片机来说都是32位
int AD_DEC;
double AD_mV;

long double get_AD_data()
{
  char data1,data2,data3;
  //……
  //其余代码略
  //……
  
  //读24位数据(高位在前)
  HAL_SPI_Receive(&hspi1, &data1, 1, 10);
  HAL_SPI_Receive(&hspi1, &data2, 1, 10);
  HAL_SPI_Receive(&hspi1, &data3, 1, 10);
  
  //转换为十进制
  AD_DEC = (unsigned int)(data1<<16)|(data2<<8)|data3;
  //如果大于800000,说明是负数,最高位补一个FF
  if(data1&0x80)
    AD_DEC |= 0xFF000000;

  //十进制转换为mV (这里以测量范围-5V~5V为例) 
  AD_mV = AD_DEC*0.000596046518808;

  return AD_mV;
}

利用python解析24位原始AD数据的hex文件并绘图

 AD采集到数据之后,我们往往想要画出AD数据的变化趋势图来直观地分析问题。

 在一些对采样率要求较高的场景下,我们往往不是保存转换后的实际电压值,因为这样太耗费时间了,而是直接将原始的十六进制数据放进HEX文件,存入大容量的SD卡中。

 接下来就介绍如何使用python解析存有原始24位AD数据的HEX文件,并绘出曲线。

 本文用来举例的hex文件格式如下图所示。前9字节是文件头,存储了一些信息,从第10字节开始,就是一个挨一个密集存放的24位原始数据。

在这里插入图片描述

 在python中,不需要我们亲自处理24bit有符号数据,直接使用int.from_bytes( )即可。因此,整个python代码看起来非常简单。

import matplotlib.pyplot as plt

fin = open('F://bottom-2000-1-1-0-37-41.hex', mode = 'rb')
# 跳过前9字节的文件头。如果你的文件没有文件头,可以删掉下面这一行
fin.seek(9) 
hex_dat = fin.read()
fin.close()

value = []
for i in range(0, len(hex_dat), 3):
  # 读取三个Byte组成一个24bit数
  value.append(0.000596046518808*int.from_bytes(hex_dat[i:i+3], byteorder = 'big', signed = 'true'))

plt.plot(value)
plt.show()

 如果你的hex文件没有前9个字节的文件头,将程序中的fin.seek(9) 删除即可。

 运行结果如下图:
请添加图片描述

  • 2
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 十六进制数据是计算机中常用的数据表示方法之一,其每个数字字符都代表4个二进制。为了方便保存和传输这些数据,我们可以将其保存hex文件hex文件是一种以文本形式保存十六进制数据文件格式。在hex文件中,每2个字符代表一个字节的十六进制值。例如,十六进制值0A代表二进制值0000 1010,而十六进制值FF代表二进制值1111 1111。 保存hex文件的好处是可以轻松地在不同计算机平台上进行数据传输和共享。由于hex文件是文本文件,所以可以直接在任何文本编辑器中打开和编辑。这使得我们可以很容易地查看和修改十六进制数据保存hex文件的过程很简单。首先,将十六进制数据按照每个字节的形式写入到文件中。每个字节都以0x开头,并用空格或其他分隔符隔开。然后,确保文件的扩展名为.hex或者.txt以明确表示其为hex文件。 总之,保存hex文件是一种方便的方式来保存和传输十六进制数据。它可以在不同平台上进行数据传输和共享,并且可以轻松地在文本编辑器中进行查看和修改。 ### 回答2: 16进制数据保存hex文件是一种常见的数据保存方式。它将数据以16进制的形式编码,并将其保存在一个文本文件中。每个字节的数值被表示为0-9和A-F的字符之一。每个字节之间可能会有空格或其他分隔符。 hex文件在许多领域中广泛应用,特别是在计算机软件和硬件开发中。它可以存储程序代码、存储设备的固件、以及各种其他类型的数据保存数据hex文件具有一些优点。首先,hex文件是可读的文本文件,方便人们查看和编辑。其次,hex文件可以很好地保留原始数据的精确性,因为它们没有进行任何压缩或编码处理。此外,hex文件可以跨平台使用,因为几乎所有的计算机系统都可以读取和处理文本文件。 要创建hex文件,我们可以使用各种编程语言或计算机工具。一个常见的方法是使用十六进制编辑器,这些编辑器允许我们在一个界面中查看和编辑hex数据,并将其保存hex文件。 总之,hex文件是一种将数据以16进制编码的文本文件。它在计算机开发和其他领域中被广泛使用,能够保留数据的精确性并方便人们查看和编辑。创建hex文件可以使用各种编程语言或工具。 ### 回答3: 十六进制数据保存hex文件,是通过将十六进制的数据转换成二进制形式,然后按字节(8)进行存储的文件格式。 在一个hex文件中,每一行通常包含16个字节的数据,前面还有一个偏移地址,用来表示每一行数据在存储中的置。一般情况下,每个字节之间会通过空格或者其他分隔符分隔开来。 hex文件保存形式有不同的版本,比如Intel Hex格式和Motorola S-Record格式。这些格式在具体的实现上存在一些差异,但都遵循了将十六进制数据转换为二进制并按字节进行存储的基本原理。 hex文件在实际应用中有广泛的用途,特别是在嵌入式系统开发中。开发人员可以将程序或者固件的机器代码以十六进制的形式保存hex文件中,然后通过一些特定的软件工具,将hex文件烧录到目标设备中。这种方式可以有效地避免因数据传输错误或者格式不匹配等问题而导致的程序烧录错误。 总而言之,hex文件是一种以十六进制数据形式保存并按字节存储的文件格式,它在嵌入式系统开发和数据传输过程中发挥着重要的作用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

河上七月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值