我是靠谱客的博主 纯真硬币,最近开发中收集的这篇文章主要介绍24位ADC数据转换,保存为hex文件,并利用python解析hex文件画图十六进制 -> 十进制十进制 -> 实际电压参考代码利用python解析24位原始AD数据的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) 删除即可。

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

最后

以上就是纯真硬币为你收集整理的24位ADC数据转换,保存为hex文件,并利用python解析hex文件画图十六进制 -> 十进制十进制 -> 实际电压参考代码利用python解析24位原始AD数据的hex文件并绘图的全部内容,希望文章能够帮你解决24位ADC数据转换,保存为hex文件,并利用python解析hex文件画图十六进制 -> 十进制十进制 -> 实际电压参考代码利用python解析24位原始AD数据的hex文件并绘图所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部