我正在研究包含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
以下代码将向左移动一个字节数组。要移位的位数必须在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 }
这会将每行打印到屏幕上,将行移动一位。
iterate
和wrap
允许图像移动几个循环。
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;
}