目录

简介

原理

接口方式

1.8080并行接口

2.SPI方式

常用命令

编写代码

IO口

软件设计

OLED初始化代码:

OLED_Refresh_Gram函数

OLED_WR_Byte函数

画点函数

字符函数

效果


1.我们将使用 MiniSTM32 开发板上的 OLED 模块接口,来点亮 OLED,并实现 ASCII 字 符的显示

简介

OLED,即有机发光二极管,又称为有机电激光显示,OLED 由于同时具备自发光,不需背光源、对比度高、 厚度薄、视角广、反应速度快、可用于挠曲性面板、使用温度范围广、构造及制程较简单等优异之特性,被认为是下一代的平面显示器新兴应用技术。

我们使用的是 ALINETEK 的 OLED 显示模块,该模块有以下特点:

1)模块有单色和双色两种可选,单色为纯蓝色,而双色则为黄蓝双色。

2)尺寸小,显示尺寸为 0.96 寸,而模块的尺寸仅为 27mm*26mm 大小。

3)高分辨率,该模块的分辨率为 128*64。

4)多种接口方式,该模块提供了总共 4 种接口包括:6800、8080 两种并行接口方式、4 线 SPI 接口方式以及 IIC 接口方式(只需要 2 根线就可以控制 OLED 了!)。

5)不需要高压,3.3V 就可以工作了。

注意:别直接接到 5V 的系统上去,否则可能烧坏模块

接口方式 4线SPI IIC 8位6800 8位8080
BS1 0 1 0 1
BS2 0 0 1 1

1:代表VCC

2:代表GND

该模块默认设置是:BS1 和 BS2 接 VCC ,即使用 8080 并口方式

原理

该模块采用 8*2 的 2.54 排针与外部连接,总共有 16 个管脚,在 16 条线中,我们只用了 15 条,有一个是悬空的。15 条线中,电源和地线占了 2 条,还剩下 13 条信号线。在不同模式下, 我们需要的信号线数量是不同的,在 8080 模式下,需要全部 13 条,而在 IIC 模式下,仅需要 2 条线就够了!这其中有一条是共同的,那就是复位线 RST(RES),RST 上的低电平,将导致 OLED 复位,在每次初始化之前,都应该复位一下 OLED 模块。

接口方式

1.8080并行接口

CS:OLED 片选信号。

WR:向 OLED 写入数据。

RD:从 OLED 读取数据。

D[7:0]:8 位双向数据线。

RST(RES):硬复位 OLED。

DC:命令/数据标志(0,读写命令;1,读写数据)。

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

控制脚的信号状态所对应的功能:

功能 RD WR CS DC
写命令 H L L
读状态 H L L
写数据 H L H
读数据 H L H

在 8080 方式下读数据操作的时候,我们有时候(例如读显存的时候)需要一个假读命令,以使得微控制器的操作频率和显存的操作频率相匹配。在读取真正的数据之 前,由一个的假读的过程。这里的假读,其实就是第一个读到的字节丢弃不要,从第二个开始, 才是我们真正要读的数据。

2.SPI方式

信号线:

CS:OLED 片选信号。

RST(RES):硬复位 OLED。

DC:命令/数据标志(0,读写命令;1,读写数据)。

SCLK:串行时钟线。在 4 线串行模式下,D0 信号线作为串行时钟线 SCLK。

SDIN:串行数据线。在 4 线串行模式下,D1 信号线作为串行数据线 SDIN。

模块的D2 需要悬空,其他引脚可以接到 GND。

在 4 线串行模式下,只能往模块写数据而 不能读数据。

我们在 STM32 的内部建立一个 OLED 的 GRAM(共 128*8 个字节),在每次修改的时候,只是修改 STM32 上的 GRAM(实际上就是 SRAM),在修改完了之后,一次 性把 STM32 上的 GRAM 写入到 OLED 的 GRAM。对于那些 SRAM 很小的单片机(比如 51 系列)就比较麻烦了。

常用命令

第一个命令为 0X81,用于设置对比度的,这个命令包含了两个字节,第一个 0X81 为命令, 随后发送的一个字节为要设置的对比度的值。这个值设置得越大屏幕就越亮。

第二个命令为 0XAE/0XAF。0XAE 为关闭显示命令;0XAF 为开启显示命令。

第三个命令为 0X8D,该指令也包含 2 个字节,第一个为命令字,第二个为设置值,第二 个字节的 BIT2 表示电荷泵的开关状态,该位为 1,则开启电荷泵,为 0 则关闭。在模块初始化 的时候,这个必须要开启,否则是看不到屏幕显示的。

第四个命令为 0XB0~B7,该命令用于设置页地址,其低三位的值对应着 GRAM 的页地址。

第五个指令为 0X00~0X0F,该指令用于设置显示时的起始列地址低四位。

第六个指令为 0X10~0X1F,该指令用于设置显示时的起始列地址高四位。

编写代码

1)设置 STM32 与 OLED 模块相连接的 IO。

2)初始化 OLED 模块。

3)通过函数将字符和数字显示到 OLED 模块上。

IO口

OLED_CS 对应 PC9;

OLED_RS 对应 PC8;

OLED_WR 对应 PC7;

OLED_RD 对应 PC6;

OLED_D[7:0]对应 PB[7:0];

软件设计

OLED初始化代码:

void OLED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,
ENABLE );
#if OLED_MODE==1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //使能 AFIO 时钟
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);//JTAG-DP 失能 + SW-DP 使能
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|
GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_Write(GPIOB,0XFFFF);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_SetBits(GPIOC, GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9);
//如果每一位决定一个 GPIO_Pin,则可以通过或的形式来初始化多个 IO
#else
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD ; //推挽输出
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_Write(GPIOB,0X03);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_SetBits(GPIOC, GPIO_Pin_8|GPIO_Pin_9);
#endif OLED_WR_Byte(0xAE,OLED_CMD); //关闭显示
OLED_WR_Byte(0xD5,OLED_CMD); //设置时钟分频因子,震荡频率
OLED_WR_Byte(80,OLED_CMD); //[3:0],分频因子;[7:4],震荡频率
OLED_WR_Byte(0xA8,OLED_CMD); //设置驱动路数
OLED_WR_Byte(0X3F,OLED_CMD); //默认 0X3F(1/64)
OLED_WR_Byte(0xD3,OLED_CMD); //设置显示偏移
OLED_WR_Byte(0X00,OLED_CMD); //默认为 0
OLED_WR_Byte(0x40,OLED_CMD); //设置显示开始行 [5:0],行数.OLED_WR_Byte(0x8D,OLED_CMD); //电荷泵设置
OLED_WR_Byte(0x14,OLED_CMD); //bit2,开启/关闭
OLED_WR_Byte(0x20,OLED_CMD); //设置内存地址模式
OLED_WR_Byte(0x02,OLED_CMD); //
OLED_WR_Byte(0xA1,OLED_CMD); //段重定义设置,bit0:0,0->0;1,0->127;
OLED_WR_Byte(0xC0,OLED_CMD); //设置 COM 扫描方向;
OLED_WR_Byte(0xDA,OLED_CMD); //设置 COM 硬件引脚配置
OLED_WR_Byte(0x12,OLED_CMD); //[5:4]配置
OLED_WR_Byte(0x81,OLED_CMD); //对比度设置
OLED_WR_Byte(0xEF,OLED_CMD); //1~255;默认 0X7F (亮度设置,越大越亮)
OLED_WR_Byte(0xD9,OLED_CMD); //设置预充电周期
OLED_WR_Byte(0xf1,OLED_CMD); //[3:0],PHASE 1;[7:4],PHASE 2;
OLED_WR_Byte(0xDB,OLED_CMD); //设置 VCOMH 电压倍率
OLED_WR_Byte(0x30,OLED_CMD); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;
OLED_WR_Byte(0xA4,OLED_CMD); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)
OLED_WR_Byte(0xA6,OLED_CMD); //设置显示方式;bit0:1,反相显示;0,正常显示 OLED_WR_Byte(0xAF,OLED_CMD); //开启显示
OLED_Clear();
} 

OLED_Refresh_Gram函数

在操作的时候,我们只 要修改 STM32 内部的 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);
}
}

OLED_Refresh_Gram 函数先设置页地址,然后写入列地址(也就是纵坐标),然后从 0 开 始写入 128 个字节,写满该页,最后循环把 8 页的内容都写入,就实现了整个从 STM32 显存 到 OLED 显存的拷贝

OLED_WR_Byte函数

#if OLED_MODE==1
//向 SSD1306 写入一个字节。
//dat:要写入的数据/命令
//cmd:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(u8 dat,u8 cmd)
{
DATAOUT(dat);
OLED_RS=cmd;
OLED_CS=0;
OLED_WR=0;
OLED_WR=1;
OLED_CS=1;
OLED_RS=1;
}
#else
//向 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;
}
#endif

这两个函数通过宏定义 OLED_MODE 来决定使用哪一个。如果 OLED_MODE=1,就定义为并口模式,选择第一个函数,而如果为 0,则为 4 线串口模式,选 择第二个函数。这两个函数输入参数均为 2 个:dat 和 cmd,dat 为要写入的数据,cmd 则表明 该数据是命令还是数据。这两个函数的时序操作就是根据上面我们对 8080 接口以及 4 线 SPI 接口的时序来编写的。

OLED_GRAM[128][8]中的 128 代表列数(x 坐标),而 8 代表的是页,每页又包含 8 行, 总共 64 行(y 坐标)。从高到低对应行数从小到大。比如,我们要在 x=100,y=29 这个点写入 1,则可以用这个句子实现: OLED_GRAM[100][4]|=1<<2;

画点函数

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;
}

字符函数

//在指定位置显示一个字符,包括部分字符
//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;
}
} }
}

main.c

int main(void)
{
u8 t=0;
delay_init(72); //延时初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
LED_Init();OLED_Init(); //初始化 OLED OLED_ShowString(0,0,"ALIENTEK",24);
OLED_ShowString(0,24, "0.96' OLED TEST",16);
OLED_ShowString(0,40,"ATOM 2014/3/7",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;
}
}

效果

DS0 不停的闪烁,实现了三种不同尺寸 ASCII 字符的显示,在 最后一行不停的显示 ASCII 字符以及其码值。

正点原子OLED显示实验相关推荐

  1. STM32正点原子图片——显示实验

    目录 一.图片显示部分 GIF piclib.c介绍 图像显示实验main.c介绍 二.SD卡模块 1.SD卡基础知识 2.SD卡读操作 3.SD卡写操作 一.图片显示部分 GIF GIF(Graph ...

  2. (实验12)单片机,STM32F4学习笔记,代码讲解【OLED显示实验】【正点原子】【原创】

    文章目录 其它文章链接,独家吐血整理 实验现象 主程序 OLED初始化程序 代码讲解 其它文章链接,独家吐血整理 (实验3)单片机,STM32F4学习笔记,代码讲解[按键输入实验][正点原子][原创] ...

  3. 【正点原子STM32连载】第二十三章 OLED显示实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1

    1)实验平台:正点原子MiniPro H750开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=677017430560 3)全套实验源码+手册+视频 ...

  4. fastreport masterdata每页都显示_ALIENTEK 阿波罗 STM32F767 开发板资料连载十六章 OLED 显示实验...

    1)实验平台:alientek 阿波罗 STM32F767 开发板2)摘自<STM32F7 开发指南(HAL 库版)>关注官方微信号公众号,获取更多资料:正点原子 http://weixi ...

  5. 原子哥 OLED显示实验笔记2

    原子哥讲解的有1206 1608 2412三种字体 意思是:例如1206用12行6列的12*6个方格显示字体 以1206的字符%为例  在OLED显示字符% {0x18,0x00,0x24,0xC0, ...

  6. 【STM32】OLED 显示实验代码详解

    文章目录 main.c oled.c oled.h main.c #include "led.h" #include "delay.h" #include &q ...

  7. 正点原子 在ADC实验中添加USMART,通过串口查看电压值

    结合了实验十七和实验十四.由于没有买LCD的板子,所以通过串口调试来查看电压值. 目录 一.准备工作:头文件 二.添加一些代码 三.开始调试 一.准备工作:头文件 1.首先将实验十四的USMART文件 ...

  8. 灵感手环第一步——0.96寸OLED显示实验

    这算是我这个系列的第一篇博客吧.首先要解决的就是屏幕显示问题.我选择了目前新兴起的OLED显示模块. OLED(OrganicLightEmittingDiode),中文译作有机发光二极管,目前被广泛 ...

  9. STM32——OLED显示实验

    一.关于OLED 1.OLED(有机发光二极管)又称有机电激光显示.OLED同时具备自发光,不需背光源.对比度高.厚度薄.视角广.反应速度快.可用于挠曲面板.使用温度范围广.构造及制作过程简单等特性. ...

最新文章

  1. 小程序打开文档标题乱码处理
  2. 微软亚研院CV大佬代季峰跳槽商汤为哪般?
  3. python爬虫代码实例-Python爬虫之urllib示例
  4. java EF6,EF Core 2.0和EF6(Entity Framework 6)中配置实体映射关系
  5. 1595 hdu find the longest of the shortest
  6. Vlan中Trunk接口配置
  7. P3195 [HNOI2008]玩具装箱TOY DP+优化
  8. 排序-InsertionSort 插入排序
  9. 开VM虚拟机导致内存和磁盘利用率高
  10. HALCON学习笔记 1
  11. 什么是狭义人工智能、通用人工智能和超级人工智能?
  12. Redis集群:./redis-trib.rb:24:in `require': no such file to load -- rubygems
  13. ArcGIS 地类净面积计算工具
  14. MySQL参数max_connect_errors分析释疑
  15. dnw驱动更新,支持全系统(xp,win7,win8/win10)
  16. c++11的regex使用
  17. linux--服务器降频
  18. Merry Christmas 圣诞树html+css+js,c++,python实现
  19. python画图横坐标_python画图把时间作为横坐标的方法
  20. 图片去水印软件教程-图片如何在线去水印

热门文章

  1. word设置多级列表
  2. 5种AI编程语言优缺点比较,谁才是程序员心中的白月光
  3. 电脑搜索不到部分wifi,搜索不到部分2.4G频率的wif,手机开热点电脑搜不到wifi。
  4. 6-使用VMWARE虚拟机调试XPE的方法
  5. 第四章 字体和格式相关
  6. C++ 模板问题(一) -- 如何识别模板类型
  7. 水粉中的这两种绘画方法?你经常用哪种?
  8. Page Peel View
  9. NumPy 基础教程
  10. html怎么创建一个盒子,怎么新建一个实线边框为红色盒子