如何通过多字节数组移位一个字节

问题描述 投票:1回答:2

我正在研究包含15层的LED塔,每层包含4个字节(32个LED)。我希望能够从右向左移动一个字节。然而,存在多个字节的问题,无法弄清楚如何连续转换移位。

附加信息:

void Invert_Display(void){
for (int y = 0; y < LAYERS; y++){
    for (int x = 0; x < BYTES; x++){
        LED_Buffer[y][x] ^= (0b11111111);
    }
}
Update_Display();

UpdateDisplay函数如下:

void Update_Display(void){

    while(!TRMT);           // Wait until transmission register is empty

    for (int y = 0; y < LAYERS; y++){
        for (int x = 0; x < BYTES; x++){
        TXREG = LED_Buffer[y][x];
        while (!TRMT);
        }
    }

    LE = 1;                 // Data is loaded to the Output latch
    NOP();              
    LE = 0;                 // Data is latched into the Output latch

预期结果如下:enter image description here

c byte bit-shift
2个回答
1
投票

以下代码将向左移动一个字节数组。要移位的位数必须在1到7之间。移位超过7将需要额外的代码。

void shiftArrayLeft(unsigned char array[], int length, int shift) // 1 <= shift <= 7
{
    unsigned char carry = 0;                        // no carry into the first byte
    for (int i = length-1; i >= 0; i--)
    {
        unsigned char temp = array[i];              // save the value
        array[i] = (array[i] << shift) | carry;     // update the array element
        carry = temp >> (8 - shift);                // compute the new carry
    }
}

它的工作原理是存储数组中的旧值。然后通过移动它来更新当前数组元素,并从前一个字节开始逻辑或运算进位。然后计算新进位(原始值的高位)。

可以使用这样的代码调用该函数

unsigned char array[] = { 0x00, 0x00, 0x00, 0xAA };
int length = sizeof(array) / sizeof(array[0]);
shiftArrayLeft(array, length, 1);

这会将数组更改为{ 0x00, 0x00, 0x01, 0x54 }


0
投票

这会将每行打印到屏幕上,将行移动一位。 iteratewrap允许图像移动几个循环。 pattern一次一行地添加到行[7]中,下一个循环将模式扩展到相邻行,因此它们包含相同的模式但右边一位。 图案也向下和向右移动。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>

void show ( unsigned char *bank, size_t size) {
    for ( size_t byte = 0; byte < size; ++byte) {
        unsigned char mask = 0x80;
        for ( int bit = 0; bit < CHAR_BIT; ++bit) {
            mask & bank[byte] ? printf ( "*") : printf ( " ");
            mask >>= 1;
        }
    }
    printf ( "\r");
}

void shiftright ( unsigned char *bank, size_t size) {
    unsigned char carry = 0;
    for ( size_t byte = 0; byte < size; ++byte) {
        unsigned char mask = bank[byte] & 1;
        bank[byte] >>= 1;
        bank[byte] |= carry << ( CHAR_BIT - 1);
        carry = mask;
    }
}

void shiftleft ( unsigned char *bank, size_t size) {
    unsigned char carry = 0;
    for ( size_t byte = size; byte > 0; ) {
        byte--;
        unsigned char mask = bank[byte] & 0x80;
        bank[byte] <<= 1;
        bank[byte] |= carry >> ( CHAR_BIT - 1);
        carry = mask;
    }
}

void shiftdown ( size_t rows, size_t cols, unsigned char (*bank)[cols]) {
    for ( size_t height = rows; height > 1; ) {
        height--;
        memmove ( bank[height], bank[height - 1], cols);
    }
}

int main( void) {
    unsigned char bank[15][4] = { { 0}};

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

    unsigned char pattern = 0xaa;
    for ( int iterate = 3; iterate >= 0; --iterate) {
        for ( int slide = 0; slide < ( sizeof bank[0] * CHAR_BIT); ++slide) {
            for ( int row = 0; row < sizeof bank / sizeof bank[0]; ++row) {
                int wrap = bank[row][0] & 0x80;
                show ( bank[row], sizeof bank[row]);
                shiftleft ( bank[row], sizeof bank[row]);
                if ( wrap) {
                    bank[row][3] |= 1;
                }
                printf ( "\n");
            }
            //add pattern
            unsigned char bit;
            if ( pattern) {//add the pattern to row 7, bit by bit
                bit = 0x80 & pattern;
                if ( bit) {
                    bank[7][3] |= 1;
                }
                pattern <<= 1;
            }
            if ( slide < CHAR_BIT * 2) {//extend pattern to adjacent rows. one bit behind
                unsigned char mask = 0x01;
                for ( int length = 0; length < 7; ++length) {
                    bit = mask & bank[7][3];
                    for ( int height = 0; height < length; ++height) {//add bit to widening lines from center
                        bank[7 - height][3] |= bit;
                        bank[7 + height][3] |= bit;
                        bit >>= 1;
                    }
                    mask <<= 1;
                }
            }
            usleep ( 150000);
            printf ( "\n\n\n\n\n\n\n");
        }
    }
    for ( int iterate = 3; iterate >= 0; --iterate) {
        for ( int slide = 0; slide < sizeof bank / sizeof bank[0]; ++slide) {
            unsigned char wraprow[4];
            memmove ( wraprow, bank[14], sizeof wraprow);
            shiftdown ( sizeof bank / sizeof bank[0], sizeof bank[0], bank);
            memmove ( bank[0], wraprow, sizeof wraprow);
            for ( int row = 0; row < sizeof bank / sizeof bank[0]; ++row) {
                show ( bank[row], sizeof bank[row]);
                printf ( "\n");
            }
            usleep ( 150000);
            printf ( "\n\n\n\n\n\n\n");
        }
    }
    for ( int iterate = 3; iterate >= 0; --iterate) {
        for ( int slide = 0; slide < ( sizeof bank[0] * CHAR_BIT); ++slide) {
            for ( int row = 0; row < sizeof bank / sizeof bank[0]; ++row) {
                int wrap = bank[row][3] & 1;
                show ( bank[row], sizeof bank[row]);
                shiftright ( bank[row], sizeof bank[row]);
                if ( iterate && wrap) {
                    bank[row][0] |= 0x08;
                }
                printf ( "\n");
            }
            usleep ( 150000);
            printf ( "\n\n\n\n\n\n\n");
        }
    }
    printf ( "\n");
    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.