OLED(SSD1306)模块显示概述
Posted studying~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OLED(SSD1306)模块显示概述相关的知识,希望对你有一定的参考价值。
OLED模块优缺点
优点:尺寸小,分辨率高,低压3.3V就可工作,支持多种接口方式,该模块提供了总共4种接口包括:6800、8080两种并行接口方式、 4线的穿行SPI接口方式,、IIC接口方式(只需要2根线就可以控制OLED了!)。
缺点:尺寸还难以大型化,价格昂贵
OLED模块工作模式选择(4种模式通过模块的BS1/BS2设置)(默认8080)
BS1/BS2的设置与模块接口模式的关系如表所示:
OLED 8080并行接口信号线说明
CS:OLED片选信号。
WR:向OLED写入数据。
RD:从OLED读取数据。
D[7:0]:8位双向数据线。
RST(RES):硬复位OLED。
DC:命令/数据标志(0,读写命令;1,读写数据)。
OLED8080并口读写过程
- 根据写入/读取的数据的类型,设置DC为高(数据)/低(命令)
- 然后拉低片选,选中SSD1306
- 接着我们根据是读数据,还是要写数据置RD/WR为低
- 然后:
(1).读数据:在RD的上升沿, 使数据锁存到数据线(D[7:0])上;
(2).写数据:在WR的上升沿,使数据写入到SSD1306(OLED控制器)里面;
并口写时序图
并口读时序图
OLED模块显存
SSD1306的显存总共为12864bit大小,SSD1306将这些显存分为了8页。每页包含了128个字节,总共8页,这样刚好是12864的点阵大小。
程序显示原理
在STM32的内部建立一个 缓存(共128*8个字节),在每次修改的时候,只是修改STM32上的缓存(实际上就是SRAM),在修改完了之后,一次性把STM32上的缓存数据写入到OLED的GRAM。当然这个方法也有坏处,就是对于那些SRAM很小的单片机(比如51系列)就比较麻烦了。
SSD1306的命令
====================================================================
OLED写一个字节
//向SSD1306写入一个字节。
//dat:要写入的数据/命令
//cmd:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(u8 dat,u8 cmd)
{
DATAOUT(dat); // 把数据传到数据口
if(cmd)
OLED_RS_Set();// D/C置高
else
OLED_RS_Clr();// D/C置低
OLED_CS_Clr(); // 片选
OLED_WR_Clr(); // 拉低WR,然后拉高产生一个上升沿
OLED_WR_Set();
OLED_CS_Set(); // 片选拉高,为下次做准备
OLED_RS_Set();
}
OLED画点函数
void OLED_DrawPoint(u8 x,u8 y,u8 t)
{
u8 pos,bx,temp=0;
if(x>127||y>63)return;//超出范围了.
pos=7-y/8;
bx=y%8;
temp=1<<(7-bx);
if(t)OLED_GRAM[x][pos]|=temp;
else OLED_GRAM[x][pos]&=~temp;
}
OLED显示
u8 OLED_GRAM[128][8];
void OLED_Refresh_Gram(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_GRAM[n][i],OLED_DATA); //更新OLED显存
}
}
OLED字符显示函数
//在指定位置显示一个字符,包括部分字符
//x:0~127 y:0~63
//mode:0,反白显示;1, size:选择字体 12/16/24
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode)
{
u8 temp,t,t1; u8 y0=y;
u8 csize=(size/8+((size%8)?1:0))*(size/2); //得到字体一个字符对应点阵集所占的字节数
chr=chr-' ';//得到偏移后的值
for(t=0;t<csize;t++)
{
if(size==12)temp=asc2_1206[chr][t]; //调用1206字体
else if(size==16)temp=asc2_1608[chr][t]; //调用1608字体
else if(size==24)temp=asc2_2412[chr][t]; //调用2412字体
else return; //没有的字库
for(t1=0;t1<8;t1++)
{
if(temp&0x80)OLED_DrawPoint(x,y,mode);
else OLED_DrawPoint(x,y,!mode);
temp<<=1;
y++;
if((y-y0)==size)
{
y=y0;
x++; break;
}
}
}
}
//字符码表
const unsigned char oled_asc2_1206[95][12]={
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
{0x18,0x00,0x24,0xC0,0x1B,0x00,0x0D,0x80,0x32,0x40,0x01,0x80},/*"%",5*/
{0x03,0x80,0x1C,0x40,0x27,0x40,0x1C,0x80,0x07,0x40,0x00,0x40},/*"&",6*/
…
{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x40,0x06,0x40,0x00,0x00},/*"c",67*/
{0x00,0x00,0x03,0x80,0x04,0x40,0x24,0x40,0x3F,0xC0,0x00,0x40},/*"d",68*/
…
{0x00,0x00,0x40,0x20,0x7B,0xE0,0x04,0x00,0x00,0x00,0x00,0x00},/*"}",93*/
{0x40,0x00,0x80,0x00,0x40,0x00,0x20,0x00,0x20,0x00,0x40,0x00},/*"~",94*/
};
const unsigned char oled_asc2_1608[95][16]={
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/ {0x0F,0x00,0x10,0x84,0x0F,0x38,0x00,0xC0,0x07,0x78,0x18,0x84,0x00,0x78,0x00,0x00},/*"%",5*/
{0x00,0x78,0x0F,0x84,0x10,0xC4,0x11,0x24,0x0E,0x98,0x00,0xE4,0x00,0x84,0x00,0x08},/*"&",6*/
…
{0x00,0x00,0x1C,0x00,0x10,0x00,0x10,0xFC,0x13,0x00,0x1C,0x00,0x10,0x00,0x00,0x00},/*"7",23*/
{0x00,0x00,0x0E,0x38,0x11,0x44,0x10,0x84,0x10,0x84,0x11,0x44,0x0E,0x38,0x00,0x00},/*"8",24*/
{0x00,0x00,0x07,0x00,0x08,0x8C,0x10,0x44,0x10,0x44,0x08,0x88,0x07,0xF0,0x00,0x00},/*"9",25*/
}
以上是关于OLED(SSD1306)模块显示概述的主要内容,如果未能解决你的问题,请参考以下文章
MicroPython ESP32ssd1306 0.96“OLED+气象数据中文显示
MicroPython ESP32ssd1306 0.96“OLED+网络时钟