在Matlab

时间:2016-12-06 15:11:27

标签: matlab casting serial-port bit-shift adc

我通过串行从24位ADC接收EEG数据。 ADC数据以3个字节从MSB发送到LSB。完整数据包为21个字节:

第一个字节是起始字节 - 0xFF(十进制255) 然后是包号字节。 然后接下来的3个字节是分成MSB LSB2 LSB1的24位ADC值 我可以很好地解析数据,但是重新构造一个2号补码签名的int32号会导致问题。我得出的价值肯定不能反映ADC应该给出的内容。

下面是读取和解析504个样本的行(它给出了24个ADC值(504个样本/ 21个字节= 24个值))。我尝试了uint8而不是uchar,结果相似(当我尝试int8时,我得到一个无效的指定精度错误)。

comEEGSMT = serial(com,'BaudRate',3000000);
fopen(comEEGSMT);
rawData(1:504) = fread(comEEGSMT, 504, 'uchar');
fclose(comEEGSMT);
startPackets = find(rawData == 255);
bytes = rawData([startpackets+2 startpackets+3 startpackets+4]);

我尝试了以下方法来重建值:

ADC_value = bytes(:,1)*256^2 + bytes(:,2)*256 + bytes(:,3);

以下行是将上述数字转换为伏特的公式:

ADC_value_volts = ADC_value*(5/3)*(1/(2^32));

值在4000 - 8000微伏范围内,值大幅跳跃。这些值应该在200 - 600微伏的范围内,变化很小。

我发现了其他与类似问题相关的问题,但是没有成功尝试提出的解决方案,例如在以下链接中:

https://uk.mathworks.com/matlabcentral/answers/137965-concatenate-3-bytes-array-of-real-time-serial-data-into-single-precision

任何帮助都会非常感激,因为我已经坚持了很长时间。

谢谢Mark

1 个答案:

答案 0 :(得分:1)

从ADC_value开始为int32,值为0,然后:

ADC_value |= MSB << 16;
ADC_value |= LSB2 << 8;
ADC_value |= LSB1;

然后,为了找出相应的伏特值,假设你的ADC有一个参考电压VREF,单位是伏特(例如5.0V):

ADC_value_volts = (ADC_value * VREF)/2^24

因为您的转换器是24位,而不是32位。 注意上面的表达式是C语言等价的,而不是Matlab。

编辑:

ADC data sheet告诉我们可以为以下值设置PGA增益: 1,2,4,6,8,12,24,每个通道的一个值。 测量的FSR(满量程范围)为:(2*VREF)/Gain = 5/3,增益= 6, (eq。(5)page 23)所以这必须在计算伏特的表达式中加以考虑 值。 (如果您可以访问硬件并且可以制作一些硬件,则可以验证这些 测量)。

ADC产生的数据已经是二进制补码,二进制形式,24位。 奇怪的是数据表计数从1开始的位,而不是0,所以这个 这就是为什么用“17”代替16代替 - 实际上这是编码的16。 (见图47,第42页)。

因此ADC_value_volts的计算公式应为:

ADC_value_volts = (AC_value * FSR/(2^23))/3 (1LSB=FSR/(2^23), pg.37)

如果原始的其他计算/修改,这些必须由提供者解释。 如果提供者不友好,值得改变......