首页 > 解决方案 > 在索引 n 处用 m 次数据填充没有位域的数组

问题描述

我尝试发送最多 8 个字节的数据。前 4 个字节始终相同,涉及定义的命令和地址。最后 4 个字节应该是可变的。

到目前为止,我正在使用这种方法。不幸的是,我被告知在这种情况下不要使用任何 for 循环。

// Construct data
local_transmit_buffer[0] = EEPROM_CMD_WREN;
local_transmit_buffer[1] = EEPROM_CMD_WRITE;
local_transmit_buffer[2] = High(MSQ_Buffer.address);
local_transmit_buffer[3] = Low(MSQ_Buffer.address);

uint_fast8_t i = 0;
for(i = 0; i < MSQ_Buffer.byte_lenght || i < 4; i++){ // assign data
    local_transmit_buffer[i + 4] = MSQ_Buffer.dataPointer[i];
} 

这是我试图解决我的问题的一些测试代码:

#include <stdio.h>

__UINT_FAST8_TYPE__ local_transmit_buffer[8];
__UINT_FAST8_TYPE__ MSQ_Buffer_data[8];


void print_local(){
for (int i = 0; i < 8; i++)
    {
        printf("%d ", local_transmit_buffer[i]);
    }
    printf("\n");
}

void print_msg(){
for (int i = 0; i < 8; i++)
    {
        printf("%d ", MSQ_Buffer_data[i]);
    }
    printf("\n");
}

int main(){
    // assign all local values to 0
    for (int i = 0; i < 8; i++)
    {
        local_transmit_buffer[i] = 0;
    } print_local();

    // assign all msg values to 1
    for (int i = 0; i < 8; i++)
    {
        MSQ_Buffer_data[i] = i + 1;
    } print_msg();

    *(local_transmit_buffer + 3) = (__UINT_FAST32_TYPE__)MSQ_Buffer_data;

    printf("\n");
    print_local();

    return 0;
}

第一个循环用 0 填充 local_transmit_buffer,用 0、1、2 填充 MSQ_Buffer,... local_transmit_buffer -> 0 0 0 0 0 0 0 0 MSQ_Buffer_data -> 1 2 3 4 5 6 7 8

现在我想将 MSQ_Buffer_data 的前 4 个值分配给 local_transmit_buffer,如下所示: local_transmit_buffer -> 0 0 0 0 1 2 3 4

是否有另一种方法可以在不使用 for 循环或 bit_field 的情况下解决此问题?

已解决: 我使用 memcpy 函数解决了我的问题

// uint_fast8_t i = 0;
// for(i = 0; i < MSQ_Buffer.byte_lenght || i < 4; i++){ // assign data
//     local_transmit_buffer[i + 4] = MSQ_Buffer.dataPointer[i];
// } 

// copy a defined number data from the message to the local buffer to send
memcpy(&local_transmit_buffer[4], &MSQ_Buffer.dataPointer, local_save_data_length);

标签: carraysbit-fields

解决方案


  • 要么通过键入每一行手动展开循环,要么简单地使用memcpy. 在这种情况下,没有理由需要抽象层,所以我会编写最合理的代码,这只是手动展开(并摆脱 icky 宏):

    uint8_t local_transmit_buffer [8];
    ...
    local_transmit_buffer[0] = EEPROM_CMD_WREN;
    local_transmit_buffer[1] = EEPROM_CMD_WRITE;
    local_transmit_buffer[2] = (uint8_t) ((MSQ_Buffer.address >> 8) & 0xFFu);
    local_transmit_buffer[3] = (uint8_t) (MSQ_Buffer.address & 0xFFu);
    local_transmit_buffer[4] = MSQ_Buffer.dataPointer[0];
    local_transmit_buffer[5] = MSQ_Buffer.dataPointer[1];
    local_transmit_buffer[6] = MSQ_Buffer.dataPointer[2];
    local_transmit_buffer[7] = MSQ_Buffer.dataPointer[3];
    
  • 不过,为什么不能使用循环并不明显,这看起来不像实际的 EEPROM 编程(开销代码可能会导致打嗝),而只是为它做准备。开始质疑这样的要求。

  • 另请注意,您不应使用__UINT_FAST8_TYPE__but uint8_t。永远不要使用自制类型,但始终使用stdint.h. 但是您不应该将fast类型用于用于 EEPROM 编程的 RAM 缓冲区,因为它永远不允许包含填充。这是一个错误。


推荐阅读