OLED显示算法调整
1 问题描述
本次用的OLED 屏幕为SSD1317芯片驱动,96x96单色OLED。根据Datasheet上指令已经可以显示,但是方向不对。
== 该显示虽然没问题,但是和电路结合,方向很不方便,正常一般是有fpc的地方为下,本文章提供一种方案。先把调整好的图像放上。==
2 解决思路
该屏幕显示设置了大小为96*12的缓冲,只要修改填充好的缓存,即可修改方向。
为了修改方向,楼主的方案是将96*12字节的缓冲扩充 为96*96字节的bit缓冲,通过数组算法重新组合96*12的缓冲。
本屏幕的显示模式为横向显示。
根据本屏幕的情况,算法如下:
static void Mem12_Cur96(void)
{
uint8_t y, x, n;
for (y = 0; y < 12; y++)
{
for (x = 0; x < 96; x++)
{
for (n = 0; n < 8; n++)
{
Mem[x + 96 * (n + y * 8)] = (CurrentMemory[y * 96 + x] >> n)
& 0x01;
}
}
}
}
static void Mem96_Cur12(void)
{
uint8_t y, x, n, num = 0;
for (y = 0; y < 12; y++)
{
for (x = 0; x < 96; x++)
{
for (n = 0; n < 8; n++)
{
num |= (Mem[(95 - x) * 96 + 8 * y + n] << n);
}
CurrentMemory[(y) * 96 + x] = num;
num = 0;
}
}
}
该算法的主要是想就是明确两次转化关系,第一次扩充:
Mem[x + 96 * (n + y * 8)] = (CurrentMemory[y * 96 + x] >> n) & 0x01;
主要是把一个字节的每一位转化为8个数据。
第二次重新整理:
for (n = 0; n < 8; n++)
{
num |= (Mem[(95 - x) * 96 + 8 * y + n] << n);
}
CurrentMemory[(y) * 96 + x] = num;
3演示
成功旋转90度,但是旋转还是有问题,旋转错了方向。最后修改指令,修改参数,成功。
最后
粘上初始化代码:
static void Init_SSD1317(spi_device_handle_t spi)
{
Oled_Write_Command(0xAE, spi); //Set Display Off
Oled_Write_Command(0xD5, spi); //Display divide ratio/osc. freq. mode
Oled_Write_Command(0xD1, spi); //
Oled_Write_Command(0xA8, spi); //Multiplex ratio mode
Oled_Write_Command(0x5F, spi);
Oled_Write_Command(0xD3, spi); //Set Display Offset
Oled_Write_Command(0x00, spi);
Oled_Write_Command(0xA2, spi); //Set Display Start Line
Oled_Write_Command(0x00, spi); //
Oled_Write_Command(0xA1, spi); //Segment Re-map
Oled_Write_Command(0xC8, spi); //Set COM Output Scan Direction
Oled_Write_Command(0xDA, spi); //Common pads hardware: alternative
Oled_Write_Command(0x12, spi); //12
Oled_Write_Command(0x20, spi); //Set memory addressing mode
Oled_Write_Command(0x00, spi); //Horizontal Addressing Mode
Oled_Write_Command(0xAD, spi); //Set Select external or internal IREF
Oled_Write_Command(0x00, spi); //External IREF
Oled_Write_Command(0x81, spi); //Contrast control
Oled_Write_Command(0x9F, spi);
Oled_Write_Command(0xD9, spi); //Set pre-charge period
Oled_Write_Command(0x22, spi);
Oled_Write_Command(0xDB, spi); //VCOM deselect level mode
Oled_Write_Command(0x30, spi);
Oled_Write_Command(0xA4, spi); //Set Entire Display On/Off
Oled_Write_Command(0xA6, spi); //Set Normal Display
OLED_Screen_Clear();
Oled_Write_Command(0xAF, spi); //Set Display On
}
static void Mem12_Cur96(void)
{
uint8_t y, x, n;
for (y = 0; y < 12; y++)
{
for (x = 0; x < 96; x++)
{
for (n = 0; n < 8; n++)
{
Mem[x + 96 * (n + y * 8)] = (CurrentMemory[y * 96 + x] >> n)
& 0x01;
}
}
}
}
static void Mem96_Cur12(void)
{
uint8_t y, x, n, num = 0;
for (y = 0; y < 12; y++)
{
for (x = 0; x < 96; x++)
{
for (n = 0; n < 8; n++)
{
num |= (Mem[(95 - x) * 96 + 8 * y + n] << n);
}
CurrentMemory[(y) * 96 + 95 - x] = num;
num = 0;
}
}
}
总结
楼主的办法有些消耗内存,如果大家有更好的办法,可以多多交流!