将内部变量序列化到i2c



我目前正致力于在几个微控制器(Atmega32)之间创建I2C网络,首先我只是试图在从机和主机之间连接它。我有一个传感器连接到slave,它以无符号int格式给我数据,但数据传输以无符号char格式发生。

我不知道如何在一个以无符号char格式工作的网络中传输以无符号int格式获得的数据。

将十进制数除以2,直到其变为0,并将每个除数的余数保存在数组&反转数组以获得该十进制数的二进制数。假设你的十进制数是7。

7/2=3 remainder=1
3/2=1 remainder=1
1/2=0 remainder=1
So array=11100000
After reverse binary is= 00000111

在c中是这样的:

int des=7,binary[8],indexNo=0;
while(des!=0)
{
    binary[indexNo]=des%2;
    des/=2;
    indexNo++;
}
now inverse the binary[] or you can directly start indexNo from last index
(Ex: 8)

听了你的评论,我现在明白多了。您需要的不是二进制到ascii字符串的转换,而是二进制传输格式。

注意这是一个xy问题:请求X,但是需要y。

为此,您只需在每个数据元素之前加上类型前缀(字节)。

// This enum must be known to all transmitters and receivers, of course!
typedef enum {
    DATA_TYPE_uint16 = 0,
    DATA_TYPE_int8,
    ...
} DataType;
因此,例如,uint16_t被传输为:
uint8_t tx_buffer[MAX_BUFFER_SIZE];
uint16_t internal_var1;
...
tx_buffer[0] = DATA_TYPE_uint16;            // type being sent
tx_buffer[1] = (uint8_t)internal_var1;      // lower 8 bits
tx_buffer[2] = (uint8_t)(internal_var1>>8); // lower 8 bits
send_i2c(3, tx_buffer);

接收器的代码:

uint8_t rx_buffer[MAX_BUFFER_SIZE];
uint16_t internal_var1;
// read the next frame (i2c delimts frames automatically)
receive(MAX_BUFFER_SIZE, rx_buffer);  // do not overflow the buffer
switch ( rx_buffer[0] ) {
    case DATA_TYPE_uint16:
        internal_var1 = (uint16_t)rx_buffer[1] | (uint16_t)rx_buffer[2] << 8;
        break;
    ...
    default:
        // invalid frame format (error handling!)
}

请注意,发送的数据是小端序(最低字节优先)。这是嵌入式编程中的常见做法。它比将每个比特打包成一个字节要紧凑得多(即发送速度更快),并且在任何一方都更容易更快地处理。

你可以扩展到任何类型的数据类型。所以你可以通过打包它的单个元素来发送一个结构体作为单一类型,就像我在uint16_t中展示的那样。不要尝试以二进制字符串的形式传递数据!这是通信协议中的灾难。

这实际上被称为"封送"(序列化结构化数据)。注意只使用可移植操作

大多数通信物理层都是面向字节的——这并不妨碍传输更大的数据结构或类型。

例如,将16位整数拆分和重组为字节组件:

word8_msb = (word16 >> 8) ; 
word8_lsb = (word16 & 0xFF) ; 
word16 = (word8_msb << 8) | word8_lsb) ;

此外,如果两个节点的字节顺序恰好相同,您可以简单地将数据强制转换为字节数组:

发送一个整数数组作为字节流:

uint16_t integer_data[] = { 1u ,2u ,3u ,4u } ;
uint8_t byte_data = (uint8_t*)integer_data ;
size_t data_length_bytes = sizeof(integer_data) * sizeof(*integer_data) ;
for( int i = 0; i < data_length_bytes )
{
    send_byte( byte_data[i] ) ;
}

接收到整数数组的字节流:

uint16_t integer_data[4] ;
uint8_t byte_data = (uint8_t*)integer_data ;
size_t data_length_bytes = sizeof(integer_data) * sizeof(*integer_data) ;
for( int i = 0; i < data_length_bytes )
{
    byte_data[i] = read_byte() ;
}

在大多数情况下,然而,它不是那么简单;至少需要某种协议来指示数据或同步的开始(因此数据不会错位),并且通常数据在数据包中传输,包含数据和元数据,以确保可靠的数据传输。

最新更新