STM32 OLED LCD 液晶 使用帧缓冲(framebuffer)
承接各类STM32项目、JAVA、C++、Android、微信、Linux,毕业设计开发
手机:18559979152(微信同号)
以12864 OLED为例(其它类似)
X方向有128个像素点,Y方向有64个像素点,只能个一字节一个字节写入,一个字节是8Bit,一个Bit为一个像素点,0为灭,1为亮。即一次写入8个像素点的数据。
先了解一下SSD1106的显示结构,显示结构如下
定义一个帧缓冲区u8 OLED_FrameBuffer[8][128];//显示缓冲区
X方向128个字节
0Byte--------------------------------------------------------------------127Byte
数组下标 [0][0] [0][1] [0][2] [0][3]
像素1行 bit0 bit0 bit0 bit0
像素2行 bit1 bit1 bit1 bit1
| |
Y 像素8行 bit7 bit7
方 [1][0] [1][1]
向 像素9行 bit0 bit0
8 | |
字 bit7 bit7
节
.
.
.
像素64行
例:
要在x0y0坐标液晶最左上角打个点,即OLED_FrameBuffer[0][0]赋值0x01,二进制表示00000001
要在x127y63坐标最右下角打个点,即OLED_FrameBuffer[7][127]赋值0x80,二进制表示10000000
知道上面的原理,就可以写出函数,任意坐标点亮/灭/取反/读取
// 写入任意坐标一个点0灭,1亮 x0-127 y0-63
void Write_Point_FrameBuffer(u8 x,u8 y,u8 Bit)
{
u8 temp,y1,y2;
y1=y%8; // y方向8个字节 8Byte*8Bit = 64Bit y坐标取余8得要操作的Bit位
y2=y/8; // y方向8个字节 8Byte*8Bit = 64Bit y坐标除以8得要操作的Byte位
temp = OLED_FrameBuffer[y2][x];
if(Bit==1){
temp|=(1<<y1);
}else{
temp&=~(1<<y1);
}
OLED_FrameBuffer[y2][x]=temp;
}
// 读取任意坐标一个点状态0灭,1亮 x0-127 y0-63
u8 Read_Point_FrameBuffer(u8 x,u8 y)
{
u8 temp,y1,y2;
y1=y%8; // y方向8个字节 8Byte*8Bit = 64Bit y坐标取余8得要操作的Bit位
y2=y/8; // y方向8个字节 8Byte*8Bit = 64Bit y坐标除以8得要操作的Byte位
temp=OLED_FrameBuffer[y2][x];
return (temp>>y1)&0x01;
}
// 取反任意坐标一个点状态 x0-127 y0-63
void Convert_Point_FrameBuffer(u8 x,u8 y)
{
u8 temp,y1,y2;
y1=y%8; // y方向8个字节 8Byte*8Bit = 64Bit y坐标取余8得要操作的Bit位
y2=y/8; // y方向8个字节 8Byte*8Bit = 64Bit y坐标除以8得要操作的Byte位
temp=OLED_FrameBuffer[y2][x];
temp^=(1<<y1);
OLED_FrameBuffer[y2][x]=temp;
}
以上函数只是写到的帧缓冲区OLED_FrameBuffer,并没有写入液晶,液晶还不会显示
再写一个刷屏函数刷新整块液晶
// 更新显示帧缓存
void Update_Show_FrameBuffer(void)
{
u8 i,n;
for(i=0;i<8;i++) {
OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7)
OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址
OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址
for(n=0;n<128;n++)OLED_WR_Byte(OLED_FrameBuffer[i][n],OLED_DATA);
}
}
这个函数可以放在定时器中自动刷新,或放在主函数中手动刷新
注意:帧缓冲技术决定于带系统还是,液晶驱动接口IIC,8080,SPI,FSMC,RGB,LVDS,MIPI等
8080,IIC和SPI看液晶大小和驱动器速率/带系统还是裸跑来决定是否用帧缓冲。FSMC,RGB,MIPI基本上都跑系统了,系统都带有帧缓冲技术了,所以不用关心。