末尾附cubemx文件与keil文件。

SPI/IIC 接口模块
模块接口定义:
1. GND 电源地
2. VCC 电源正(3~ 5.5V )
3. D0           OLED 的 D0 脚,在 SPI 和 IIC 通信中为时钟管脚
4. D1           OLED 的 D1 脚,在 SPI 和 IIC 通信中为数据管脚
5. RES        OLED 的 RES# 脚,用来复位(低电平复位)
6. DC          OLED 的 D/C#E 脚,数据和命令控制管脚
7. CS           OLED 的 CS# 脚,也就是片选管脚

原理图如下:

SSD1306的显存大小为128*64bit,内部储存中分为8页,每页128字节,对应128*64的点阵大小

SSD1306由命令集控制,如下是开发手册中的一个命令表

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

命令0xA4/A5:0xA4,即X0=0:恢复到RAM内容显示(RESET),输出遵循RAM内容;0xA5,即X0=1:整个显示打开,输出忽略RAM内容。

命令0xA6/0xA7: 0xA6,即X0=0: 0在RAM中表OFF,1在RAM中表ON;0xA7为反转模式,与之相反。
命令0XAE/0XAF:0XAE为关闭显示命令;0XAF为开启显示命令。
命令0X8D:包含2个字节,第一个为命令字,第二个为设置值,第二个字节的BIT2表示电荷泵的开关状态,该位为1,则开启电荷泵,为0则关闭。在模块初始化的时候,这个必须要开启,否则是看不到屏幕显示的。
命令0XB0~B7:用于设置页地址,其低三位的值对应着GRAM的页地址。命令0X00-0XOF:用于设置显示时的起始列地址低四位。
命令0X10~0X1F用于设置显示时的起始列地址高四位。

OLED显示过程:1.复位  2.SSD1306初始化 3.开启显示  4.清零显存 5.开始显示

2. SSD1306初始化:

void OLED_Init(void)
{   GPIO_InitTypeDef GPIO_InitStruct = {0};__HAL_RCC_GPIOB_CLK_ENABLE();GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_12|GPIO_PIN_13;//配置管脚为输出GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_12|GPIO_PIN_13, GPIO_PIN_SET);HAL_Delay(100);OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panelOLED_WR_Byte(0x00,OLED_CMD);//---set low column addressOLED_WR_Byte(0x10,OLED_CMD);//---set high column addressOLED_WR_Byte(0x40,OLED_CMD);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control registerOLED_WR_Byte(0xCF,OLED_CMD); // Set SEG Output Current BrightnessOLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常OLED_WR_Byte(0xA6,OLED_CMD);//--set normal displayOLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 dutyOLED_WR_Byte(0xD3,OLED_CMD);//-set display offset  Shift Mapping RAM Counter (0x00~0x3F)OLED_WR_Byte(0x00,OLED_CMD);//-not offsetOLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequencyOLED_WR_Byte(0xf0,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/SecOLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge periodOLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 ClockOLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configurationOLED_WR_Byte(0x12,OLED_CMD);OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomhOLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect LevelOLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)OLED_WR_Byte(0x02,OLED_CMD);//OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disableOLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disableOLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7) OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panelOLED_WR_Byte(0xAF,OLED_CMD); /*display ON*/ OLED_Clear();OLED_Set_Pos(0,0);
}  

3.开启显示

3.1 向ic写入一个字节

/向SSD1306写入一个字节。
//dat:要写入的数据/命令
//cmd:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(u8 dat,u8 cmd)
{   u8 i;             if(cmd)OLED_DC_Set();else OLED_DC_Clr();        OLED_CS_Clr();for(i=0;i<8;i++)//8位命令/数据{              OLED_SCLK_Clr();if(dat&0x80)//0x80=1000 0000 从首位开始读OLED_SDIN_Set();else OLED_SDIN_Clr();OLED_SCLK_Set();dat<<=1;   //读完左移一位,读下一位}                        OLED_CS_Set();OLED_DC_Set();
} 

先通过cmd判断此次是写入命令还是数据,再决定将DC拉低或者拉高。

数据/命令写入前,先将CS拉低,开启数据通道,SCLK需一个上升沿触发写入,所以需要先拉低,SDIN获得一位数据后,SCLK拉高,将数据写入SPI。

8位数据/命令写入完成后,CS拉高,关闭数据通道,再将DC拉高,下次再判断是写入数据还是命令。

3.2 开启显示

//开启OLED显示
void OLED_Display_On(void)
{OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令OLED_WR_Byte(0X14,OLED_CMD);  //DCDC ONOLED_WR_Byte(0XAF,OLED_CMD);  //DISPLAY ON
}
//关闭OLED显示
void OLED_Display_Off(void)
{OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令OLED_WR_Byte(0X10,OLED_CMD);  //DCDC OFFOLED_WR_Byte(0XAE,OLED_CMD);  //DISPLAY OFF
}           

4. 通过字节命令清除RAM缓存(清屏)

//清屏函数,所有像素点熄灭。
void OLED_Clear(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(0,OLED_DATA); } //更新显示
}

通过B0~B7命令选页,再由00~0F命令设置列地址的第四位,10~1F命令设置列地址的高四位,我们需要将所有像素点置为0,从0地址开始,高四位和第四位均为0,再执行128次写字节,将全部显存位置0,一共有8页,每次选择一页,故for循环执行8次。

5.1 OLED字符显示

//将指针移动到指定的点位
void OLED_Set_Pos(unsigned char x, unsigned char y)
{ OLED_WR_Byte(0xb0+y,OLED_CMD);OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);OLED_WR_Byte((x&0x0f)|0x01,OLED_CMD);
}   

SetPos的功能是将指针移动到指定的点位

//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白显示;1,正常显示
//size:选择字体 16/12
void OLED_ShowChar(u8 x,u8 y,u8 chr)
{       unsigned char c=0,i=0;    c=chr-' ';//得到偏移后的值          if(x>Max_Column-1){x=0;y=y+2;}if(SIZE ==16){OLED_Set_Pos(x,y);  for(i=0;i<8;i++)OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);OLED_Set_Pos(x,y+1);for(i=0;i<8;i++)OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);}else {   OLED_Set_Pos(x,y+1);for(i=0;i<6;i++)OLED_WR_Byte(F6x8[c][i],OLED_DATA);}
}

F8X16和F6X8数组由取模软件生成,存在oledfont.h库中,分别对应6*8的点阵和8*16的点阵,是两种不同的字体。

5.2  OLED汉字显示

同样的,如果想显示汉字或者任意图案,都可以通过取模软件绘制,然后导出生成数组,如下图所示

我采用的字体点阵大小为16*16,故我的汉字显示函数为:

//显示汉字
void OLED_ShowCHinese(u8 x,u8 y,u8 no)
{                   u8 t,adder=0;OLED_Set_Pos(x,y);    for(t=0;t<16;t++){OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);adder+=1;}   OLED_Set_Pos(x,y+1);   for(t=0;t<16;t++){    OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);adder+=1;}
}

no对应数组中存放汉字的下标,0~3共4位分别为‘扎’,‘西’ ,‘德’,‘勒’,16*16的点阵需要两个page存储,故下标0需要拆分为2*0和2*0+1两组,每组16个8位2进制数,通过命令控制,两个2进制数对应一列8个像素点,两组数据实现一个字的显示。

以下是笔者所使用的芯片原理图及keil工程文件与cubemx项目文件,各位想进行显示实验的,如果无法输出正确结果,可以修改cubemx配置文件重新生成keil工程或者在keil里修改对应引脚的参数

文件下载链接(蓝奏云):

https://wwi.lanzoup.com/i6JXC0sijq1i

0.96寸OLED12864屏幕控制(原理+代码)相关推荐

  1. 四针脚0.96寸OLED屏幕标准库代码转Cube Max创建的HAL库工程代码

    stm32学了一个多月了. 刚开始是跟着江科大学的,讲的很好,里面是用标准库. 后来因为Hal库用着简单,就开始学习Hal库,跟的是b站的[小蜜蜂笔记]基于STM32CubeMX的嵌入式开发基础教程. ...

  2. STM32(基于HAL库)驱动0.96寸OLED屏幕(六脚)

    STM32驱动0.96寸OLED屏幕(六脚) 1 序言 2 如何利用STM32单片机驱动12864液晶屏 2.1*基本配置* 2.2 *0.96寸OLED端口含义* 2.3 *0.96寸OLED液晶屏 ...

  3. NRF51822---驱动0.96寸OLED屏幕(连载4)

    NRF51822---驱动0.96寸OLED屏幕(连载4) 前言 屏幕简介 连接方法 驱动原理 IIC SSD1306 代码实现 总结 前言 上节讲解了IIC的协议,并用STM32实践了一下.今天趁热 ...

  4. 0.96寸oled屏幕在任意区域画点

    首先,我使用的是SPI协议的0.96寸oled屏幕,如图 相信大家在淘宝下单的时候,能以各种渠道获得"中景园科技"的关于驱动该屏幕的源码,但令人遗憾的是,源码中仅仅包含了写数字,写 ...

  5. CX32l003 点亮0.96寸OLED屏幕

    之前的文章写了很多关于CX32L003芯片的程序代码,几乎都是应用的芯片内部资源,对于这款低成本的芯片还能做些什么功能呢.本篇文章采用cx32l003单片机实现点亮0.96寸的OLED屏幕. OLED ...

  6. STM32(基于HAL库)驱动0.96寸OLED屏幕(四脚且中英文皆可显示)

    STM32驱动0.96寸OLED屏幕(四脚) 1 注意事项 2 如何利用STM32单片机驱动12864液晶屏 2.1*基本配置* 2.2 *0.96寸OLED端口含义* 2.3 *0.96寸OLED液 ...

  7. 用esp8266驱动0.96寸OLED屏幕 太空人动画

    昨天闲来没事玩了一下OLED屏幕 之前只是做过显示图片 还没弄过动画的 (其实差不多–) 用esp8266驱动0.96寸LED屏幕 太空人动画 入门esp8266 看这篇文章 参考https://bl ...

  8. 0.96寸_OLED_屏幕_SSD1306_IIC通信_入门教程_指令详解_驱动介绍_笔记分享_初学者易懂

    目录 一.简介 1:总结 2:屏幕介绍 二.基本使用流程 1_介绍: 2_流程:(省略了应答) 三.指令集 1.基础指令 1:设置对比度(亮度)(81H + A[7:0]) 2:设置全屏全亮(A4H. ...

  9. 0.96寸OLED屏幕_清行

    记: OLED例程里面的函数库只有清屏的函数.. 对于想实现只想清行的我. 首先记录一下相关的显示原理. OLED控制器为SSD1306,也就是说:裸屏由SSD1306驱动. OLED模块显存 OLE ...

最新文章

  1. UVa1112 - Mice and Maze(Dijkstra和Floyd_warshall)
  2. k8s多master建议用几个_K8s 还是 k3s?This is a question
  3. 大数据与web开发整合的最佳实践-思考
  4. EF Core 插件 —— ToSql
  5. 特征工程之数据预处理(上)
  6. 互联网金融行业申请评分卡(A卡)简介
  7. 智能路由器-OpenWRT 系列三 (OpenWRT安装LuCI网络配置)
  8. Windows下配置OpenSSL(傻瓜式教程,一看就会)
  9. 【Hibernate】ch01Demo
  10. Linux系统进程优先级——计算方式
  11. HbuilderX下载安装教程
  12. 搭建一个完整的实时日志统计平台
  13. android 基础知识-LOG和版本解释
  14. 关于curses 安装
  15. 如何从官网下载 Google Chrome 64位离线安装包
  16. CTF-隐写术(六)
  17. Android 自定义View 滑动解锁
  18. SpringBoot分片上传、断点续传、大文件极速秒传功能(典藏版)
  19. 狂神说HTML5 + CSS + JavaScript 笔记(已完结)
  20. Adobe的音频编辑软件Adobe Audition (Au)2023版本下载与安装教程

热门文章

  1. 苹果工具条_苹果iOS 13.4 Beta 1来袭:网友直接吐槽0创新
  2. 支付行业-银行渠道对接
  3. PHP简单的学生管理系统的代码
  4. 《Python基础知识-4判断和循环语句》
  5. 【程序】 一位前辈的编程经历(转)
  6. Android脑图--Android动画
  7. stm32将flash虚拟成U盘来下载程序
  8. 大部分人朋友圈仅三天可见的原因,竟然是……
  9. 什么是迭代计算机编程,什么是递归?什么是迭代?
  10. 举头望明月,低头敲代码