将内部变量序列化为i2c

将内部变量序列化为i2c,c,C,我目前正致力于在几个微控制器(Atmega32)之间创建一个I2C网络,首先,我只是尝试在从机和主机之间建立接口。我有一个传感器连接到从机,它以无符号int格式提供数据,但数据传输以无符号char格式进行 我不知道如何在一个以无符号字符格式工作的网络中传输以无符号int格式获得的数据 任何类型的帮助都会很有帮助。将十进制数除以2,直到变为0,然后将每个除法的余数保存在一个数组中,并将数组反转以获得该十进制数的二进制数。 假设你的十进制数是7 7/2=3 remainder=1 3/2=1 rem

我目前正致力于在几个微控制器(Atmega32)之间创建一个I2C网络,首先,我只是尝试在从机和主机之间建立接口。我有一个传感器连接到从机,它以无符号int格式提供数据,但数据传输以无符号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

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

因此,例如,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!)
}
uint8接收缓冲区[最大缓冲区大小];
uint16\u t内部变量1;
//读取下一帧(i2c delimts帧自动读取)
接收(最大缓冲区大小,接收缓冲区);//不要使缓冲区溢出
开关(rx_缓冲器[0]){
案例数据类型16:

内部_var1=(uint16_t)rx_buffer[1]|(uint16_t)rx_buffer[2]大多数通信物理层都是面向字节的,这不会阻止更大数据结构或类型的传输

例如,将16位整数拆分并重新组装到字节组件中:

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

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

word16=(word8_msb您能为您自己能够完成的部分编写代码吗?使用“&”检查数字的每一位无符号字符已经是二进制的(无符号int也是如此)在您的平台上很可能有8位。如果您想以任何特定形式输出它,您需要将其转换为字符序列。这不是从十进制转换为二进制,而是将int表示为带二进制基数的字符串。而且没有“嵌入式C”语言;它只是C,任何差异或扩展都将特定于您的编译器/目标。可能的重复谢谢…我实际上取二进制[]数组的初始值为0。对于十进制值0,不会出现循环,但二进制值仍然是00000000。这似乎不必要的复杂。请改为使用位运算符。没有“十进制数”。上次我看了一下,大多数计算机都是二进制的。当然,除非他正在编写ENIAC(是否有C编译器可用?)。这可能不适用于负值。请使用unsigned。此外,TO需要的是字符串,而不是int数组。另外:为什么是反向的而不是自顶向下的?具有allo 0的数组仅对第一次调用和本地调用有效(这实际上更有意义)虽然这确实可以将十进制转换为二进制表示形式,但机器已经将所有数据存储在二进制表示形式中;因此,虽然该算法在纸上很好,但在机器上是浪费的-所需的只是显示已经表示数字的位。我们的猜测完全是c没错,这实际上比我以前想做的要容易得多D@RohanNarlanka:有时我擅长猜测……如果你在嵌入式领域工作,你就会习惯它。@RohanNarlanka:我会稍微更新一下我的答案(最后两段)。你说的可移植操作到底是什么意思?@RohanNarlanka:例如:使用操作来提取单个字节。只需遵循我使用的模式。使用带符号整数时也要小心:例如右移可能是符号,也可能不是符号(它们可能与除法不同)。你可能想在谷歌上搜索“c陷阱”。并且只使用
stdint.h
中的类型(重要!请熟悉这一点),至少在准备传输/接收数据时。只要阅读,阅读,阅读,这里的每个人都会给你一些提示。
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() ;
}