提前感谢任何人可以提供的帮助!
这是我的问题:我要更换过时的 LCD。新旧 LCD 的像素均为 240 宽 x 128 高,但像素排列不同。 我已经编写了代码将 Screen 数组从旧格式转换为新格式,但速度太慢。我希望有人更擅长位操作,我可以想出更好的方法。下面是一个箭头排列,代表一个 8 像素的字节以及它们在 LCD 上的方向。
基本上,旧 LCD 以 8 个像素字节排列在水平切片中,水平递增并环绕然后垂直递增。 新的 LCD 以 8 个像素字节的形式排列在垂直切片中,水平递增并环绕然后垂直递增。
我试图将表示 8 个像素字节的箭头的两种排列可视化为指向位增量方向的垂直或水平箭头。两种表示中的每个箭头都是一个字节或 8 个像素。
这是旧 LCD 的排列:30,720 位或像素的 30 字节 x 128 字节 240 位水平是 30 字节 128 字节垂直 Old LCD
这是新 LCD 的排列方式:240 字节 x 16 字节,代表 30,720 位或像素 16 字节中的 128 位垂直 水平 240 字节 New LCD
下面是我的翻译代码,可以运行,但速度太慢。它通过新排列的字节递增,找到旧排列中每个字节的每个位的来源。太慢太繁琐,系统滞后,必须有更好的方法!我尝试将所有函数调用更改为内联代码,但没有任何改进。
#define DISPLAY_BUFFER_SIZE 3840 // buffer size in *bytes*
#define HORIZONTAL_PIX 240
#define VERTICAL_ROWS 16
#define VERTICAL_PIX 128
#define HORIZONTAL_COL 30
#define BITS_IN_BYTE 8
UBYTE isBitSet(UBYTE* arr, USHORT bit)
{
USHORT index = bit / 8; // Get the index of the array for byte with this bit
USHORT bitPosition = 7-(bit % 8); // Position of this bit a byte Every byte on the OLD LCD was bit swapped from MSB to LSB so annoyingly this is reversed here
return (arr[index] >> bitPosition & 1) == 1;
}
// main code inside another function
for (i=0; i<DISPLAY_BUFFER_SIZE; i++)
{
newbyte_pos = i % HORIZONTAL_PIX; // Value is 0 to 29. 30 = 240col / 8bits
newbyte_offset = i / HORIZONTAL_PIX; // Value is 0 to 127
new_display_byte = 0x00;
// Bit 0
oldbit_num = (newbyte_offset * 1920) + (240 * 0) + newbyte_pos;
if (isBitSet(buffer_pointer, oldbit_num))
new_display_byte |= 0x01;
// Bit 1
oldbit_num = (newbyte_offset * 1920) + (240 * 1) + newbyte_pos;
if (isBitSet(buffer_pointer, oldbit_num))
new_display_byte |= 0x02;
// Bit 2
oldbit_num = (newbyte_offset * 1920) + (240 * 2) + newbyte_pos;
if (isBitSet(buffer_pointer, oldbit_num))
new_display_byte |= 0x04;
// Bit 3
oldbit_num = (newbyte_offset * 1920) + (240 * 3) + newbyte_pos;
if (isBitSet(buffer_pointer, oldbit_num))
new_display_byte |= 0x08;
// Bit 4
oldbit_num = (newbyte_offset * 1920) + (240 * 4) + newbyte_pos;
if (isBitSet(buffer_pointer, oldbit_num))
new_display_byte |= 0x10;
// Bit 5
oldbit_num = (newbyte_offset * 1920) + (240 * 5) + newbyte_pos;
if (isBitSet(buffer_pointer, oldbit_num))
new_display_byte |= 0x20;
// Bit 6
oldbit_num = (newbyte_offset * 1920) + (240 * 6) + newbyte_pos;
if (isBitSet(buffer_pointer, oldbit_num))
new_display_byte |= 0x40;
// Bit 7
oldbit_num = (newbyte_offset * 1920) + (240 * 7) + newbyte_pos;
if (isBitSet(buffer_pointer, oldbit_num))
new_display_byte |= 0x80;
new_display_buf[i] = new_display_byte;
}
}
最佳答案
这是基于 Mark Ransom 非常有用的建议的新代码:
void transpose8x8bits(UBYTE * block, UBYTE * result)
{
int bit;
for (bit = 7; bit >= 0; bit--)
{
result[7-bit] = (((block[0] >> bit) & 1) << 0) |
(((block[30] >> bit) & 1) << 1) |
(((block[60] >> bit) & 1) << 2) |
(((block[90] >> bit) & 1) << 3) |
(((block[120] >> bit) & 1) << 4) |
(((block[150] >> bit) & 1) << 5) |
(((block[180] >> bit) & 1) << 6) |
(((block[210] >> bit) & 1) << 7);
}
}
//////////////////////////////////////////////////////////////////
// calling code
buf_inx = 0;
for (z=0; z<16; z++) // 128 bits / 8 bit per byte = 16 bytes
{
for (i=0; i<30; i++)
{
transpose8x8bits((buffer_pointer+i+(z*240)), (new_display_buf+buf_inx));
buf_inx += 8;
}
}
这至少提供了一个数量级的改进,这对于我的任务来说是完全可行的;没有更多的过度滞后!尽管我愿意接受任何人建议的进一步优化。我确信我对 Mark 的想法的实现远未得到优化。再次感谢马克!
关于c - 新的 LCD 有不同的像素布局,需要更有效的方法来转换数组缓冲区(工作方法太慢),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40226717/