OLED,即有机发光二极管(Organic Light-Emitting Diode),LCD 都需要背光,而 OLED 不需要,因为它是自发光的。这样同样的显示, OLED 效果要来得好一些。 以目前的技术, OLED 的尺寸还难以大型化,但是分辨率确可以做到很高。
OLED优点:1.自发光,不需要背光 2.功耗更低,节能 3.对比度高,色彩鲜艳
OLED缺点:1.烧屏 2.价格昂贵 3.低频频闪
ALINETEK 的 OLED 显示模块,该模块有以下特点: 1) 模块有单色和双色两种可选,单色为纯蓝色,而双色则为黄蓝双色。
2) 尺寸小,显示尺寸为 0.96 寸,而模块的尺寸仅为 27mm*26mm 大小。
3) 高分辨率,该模块的分辨率为 128*64。
4) 多种接口方式,该模块提供了总共 5 种接口包括: 6800、 8080 两种并行接口方式、 3
线或 4 线的串行SPI 接口方式、 IIC 接口方式(只需要 2 根线就可以控制 OLED 了!)。
CS: OLED 片选信号。
WR:向 OLED 写入数据。
RD:从 OLED 读取数据。
D[7:0]:8位双向数据线。
RST(RES):硬复位 OLED。
DC:命令/数据标志(0,读写命令;1,读写数据)。
并口总线时序,常用于屏幕驱动IC,由英特尔提出
//OLED模式设置
//0: 4线串行模式 (模块的BS1,BS2均接GND)
//1: 并行8080模式 (模块的BS1,BS2均接VCC)
#define OLED_MODE 1
//---------------------------OLED端口定义--------------------------
#define OLED_CS PDout(6)
#define OLED_RST PGout(15)
#define OLED_RS PDout(3)
#define OLED_WR PGout(14)
#define OLED_RD PGout(13)
//PC0~7,作为数据线
#define DATAOUT(x) GPIO_Write(GPIOC,x);//输出
//使用4线串行接口时使用
#define OLED_SCLK PCout(0)
#define OLED_SDIN PCout(1)
#define OLED_CMD 0 //写命令
#define OLED_DATA 1 //写数据
#define DATAOUT(x) GPIO_Write(GPIOC,x);//输出
//向SSD1306写入一个字节。
//dat:要写入的数据/命令
//cmd:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(u8 dat,u8 cmd)
{
OLED_RS=cmd;
OLED_CS=0; //数据拉低片选线,选择SSD1306
OLED_WR=0; //拉低WR写线,准备数据
DATAOUT(dat);//在低电平期间准备数据
OLED_WR=1; //拉高WR,数据发送到SSD1306
OLED_CS=1; //取消片选
OLED_RS=1; //释放RS线,恢复默认
}
指令(HEX) |
各位描述 |
名称 |
说明 |
|||||||
D7 |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
|||
0xAE/0xAF |
1 |
0 |
1 |
0 |
1 |
1 |
1 |
X0 |
设置显示开关 |
X0 = 0,关闭显示 X0 = 1,开启显示 |
0xB0~0xB7 |
1 |
0 |
1 |
1 |
0 |
X2 |
X1 |
X0 |
设置页地址 |
X[2:0]:0~7对应页0~7 B0是页0,B1是页1... |
0x00~0x0F |
0 |
0 |
0 |
0 |
X3 |
X2 |
X1 |
X0 |
设置列地址(L4) |
设置8位列地址的低四位 |
0x10~0x1F |
0 |
0 |
0 |
1 |
X3 |
X2 |
X1 |
X0 |
设置列地址(H4) |
设置8位列地址的高四位 |
OLED是128*64,前面的128是用两位来表示列地址,0x00-0x0F是低4位,0x10-0x1F是高4位。
表格中的下面三行合起来就可以表示SSD1306的GRAM写入位置。
图形显示数据RAM是一个位映射静态RAM(可以理解为“FIFO”,与物理位置有映射关系),保存要显示的位模式。内存大小为128 * 64位,可分为8页,从页0到页7,用于黑白128 * 64点阵显示。
对GRAM进行操作时,列地址指针会自动递增。当列地址指针到达列结束地址时,重置为开始地址,但页地址指针不变。用户必须设置新的页面和列地址,以便访问下一页GRAM内容。
三种设置内存地址模式:页地址模式,水平地址模式和垂直地址模式。
1. 发送内存地址模式命令0x20 2. 发送页地址模式命令0x02
建立一个OLED的GRAM
单片机内部需要128*8个字节,每次修改的时候,只是修改单片机上的GRAM(实际上就是SRAM),在修改完之后,一次性把单片机内部的GRAM写入到OLED的GRAM。
//存放格式如下.
//[0]0 1 2 3 ... 127
//[1]0 1 2 3 ... 127
//[2]0 1 2 3 ... 127
//[3]0 1 2 3 ... 127
//[4]0 1 2 3 ... 127
//[5]0 1 2 3 ... 127
//[6]0 1 2 3 ... 127
//[7]0 1 2 3 ... 127
#define OLED_CMD 0 //写命令
#define OLED_DATA 1 //写数据
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);
}
}
}
//画点
//x:0~127
//y:0~63
//t:1 填充 0,清空
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;
}
1.显示字符,必须先有其点阵数据,点阵数据的集合,叫做字库
2.单片机根据点阵数据按取模方向进行描点还原,就能显示字符
3.ASCII字符宽度 = 汉字宽度的一半
16*16大小,字符A的点阵数据数组:
uint8_t oled_ascii_1608[]=
{
0x00,0x04,0x00,0x3C,0x03,0xC4,0x1C,0x40,
0x07,0x40,0x00,0xE4,0x00,0x1C,0x00,0x04
} ;
uint8_t temp, t1, t;
uint8_t y0 = y; // 保存y的初值
for(t = 0; t < 16; t++) //总共16个字节,要遍历一遍
{
temp = oled_ascii_1608[t]; // 依次获取点阵数据
for(t1 = 0; t1 < 8; t1++)
{
if(temp & 0X80) // 这个点有效,需要画出来 1000 0000
oled_draw_point(x, y, mode);
else // 这个点无效,不需要画出来
oled_draw_point(x, y, !mode);
temp <<= 1; //低位数据往高位移位,最高位数据直接丢弃
y++; //y坐标自增
if((y-y0) == 16) //显示完一列了
{
y = y0; //y坐标复位
x++; //x坐标递增
break; //跳出 for循环
}
}
}