2016-10-24 3 views
1

Заранее благодарим за любую помощь, которую любой может предоставить!Новый ЖК-дисплей имеет разную компоновку пикселей, необходим более эффективный метод перевода буфера массива (рабочий метод слишком медленный)

Вот моя проблема: я заменяю устаревший ЖК-дисплей. Оба ЖК-дисплея, новые и старые, имеют ширину 240 на 128 пикселей, но имеют разные пиксельные устройства. Я написал код для перевода массива Screen из OLD в формат NEW, но он слишком медленный. Я надеюсь, что кто-то лучше справится с небольшими манипуляциями, чтобы я мог придумать лучший метод. Ниже представлена ​​компоновка в виде стрелок, которые представляют собой байт в 8 пикселей и какова их ориентация на ЖК-дисплее.

В основном старый ЖК-дисплей размещается в 8 пиксельных байтах в горизонтальных срезах, которые увеличиваются горизонтально и обтекаются, а затем увеличиваются вертикально. Новый ЖК-дисплей расположен в 8 пиксельных байтах в вертикальных срезах, которые увеличиваются горизонтально и обтекаются, а затем увеличиваются вертикально.

Я пытаюсь визуализировать оба устройства со стрелками, представляющими 8-пиксельные байты, как вертикальные или горизонтальные стрелки, указывающие в направлении увеличения битов. Каждая стрелка в обоих представлениях представляет собой один байт или 8 пикселей.

Здесь расположение старого ЖК-дисплея: 30 байт по 128 байт для 30,720 бит или пикселей 240 битов по горизонтали составляет 30 байтов 128 байт вертикальные Old LCD

Здесь расположение нового ЖК-дисплея: 240 байт по 16 байт для 30,720 бит или пикселей 128 бит вертикали в 16 байт 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; 
    } 
} 
+2

Почему вы отмечаете два языка? Вы только пишете в одном из них. –

+0

Попробуйте * вставить * или вставить код 'isBitSet' в местах. Изменение путей выполнения замедляет работу процессора. –

+0

компилятор уже может это сделать, но нет необходимости вычислять 'newbyte_offset * 1920' 8 раз .. просто сделайте это один раз. Возможно, вы могли бы предварительно вычислить '240 * x', а затем просто добавить правильный. – yano

ответ

0

Что вам нужно, это функция, которая может перенести блок 8х8 битов быстро, то вы можете запустить его на всех 480 блоков в вашем дисплее.

void transpose8x8bits(UBYTE * block, UBYTE * result) 
{ 
    int bit; 
    for (bit = 7; bit >= 0; bit--) 
    { 
     result[7-bit] = (((block[0] >> bit) & 1) << 7) | 
         (((block[1] >> bit) & 1) << 6) | 
         (((block[2] >> bit) & 1) << 5) | 
         (((block[3] >> bit) & 1) << 4) | 
         (((block[4] >> bit) & 1) << 3) | 
         (((block[5] >> bit) & 1) << 2) | 
         (((block[6] >> bit) & 1) << 1) | 
         ((block[7] >> bit) & 1); 
} 
+0

Спасибо, Марк, это похоже на то, что мне нужно. Я попробую его и отправлю обратно об улучшении. –

+0

Я попытался опросить ваш ответ, но он говорит, что мой представитель слишком низок, чтобы его пересчитать. –

+0

@CharlesNuzum не волнуйтесь, это сработает в конце. В конечном итоге вы можете нажать на галочку, чтобы показать, что это принятый ответ, но я бы этого не сделал, пока вы не узнаете, что он работает хорошо. –

1

Вот новый код, основанный на очень полезное предложение от Марка 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; 
     } 
    } 

Это дает по крайней мере, порядок улучшения величины, которая является полностью работоспособным для моей задачи; нет чрезмерной лаги. Хотя я открыт для дальнейших оптимизаций, которые каждый мог бы предложить. Я уверен, что моя реализация идеи Марка далеко не оптимизирована. Еще раз спасибо!

+0

Ах, я вижу свою ошибку сейчас - вам нужно пройти всю линию, а не 8 пикселей. Я рад, что ты это понял! Я бы сменил имя, но это уже не транспонирование 8x8. –

+0

Хороший вопрос об имени, еще раз спасибо! –