前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一文彻底了解SSD1306驱动0.96寸OLED

一文彻底了解SSD1306驱动0.96寸OLED

作者头像
ManInRoad
发布2021-03-10 13:40:41
10.4K0
发布2021-03-10 13:40:41
举报
文章被收录于专栏:物联网思考

前言:整理东西的时候,翻出了一个OLED,驱动起来玩一玩。先上一张图,显示了字符串、汉字。本文驱动在esp32、stm8、efm32,es32上面均已验证通过过。

在淘宝上找了一些资料,但是要想彻底理解如何驱动,还是要看驱动芯片的手册。

这个模块默认是使用SPI通讯的,如果要使用I2C通讯,需要把R3电阻取下来,焊接到R1的位置,如上图。

首先,需要说明的一点,显示屏都需要控制器;所谓显示,其实就是操作控制芯片,包括入门级别的LCD1602、LCD12864都是集成了控制芯片的,不同厂家用的控制芯片可能不同,像LCD1602、LCD12864这些的控制芯片基本上驱动都是一样的,这也是我们在驱动这些的时候,没有去研究所用的控制芯片的原因。

图中的0.96寸OLED,所用的控制芯片正是SSD1306,不同厂家可以用不同的驱动芯片,要让OLED显示,其实就是要驱动SSD1306。

SSD1306支持多种控制方式,I2C、6800、8080、4线SPI、3线SPI,通过BS0、BS1、BS2引脚接不同的电平来选择控制方式,此次我们使用I2C来控制,那么需要BS0接GND、BS1接VCC、BS2接GND,如下datasheet中描述的:

针对本模块我们还需用到的其他引脚:

复位信号引脚,在显示的时候保持高电平。

1、I2C通讯

(1)通过D/C#(datasheet中的SA0)这个引脚来扩展I2C地址,这个引脚接VCC或者GND,对应不同的地址;

(2)需要将D1和D2接在一起作为SDA;

(3)D0为SCL;

(4)SCL和SDA需接外部上拉,这也是I2C通讯最基本的要求;

(5)RES#引脚用于初始化,需要在硬件设计上注意。

2、写I2C

(1)发送地址之后,发送控制数据或者命令数据字节;这个字节由Co位和D/C#位以及6个0组成;

(2)如果Co位为0,那么后续的信息都是数据;

(3)D/C#位决定了下一个数据是命令还是数据,如果D/C#位是0,那么后面的数据是命令,如果D/C#位是1,那么后面的数据是数据将被存储在GDDRAM中。

(4)基本控制规律就是,发送I2C地址,发送命令或者数据控制字节、发送数据或者命令。

3、原理设计

模块带的原理图,可以看出来,通过R8将D1和D2连在了一起,这也符合手册中的要求,但是我们主要是向SSD1306写数据,所以这个R8也可以不接。如果需要读数据的话,就需要接上。

4、显存

显存大小128*64,分8个页,PAGE0~PAGE7,128列。

一次写8个像素点,即同一个page内的同一列8个点。一个字节的8个bit刚好对应D0到D7(根据这个特性,我们取模的时候,首先要按列取模)。

5、寻址模式

三种寻址模式:页寻址、水平寻址、垂直寻址。

寻址模式设置命令:

5.1、页寻址(默认的寻址方式,我们用这种寻址,综合上面的列式取模,因此我们用列行式的取模方式)

(1)列地址指针每次自动加1,如果列地址指针到达最后一个地址,将会自动复位到开始的地址,页地址指针不变;

(2)为了访问下一个页面RAM内容,用户必须设置新的页面和列地址;

(3)页地址的范围0-7,对应的命令是B0-B7;

(4)低列地址的设置命令是00-0FH,高列地址的设置命令是10h-1Fh。

页寻址模式设置命令:

5.2、水平寻址模式

列地址指针每次自动加1,如果列地址指针到达最后一个地址,将会自动复位到开始的地址,页地址指针也加1。

5.3、垂直寻址模式

页地址指针每次自动加1,如果页地址指针到达最后一个地址,将会自动复位到开始的地址,列地址指针也加1。

水平或者垂直寻址模式设置命令:

6、代码实现

6.1、I2C写

代码语言:javascript
复制

代码语言:javascript
复制
void SSD1306_WriteCmd(uint8 cmd){  I2C_Start();  I2C_SendByte(SSD1306_I2C_ADDR | 0x00);          I2C_Ack();  I2C_SendByte(0x00);   //cmd  I2C_Ack();  I2C_SendByte(cmd);     I2C_Ack();  I2C_Stop();                }
void SSD1306_WriteData(uint8 data){  I2C_Start();  I2C_SendByte(SSD1306_I2C_ADDR | 0x00);          I2C_Ack();  I2C_SendByte(0x40);   //data  I2C_Ack();  I2C_SendByte(data);     I2C_Ack();  I2C_Stop(); }

6.2、OLED驱动

代码语言:javascript
复制
//SSD1306初始化void OLED_Init(void){  _delay_ms(1000);  //SSD1306复位之后,默认的是页寻址方式
  SSD1306_WriteCmd(0xAE);//--display off
  SSD1306_WriteCmd(0x00);//--set low column address  SSD1306_WriteCmd(0x10);//--set high column address  SSD1306_WriteCmd(0x40);//--set start line address  
  SSD1306_WriteCmd(0xB0);//--set page address
  SSD1306_WriteCmd(0x81);// contract control  SSD1306_WriteCmd(0xFF);//--128     SSD1306_WriteCmd(0xA1);//set segment re-map  0 to 127   SSD1306_WriteCmd(0xA6);//set normal  display    SSD1306_WriteCmd(0xA8);//set multiplex ratio(1 to 64)  SSD1306_WriteCmd(0x3F);//--1/32 duty
  SSD1306_WriteCmd(0xC8);//Com scan direction  SSD1306_WriteCmd(0xD3);//set display offset  SSD1306_WriteCmd(0x00);//no offset
  SSD1306_WriteCmd(0xD5);//set display clock divide ratio/oscillator frequency    SSD1306_WriteCmd(0x80);//
  SSD1306_WriteCmd(0xD8);//set area color mode off  SSD1306_WriteCmd(0x05);//
  SSD1306_WriteCmd(0xD9);//Set Pre-Charge Period  SSD1306_WriteCmd(0xF1);//
  SSD1306_WriteCmd(0xDA);//set com pin  hardware configuartion  SSD1306_WriteCmd(0x12);//
  SSD1306_WriteCmd(0xDB);//set Vcomh  SSD1306_WriteCmd(0x30);//0x20,0.77xVcc
  SSD1306_WriteCmd(0x8D);//set charge pump enable  SSD1306_WriteCmd(0x14);//
  SSD1306_WriteCmd(0xAF);//--turn on oled panel}

代码语言:javascript
复制
//坐标设置:也就是在哪里显示void OLED_SetPos(uint8 x, uint8 y) {   //以下3个寄存器只在页寻址的模式下有效    SSD1306_WriteCmd(0xb0+y);             //页地址设置     0xb0~0xb7  SSD1306_WriteCmd(((x&0xf0)>>4)|0x10); //列高位地址设置  SSD1306_WriteCmd((x&0x0f));           //列低位地址设置}

代码语言:javascript
复制
//开启OLED显示void OLED_DisplayOn(void){  SSD1306_WriteCmd(0X8D);  //SET DCDC命令  SSD1306_WriteCmd(0X14);  //DCDC ON  SSD1306_WriteCmd(0XAF);  //DISPLAY ON}
代码语言:javascript
复制
//关闭OLED显示   void OLED_DisplayOff(void){  SSD1306_WriteCmd(0X8D);  //SET DCDC命令  SSD1306_WriteCmd(0X10);  //DCDC OFF  SSD1306_WriteCmd(0XAE);  //DISPLAY OFF}
代码语言:javascript
复制
//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样  void OLED_Clear(void)  {    uint8 i,n;  
  for(i=0;i<8;i++)    {      SSD1306_WriteCmd (0xb0+i);    //设置页地址(0~7)    SSD1306_WriteCmd (0x00);      //设置显示位置—列低地址    SSD1306_WriteCmd (0x10);      //设置显示位置—列高地址       for(n=0;n<128;n++)      SSD1306_WriteData(0);   } //更新显示}

代码语言:javascript
复制
//在指定位置显示一个字符,包括部分字符//x:0~127,y:0~7//Char_Size:选择字体 16/12 void OLED_ShowChar(uint8 x,uint8 y,uint8 chr,uint8 Char_Size){          uint8 c=0,i=0;  
  c=chr-' ';//得到偏移后的值        if(x>MAX_COLUMN-1)  {    x=0;    y=y+2;  }  if(Char_Size ==16)  {    OLED_SetPos(x,y);      for(i=0;i<8;i++)    {      SSD1306_WriteData(F8X16[c*16+i]);//先写上半部分    }
    OLED_SetPos(x,y+1);    for(i=0;i<8;i++)    {      SSD1306_WriteData(F8X16[c*16+i+8]);//后写下半部分    }  }  else  {      OLED_SetPos(x,y);    for(i=0;i<6;i++)    {      SSD1306_WriteData(F6x8[c][i]);    }  }}
代码语言:javascript
复制
//显示一个字符串void OLED_ShowString(uint8 x,uint8 y,char *str,uint8 Char_Size){  unsigned char j=0;
  while (str[j]!='\0')  {    OLED_ShowChar(x,y,str[j],Char_Size);    x+=8;    if(x>120)    {      x=0;      y+=2;    }    j++;//移动一次就是一个page,取值0-7  }}
代码语言:javascript
复制
//显示汉字//由于汉字是16*16大小的,所以最多显示4行汉字//index:在汉字取模中的索引void OLED_ShowCN(uint8 x,uint8 y,uint8 index){                  uint8 t;
  OLED_SetPos(x,y);    for(t=0;t<16;t++)  {    SSD1306_WriteData(Hzk[index][t]);  }  
  OLED_SetPos(x,y+1);    for(t=0;t<16;t++)  {      SSD1306_WriteData(Hzk[index][t+16]);  }          }

6.3、测试代码

也就是我们在开头看到的图片。

代码语言:javascript
复制

代码语言:javascript
复制
void OLED_DisplayTest(void){  OLED_Clear(); 
  OLED_ShowCN(40,0,0);  OLED_ShowCN(56,0,1);  OLED_ShowCN(72,0,2);
  OLED_ShowCN(24,2,3);  OLED_ShowCN(40,2,4);  OLED_ShowCN(56,2,5);  OLED_ShowCN(72,2,6);  OLED_ShowCN(88,2,7);
  OLED_ShowString(0,4,(char *)("LoRa stm32 gd32 "),16);  OLED_ShowString(0,6,(char *)("esp32...IoT."),16);}

相关推荐:

LoRa点对点通信,OLED显示(内附代码)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-03-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 物联网思考 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言:整理东西的时候,翻出了一个OLED,驱动起来玩一玩。先上一张图,显示了字符串、汉字。本文驱动在esp32、stm8、efm32,es32上面均已验证通过过。
  • 1、I2C通讯
  • 2、写I2C
  • 3、原理设计
  • 4、显存
  • 5、寻址模式
  • 6、代码实现
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档