我正在尝试实现动画平移功能,该功能允许我将所有(LAYERS * BYTES)LED重叠32位。我只能用字节移位来做到这一点,但这不是我所需要的。
为了更好地理解这个主意,下面提供了图片:
我将其绘制出来,其中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 ;
}
}
}
答案 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