Pay*_*ich -1 c embedded binary hex
我正在编写一个嵌入式系统程序,它通过SPI从外部ADC接收24位数据,并将数据存储在整数数组中.那部分是有效的.为了使数据有用,我需要以二进制或十六进制形式连接每个字节并除以0x7FFFFFF.这是我遇到麻烦的地方.例如,我可能会通过SPI接收一个如下所示的数据数组:
data_buffer = { 24 , 17 , 140 };
Run Code Online (Sandbox Code Playgroud)
又名
data_buffer = { 0b00011000 , 0b00010001 , 0b10001100 };
Run Code Online (Sandbox Code Playgroud)
又名
data_buffer = { 0x18 , 0x11 , 0x8C };
Run Code Online (Sandbox Code Playgroud)
我需要用这个值来连接每个元素来得到这样的东西:
data_value = 0x18118C
Run Code Online (Sandbox Code Playgroud)
然后将该值除以0x7FFFFF,以使其在我的程序中有用.在这个例子中,我最终想要的值是0x18118C/0x7FFFFF = 0.188
我该怎么做呢?
对不起,我没有提供更多代码,老实说我不知道从哪里开始.
将三个字节组合成一个24位(实际上是32位)值是C的按位运算符的直接应用.这是一个冗长的"纵向"形式:
unsigned char data_buffer[] = { 24 , 17 , 140 };
unsigned long int data_value = 0;
data_value |= data_buffer[0];
data_value <<= 8;
data_value |= data_buffer[1];
data_value <<= 8;
data_value |= data_buffer[2];
Run Code Online (Sandbox Code Playgroud)
我可能会用更紧凑的形式写它:
unsigned long int data_value = 0;
data_value |= data_buffer[0];
data_value = (data_value << 8) | data_buffer[1];
data_value = (data_value << 8) | data_buffer[2];
Run Code Online (Sandbox Code Playgroud)
或者你可以按照其他顺序进行,可以这么说:
unsigned long int data_value = 0;
data_value |= (unsigned long)data_buffer[0] << 16;
data_value |= data_buffer[1] << 8;
data_value |= data_buffer[2];
Run Code Online (Sandbox Code Playgroud)
(这里你需要一个额外的演员阵容,如果你使用的是16位处理器,那么普通data_buffer[0] << 16
会将所有的位移掉并丢失它们.)
或者你可以一次完成所有工作:
unsigned long int data_value =
((unsigned long)data_buffer[0] << 16) |
(data_buffer[1] << 8) |
data_buffer[2];
Run Code Online (Sandbox Code Playgroud)
无论如何,您可以进行所需的划分:
float float_value = (float)data_value / 0x7FFFFF;
Run Code Online (Sandbox Code Playgroud)
(您可能希望使用double
而不是float
.或者根据嵌入式环境的限制,您可能根本不希望使用这样的直接浮点;您没有说.)
当我打印这些时,我得到你要求的值:
printf("data_value = %#lX, float_value = %f\n", data_value, float_value);
Run Code Online (Sandbox Code Playgroud)
收益率:
data_value = 0X18118C, float_value = 0.188036
Run Code Online (Sandbox Code Playgroud)
附录:我忘记提到的一件事是,为了使这些技术正常工作,输入数据(即示例中的数组)的类型通常非常重要.如果不是 - 例如,如果它是普通的,在大多数机器上签名 - 你通常最终会出现令人虚弱的符号扩展问题.例如,如您所知,您的值140是十六进制数,但解释为带符号的 8位数,它是-116.当它参与其他整数的表达式时,它通常会被符号扩展为或者,这当然不是你想要的.(正如SteveB的回答中所建议的那样,你可以使用额外的掩码来解决这个问题,但这很麻烦.使用起来要简单得多.)data_buffer
unsigned char
char
0x8c
0xff8c
0xffffff8c
& 0xff
unsigned char