OLED通信速度アップ
- PROG03_OLED_BMPを使って、OLED通信速度アップに挑戦。 (2011/6/1)
- さらに改善。(2011/6/11)
- さらに改善。(2011/6/22)
- APIを追加。(2011/6/25)
結果
改善前 →929msec.
2.3.4. →249msec. (2011/6/1)
5. →198msec. (2011/6/11)
6.7. →183msec. (2011/6/22)
8.9.10.→42msec. (2011/6/25)
プログラム
詳細
1.表示開始と表示終了のタイミングをLED出力。ロジアナで測定。→929msec.
main.c
int main(void)
{
...
Init_SysTick();
Init_Color_LED();
Init_OLED();
// [2011/06/01 NanaCraft]
Set_Color_LED(7);
//
// Send Bitmap Data
//
...
//
// Finish Sign
//
while(1)
{
// [2011/06/01 NanaCraft]
//Draw_Color_LED();
Set_Color_LED(0);
}
return 0;
}
2.Optimization LevelをNoneからOptimize Mostに変更。→501msec.
3.SPIのFIFOを有効に使用。→261msec.
spi.c
void SPI_TxData(uint32_t txdata)
{
// [2011/06/01 NanaCraft]
while (!(LPC_SSP0->SR & SSPSR_TNF));
LPC_SSP0->DR = txdata;
}
4.OLED_Send_Command()のコードを最適化。→249msec.
oled.c
void OLED_Send_Command(uint32_t *oled)
{
// [2011/06/01 NanaCraft]
uint32_t countAndCommand;
uint32_t end;
uint32_t i;
countAndCommand = oled[OLED_COMMAND];
SPI_TxData(countAndCommand & 0x0ff);
end = OLED_DATA + ((countAndCommand >> 8) & 0x0ff);
for (i = OLED_DATA; i < end; i++)
{
SPI_TxData(oled[i] | 0x100);
}
}
5.OLED_Fill_Rect()のコードを最適化。→198msec.
oled.c
void OLED_Fill_Rect(int32_t x0, int32_t y0, int32_t xsize, int32_t ysize, uint32_t color)
{
// [2011/06/11 NanaCraft]
uint32_t x1, y1;
uint32_t col0, col1, row0, row1;
uint32_t oled[3];
uint32_t i;
uint32_t pixels;
if (xsize < 1) return;
x1 = x0 + xsize - 1;
if (x0 < 0) x0 = 0;
else if (x0 > 127) return;
if (x1 < 0) return;
else if (x1 > 127) x1 = 127;
if (ysize < 1) return;
y1 = y0 + ysize - 1;
if (y0 < 0) y0 = 0;
else if (y0 > 127) return;
if (y1 < 0) return;
else if (y1 > 127) y1 = 127;
switch (gOELD_Orientation_Mode)
{
case OLED_TOP_N:
case OLED_TOP_S:
col0 = x0;
col1 = x1;
row0 = y0;
row1 = y1;
break;
case OLED_TOP_W:
case OLED_TOP_E:
col0 = y0;
col1 = y1;
row0 = x0;
row1 = x1;
break;
default:
return;
}
oled[OLED_COMMAND] = C_SET_COLUMN_ADDRESS;
oled[D_START_ADDRESS] = col0;
oled[D_END_ADDRESS] = col1;
OLED_Send_Command(oled);
oled[OLED_COMMAND] = C_SET_ROW_ADDRESS;
oled[D_START_ADDRESS] = row0;
oled[D_END_ADDRESS] = row1;
OLED_Send_Command(oled);
oled[OLED_COMMAND] = C_WRITE_RAM_COMMAND;
OLED_Send_Command(oled);
pixels = (x1 - x0 + 1) * (y1 - y0 + 1);
for (i = 0; i < pixels; i++)
{
OLED_Send_Pixel(color);
}
}
6.SPI_TxData()の呼び出し回数を削減。→194msec.
spi.h
void SPI_BulkTxData(uint32_t* txdata, uint32_t length); // [2011/06/22 NanaCraft]
spi.c
void SPI_BulkTxData(uint32_t* txdata, uint32_t length)
{
uint32_t i;
for (i = 0; i < length; i++)
{
while (!(LPC_SSP0->SR & SSPSR_TNF));
LPC_SSP0->DR = txdata[i];
}
}
oled.c
void OLED_Fill_Rect(int32_t x0, int32_t y0, int32_t xsize, int32_t ysize, uint32_t color)
{
// [2011/06/11 NanaCraft]
uint32_t x1, y1;
uint32_t col0, col1, row0, row1;
uint32_t oled[3];
uint32_t i;
uint32_t pixels;
if (xsize < 1) return;
x1 = x0 + xsize - 1;
if (x0 < 0) x0 = 0;
else if (x0 > 127) return;
if (x1 < 0) return;
else if (x1 > 127) x1 = 127;
if (ysize < 1) return;
y1 = y0 + ysize - 1;
if (y0 < 0) y0 = 0;
else if (y0 > 127) return;
if (y1 < 0) return;
else if (y1 > 127) y1 = 127;
switch (gOELD_Orientation_Mode)
{
case OLED_TOP_N:
case OLED_TOP_S:
col0 = x0;
col1 = x1;
row0 = y0;
row1 = y1;
break;
case OLED_TOP_W:
case OLED_TOP_E:
col0 = y0;
col1 = y1;
row0 = x0;
row1 = x1;
break;
default:
return;
}
// [2011/06/22 NanaCraft]
oled[0] = 0x15; // Set Column Address
oled[1] = col0 | 0x100;
oled[2] = col1 | 0x100;
SPI_BulkTxData(oled, 3);
oled[0] = 0x75; // Set Row Address
oled[1] = row0 | 0x100;
oled[2] = row1 | 0x100;
SPI_BulkTxData(oled, 3);
SPI_TxData(0x5c); // Write RAM Command
pixels = (x1 - x0 + 1) * (y1 - y0 + 1);
for (i = 0; i < pixels; i++)
{
oled[0] = ((color >> 8) & 0xff) | 0x100;
oled[1] = ( color & 0xff) | 0x100;
SPI_BulkTxData(oled, 2);
}
}
7.OLED_Draw_Dot()->OLED_Fill_Rect()のオーバーヘッドを削減。→183msec.
oled.h
// [2011/06/22 NanaCraft]
//void OLED_Draw_Dot(int32_t x, int32_t y, int32_t size, uint32_t color);
#define OLED_Draw_Dot(x, y, size, color) OLED_Fill_Rect(x, y, size, size, color)
oled.c
// [2011/06/22 NanaCraft]
/*
void OLED_Draw_Dot(int32_t x, int32_t y, int32_t size, uint32_t color)
{
OLED_Fill_Rect(x, y, size, size, color);
}
*/
8.OLED関連APIを追加。
(プログラムの20110625に同封。)
9.WRITE_RAM_BUFFERを調整。
NcOledFill8()を使い、128pixel分を一括表示したときの、1画面分の処理時間。
10.8~9を反映して、NcOledFill16()を使用。→42msec.
main.c
#include "NcOb.h"
uint16_t pixels[128];
// [2011/06/25 NanaCraft]
i = 0;
for (y = 0; y < 128; y++)
{
for (x = 0; x < 128; x++)
{
index = BMP_RGB[i++];
palette = BMP_PLT[index];
red = (palette >> (16 + 3)) & 0x01f;
grn = (palette >> ( 8 + 2)) & 0x03f;
blu = (palette >> ( 0 + 3)) & 0x01f;
pixel = (red << 11) + (grn << 5) + (blu << 0);
pixels[x] = pixel;
}
NcOledFillBegin(0, y, 128, 1);
NcOledFill16(pixels, 128);
}
最終更新:2011年06月25日 14:32