OLED的8080并口驱动

1. OLED 模块的 8080 接口方式需要如下一些信号线:

CS:OLED 片选信号。
WR:向 OLED 写入数据。
RD:从 OLED 读取数据。
D[7:0]:8 位双向数据线。
RST(RES):硬复位 OLED。
DC:命令/数据标志(0,读写命令;1,读写数据)。

2.模块的 8080 并口读/写的过程为:

先根据要写入/读取的数据的类型,设置 DC 为高(数据)/低(命令),然后拉低片选,选中 SSD1306,接着我们根据是读数据,还是要写数据置 RD/WR为低,然后:
在 RD 的上升沿, 使数据锁存到数据线(D[7:0])上;
在 WR 的上升沿,使数据写入到 SSD1306 里面;

3.SSD1306 的 8080 并口读写时序图

在这里插入图片描述
在这里插入图片描述

4.OLED的显示驱动芯片为SSD1306

SSD1306 的显存总共为 12864bit 大小,SSD1306 将这些显存分为了 8 页,其对应关系如表所示:
在这里插入图片描述
可以看出,SSD1306 的每页包含了 128 个字节,总共 8 页,这样刚好是 128
64 的点阵大小。因为每次写入都是按字节写入的,这就存在一个问题,如果我们使用只写方式操作模块,那么,每次要写 8 个点,这样,我们在画点的时候,就必须把要设置的点所在的字节的每个位都搞清楚当前的状态(0/1?),否则写入的数据就会覆盖掉之前的状态,结果就是有些不需要显示的点,显示出来了,或者该显示的没有显示了。这个问题在能读的模式下,我们可以先读出来要写入的那个字节,得到当前状况,在修改了要改写的位之后再写进 GRAM,这样就不会影响到之前的状况了。
我们采用的办法是在 STM32F4 的内部建立一个 OLED 的 GRAM(共 128*8 个字节),在每次修改的时候,只是修改 STM32F4 上的 GRAM(实际上就是 SRAM),在修改完了之后,一次性把 STM32F4 上的 GRAM 写入到 OLED 的 GRAM。当然这个方法也有坏处,就是对于那些 SRAM 很小的单片机(比如 51 系列)就比较麻烦了。

5.SSD1306 的常用命令

在这里插入图片描述
①第一个命令为 0X81,用于设置对比度的,这个命令包含了两个字节,第一个 0X81 为命令,随后发送的一个字节为要设置的对比度的值。这个值设置得越大屏幕就越亮。
②第二个命令为 0XAE/0XAF。0XAE 为关闭显示命令;0XAF 为开启显示命令。
③第三个命令为 0X8D,该指令也包含 2 个字节,第一个为命令字,第二个为设置值,第二个字节的 BIT2 表示电荷泵的开关状态,该位为 1,则开启电荷泵,为 0 则关闭。在模块初始化的时候,这个必须要开启,否则是看不到屏幕显示的。
④第四个命令为 0XB0~B7,该命令用于设置页地址,其低三位的值对应着 GRAM 的页地址。
⑤第五个指令为 0X00~0X0F,该指令用于设置显示时的起始列地址低四位。
⑥第六个指令为 0X10~0X1F,该指令用于设置显示时的起始列地址高四位。

6. OLED 模块的初始化过程

在这里插入图片描述

7.软件设计

OLED初始化

在这里插入图片描述

OLED写字节

//向 SSD1306 写入一个字节。
//dat:要写入的数据/命令
//cmd:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(u8 dat,u8 cmd)
{
u8 i;
OLED_RS=cmd; //写命令
OLED_CS=0;
for(i=0;i<8;i++)
{
OLED_SCLK=0;
if(dat&0x80)OLED_SDIN=1;
else OLED_SDIN=0;
OLED_SCLK=1;dat<<=1;
}
OLED_CS=1; OLED_RS=1;
}

OLED_Refresh_Gram函数
我们在STM32F4内部定义了一个块GRAM:u8 OLED_GRAM[128][8];此部分 GRAM 对应 OLED 模块上的 GRAM。在操作的时候,我们只要修改 STM32F4 内部的 GRAM 就可以了,然后通过 OLED_Refresh_Gram 函数把 GRAM 一次刷新到 OLED 的 GRAM 上。该函数代码如下:

//更新显存到 LCD
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);
}
}

主函数

int main(void)
{
u8 t=0;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200); //初始化串口波特率为 115200
LED_Init(); //初始化 LED
OLED_Init(); //初始化 OLED
OLED_ShowString(0,0,“ALIENTEK”,24);
OLED_ShowString(0,24, “0.96’ OLED TEST”,16);
OLED_ShowString(0,40,“ATOM 2014/5/4”,12);
OLED_ShowString(0,52,“ASCII:”,12);
OLED_ShowString(64,52,“CODE:”,12);
OLED_Refresh_Gram();//更新显示到 OLED
t=’ ‘;
while(1)
{
OLED_ShowChar(36,52,t,12,1);//显示 ASCII 字符
OLED_ShowNum(94,52,t,3,12); //显示 ASCII 字符的码值
OLED_Refresh_Gram();//更新显示到 OLED
t++;
if(t>’~’)t=’ ';
delay_ms(500); LED0=!LED0;
}
}
该部分代码用于在 OLED 上显示一些字符,然后从空格键开始不停的循环显示 ASCII 字符集,并显示该字符的 ASCII 值。然后我们编译此工程,直到编译成功为止。

发布了2 篇原创文章 · 获赞 1 · 访问量 24

猜你喜欢

转载自blog.csdn.net/wuyanboplus/article/details/104163293