Удалось поднять FPS при выводе видео на дисплей, на неожиданную для себя величину: с 12.8 кадров в секунду до 17.9. Поэтому продолжу писать про оптимизацию алгоритма, может кому-то потом пригодится.
Вот тут
Код: Выделить всё
// Отправляем в дисплей пикселы в любом количестве
// рисуются они попиксельно слева направо и сверху вниз
// когда кадр отрисуется то начинает рисоваться следующий поверх
Send_to_lcd( DAT, color ); // Вывод первого пиксела
Send_to_lcd( DAT, color ); // второго
Send_to_lcd( DAT, color ); // третьего
Вот сама процедура Send_to_lcd
Код: Выделить всё
void Send_to_lcd (char RS, char data) {
unsigned char mm;
byte_to_send = data;
LCD_CLK=0;
LCD_DATA=0;
if ((RS_old != RS) || (!RS_old && !RS)) { // проверяю старое значение RS и тут (мол если прутся одни команды то дергаем CS)
LCD_CS=1;
LCD_RS=RS;
LCD_CS=0;
}
for (mm = 0; mm < 8; mm++) { //собсно цикл передачи данных
LCD_DATA = (byte_to_send >> 7);
LCD_CLK=1; // защелкиваю в дисплей
byte_to_send = (byte_to_send << 1);
LCD_CLK=0; // готовлю к следующей защелке
}
RS_old=RS; // запоминаю значение RS
LCD_DATA = 0;
}
Пикселы идут всегда с первым параметров для процедуры Send_to_lcd(
DAT, ...
сразу можно убрать проверку эту " if ((RS_old != RS) || (!RS_old && !RS))", вместо этого один раз перед выводом пикселов:
Код: Выделить всё
// Обнуление
LCD_CLK=0;
LCD_DATA=0;
// Сообщаем что данные пойдут
LCD_CS=1;
LCD_RS=1;
LCD_CS=0;
Дальше лучше процедуру Send_to_lcd вообще не использовать, потому что каждый вызов процедуры это RCALL и RET команды, по даташиту 3 и 4 машинных такта теряем на каждый пиксел. Поэтому лучше сразу вытащить вывод пиксела прямо в код:
Код: Выделить всё
unsigned char mm, cc, color;
...
cc = color;
for (mm = 0; mm < 8; mm++) { //собсно цикл передачи данных
LCD_DATA = 0;
if (cc > 127) { LCD_DATA = 1; }
LCD_CLK=1; // защелкиваю в дисплей
cc = (cc << 1);
LCD_CLK=0; // готовлю к следующей защелке
}
Но после этого всего я получил только 12.8 FPS, а 17.9 после того как последний кусок превратил в прямой код (без цикла):
Код: Выделить всё
LCD_DATA = 0;
if ((cc & 128) == 128) { LCD_DATA = 1; }
LCD_CLK=1;
LCD_CLK=0;
LCD_DATA = 0;
if ((cc & 64) == 64) { LCD_DATA = 1; }
LCD_CLK=1;
LCD_CLK=0;
LCD_DATA = 0;
if ((cc & 32) == 32) { LCD_DATA = 1; }
LCD_CLK=1;
LCD_CLK=0;
LCD_DATA = 0;
if ((cc & 16) ==16) { LCD_DATA = 1; }
LCD_CLK=1;
LCD_CLK=0;
LCD_DATA = 0;
if ((cc & 8) == 8) { LCD_DATA = 1; }
LCD_CLK=1;
LCD_CLK=0;
LCD_DATA = 0;
if ((cc & 4) == 4) { LCD_DATA = 1; }
LCD_CLK=1;
LCD_CLK=0;
LCD_DATA = 0;
if ((cc & 2) == 2) { LCD_DATA = 1; }
LCD_CLK=1;
LCD_CLK=0;
LCD_DATA = 0;
if ((cc & 1) == 1) { LCD_DATA = 1; }
LCD_CLK=1;
LCD_CLK=0;
Подглядывал как WinAVR это компилирует в ассемблер, в файле
.lss получается красивый код на базе SBRC, SBI, CBI команд.
И вот такой код уже даёт 17.9 FPS на том же самом видео из Терминатора-2.