如何通过环绕将4字节数组全部移位32位?

时间:2019-04-23 21:47:50

标签: c multidimensional-array embedded pic

我正在尝试实现动画平移功能,该功能允许我将所有(LAYERS * BYTES)LED重叠32位。我只能用字节移位来做到这一点,但这不是我所需要的。

为了更好地理解这个主意,下面提供了图片:

enter image description here

我将其绘制出来,其中C是一个进位位,移到下一个字节的开头,而4个字节的最后一个元素分配给第一个字节的第一个元素。

可能有更好的方法来实现此目的。感谢您提前提供的帮助。

其他信息:

void Shift_Right_Byte(void){
    for (int row = 0; row < LAYERS; row++) {
            for (int col = 0; col < BYTES; col++) {
                LED_Buffer[row][col] = LED_Buffer[row][(col + 1) % BYTES];
            }
        }
        delay(1000);
}

新功能:

void layer_rotate_right(void) 
{
    for (int row = 0; row < LAYERS; row++) {
        unsigned char carry = LED_Buffer[row][BYTES - 1] << 7 ;
        for( int i = 0; i < BYTES; i++ )
        {   
            unsigned char next_carry = LED_Buffer[row][i] << 7 ;
            LED_Buffer[row][i] = (LED_Buffer[row][i] >> 1) | carry ;
            carry = next_carry ;
        }
    }
}

2 个答案:

答案 0 :(得分:2)

如果层始终为4个字节的一种具体解决方案是将字节打包到uint32_t中并对其应用旋转。

给出:

void layer_rotate_right( uint8_t layer[4] ) 
{
    // Pack...
    uint32_t word = layer[0]<<24 | layer[1]<<16 | layer[2]<<8 | layer[3] ;

    // Rotate...
    uint32_t rotated = word << 31 | word >> 1 ;

    // Unpack...
    layer[0] = rotated >> 24 ;
    layer[1] = (rotated >> 16) & 0xff ;
    layer[2] = (rotated >> 8) & 0xff ;
    layer[3] = rotated & 0xff ;
}

然后:

for (int row = 0; row < LAYERS; row++) 
{
    layer_rotate_right( LED_Buffer[row] )
}

装箱和拆箱比较麻烦。只要具有适当的字节序和对齐方式,您就可以摆脱转换,但是作为解决方案,它无法缩放。

对于任何大小的字节数组,更通用的解决方案是:

void layer_rotate_right( uint8_t* layer, int len ) 
{
    uint8_t carry = layer[len - 1] << 7 ;
    for( int i = 0; i < len; i++ )
    {   
        uint8_t next_carry = layer[i] << 7 ;
        layer[i] = (layer[i] >> 1) | carry ;
        carry = next_carry ;
    }
}

然后:

for (int row = 0; row < LAYERS; row++) 
{
    layer_rotate_right( LED_Buffer[row], BYTES )
}

答案 1 :(得分:1)

另一种方法是使用联合。例如,

typedef union{
    uint8_t buff8[4];
    uint32_t buff32;
}led_buffer_t;

然后使用它来声明LED_Buffer(例如led_buffer_t LED_Buffer[LAYERS] = {0};

然后在此处使用循环移位答案:Circular shift in c

我在这里尝试过:https://onlinegdb.com/ByfcMY1sE