STM32学习笔记(12)OLED(IIC接口)

简介

OLED:Organic Light-Emitting Diode,即有机发光二极管,又称为有机电激光显示(Organic Electroluminesence Display,OELD)。

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

stm32使用的OLED有多种模式可以选择,包括8080模式(13条信号线),6800模式(13条信号线),SPI模式(四线),IIC模式(两线)(也被称为I2C),四种模式通过模块的BS1及BS2进行设置。本文主要介绍IIC模式的原理及相关代码配置。

8080与6800的区别:存取的控制
8080是通过“读使能(RE)”和“写使能(WE)”两条控制线进行读写操作
6800是通过“总使能(E)”和“读写选择(W/R)”两条控制线进行

硬件相关

SSD1306控制

SSD1306,即OLED上的芯片。
在这里插入图片描述

0:这个命令包含了两个字节,第一个 0X81 为命令(预告即将发出设置对比度的值),随后发送的一个字节为要设置的对比度的值。
1:0XAE 为关闭显示命令; 0XAF 为开启显示命令 。
2:第一个 0X8D为命令,第二个字节 表示电荷泵的开关状态 。(必开,否则看不到显示)
3:用于设置页地址,其低三位的值对应页地址。 (三位可以设置8个地址)

OLED显存

SSD1306的显存容量总共为128*64bit,SSD1306将这些显存分为8page,每个page包含8行,每行128bit,即每一page包含128个字节。

显存:用来存储要处理的图形信息的部件(大概就等于内存吧)

在这里插入图片描述

初始化过程

在这里插入图片描述

操作相关

写入数据(或命令)

在这里插入图片描述
总结一下,每一次写入数据(或命令)的步骤:
1.使用起始信号 I2C_Start();
2.发送OLED地址:0x78 Send_Byte(0x78);
3.发送应答信号 I2C_WaitAck();
4.发送寄存器地址(命令或数据)
5.发送应答信号
6.发送命令或数据
7.再一次发送应答信号
8.使用结束信号 I2C_Stop();;

//mode:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(u8 dat,u8 mode)
{
 I2C_Start();
 Send_Byte(0x78);
 I2C_WaitAck();
 if(mode){Send_Byte(0x40);}
  else{Send_Byte(0x00);}
 I2C_WaitAck();
 Send_Byte(dat);
 I2C_WaitAck();
 I2C_Stop();
}

开始信号:让SCL时钟保持高电平,然后让SDA数据信号由高变低表示一个开始信号。当IIC总线上的设备检测到开始信号就知道处理器要发送数据。
停止信号:让SCL时钟保持高电平,然后让SDA数据信号由低变高表示一个停止信号。当IIC总线上的设备检测到停止信号就知道处理器结束数据传输。

寻址模式

OLED的显存分为8page,每个page都有8行,每行又有128个位,为了控制总共128* 8* 8个bit,总共有三种寻址模式。(即寻找相应的地址来控制相应位)

页寻址模式

在这里插入图片描述
该模式下,显示RAM读/写后,列地址指针自动加一(每一列8位),当列地址指针到达列结束地址,自动重置为列开始地址,页地址指针不变。需要设置新的页和列地址才能去到下一页。

水平寻址模式

在这里插入图片描述
该模式下,显示RAM读/写后,列地址指针自动加一(每一列8位),当列地址指针到达列结束地址,列地址指针重置为列开始地址,页地址指针增加。当页地址与列地址指针都到达结束地址,指针重置为列起始地址与页起始地址。

垂直寻址模式

在这里插入图片描述
该模式下,显示RAM读/写后,页地址指针自动加一,当页地址指针到达页结束地址,页地址指针重置为页开始地址,列地址指针增加。当页地址与列地址指针都到达结束地址,指针重置为列起始地址与页起始地址。

代码相关

1.开启OLED显示

void OLED_DisPlay_On(void)
{
 OLED_WR_Byte(0x8D,OLED_CMD);//电荷泵使能
 OLED_WR_Byte(0x14,OLED_CMD);//开启电荷泵
 OLED_WR_Byte(0xAF,OLED_CMD);//点亮屏幕
}

2.关闭OLED显示

void OLED_DisPlay_Off(void)
{
 OLED_WR_Byte(0x8D,OLED_CMD);//电荷泵使能
 OLED_WR_Byte(0x10,OLED_CMD);//关闭电荷泵
 OLED_WR_Byte(0xAE,OLED_CMD);//关闭屏幕
}

3.画点

void OLED_DrawPoint(u8 x,u8 y,u8 t)
{
 u8 i,m,n;
 i=y/8;//确定页
 m=y%8;//确定行
 n=1<<m;//计算点在页的位置
 if(t){OLED_GRAM[x][i]|=n;}
 else
 {
  OLED_GRAM[x][i]=~OLED_GRAM[x][i];
 }
}

4.更新内存

void OLED_Refresh(void)
{
 u8 i,n;
 for(i=0;i<8;i++)
 {
  OLED_WR_Byte(0xb0+i,OLED_CMD); //设置行起始地址
  OLED_WR_Byte(0x00,OLED_CMD);   //设置低列起始地址
  OLED_WR_Byte(0x10,OLED_CMD);   //设置高列起始地址
  I2C_Start();
  Send_Byte(0x78);
  I2C_WaitAck();
  Send_Byte(0x40);
  I2C_WaitAck();
  for(n=0;n<128;n++)
  {
   Send_Byte(OLED_GRAM[n][i]);
   I2C_WaitAck();
  }
  I2C_Stop();
  }

5.显示16*16的任意符号(通过字模获取)

void OLED_ShowChinese(u8 x,u8 y,u8 num,u8 mode)
{
 u8 m,temp;
 u8 x0=x,y0=y;
 u16 i,size=16*16;  //得到字体一个字符对应点阵集所占的字节数
 for(i=0;i<size;i++)
 {

  for(m=0;m<8;m++)
  {
   if(temp&0x01)OLED_DrawPoint(x,y,mode);
   else OLED_DrawPoint(x,y,!mode);
   temp>>=1;
   y++;
  }
  x++;
  if((x-x0)==16)
  {x=x0;y0=y0+8;}
  y=y0;
 }
}

6.相应引脚时钟使能及OLED的初始化

void OLED_Init(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;//初始化相应结构体
  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG|RCC_APB2Periph_GPIOD, ENABLE);  //使能A端口时钟
 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;  
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;    //推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
  GPIO_Init(GPIOG, &GPIO_InitStructure);   //初始化GPIOG12
  GPIO_SetBits(GPIOG,GPIO_Pin_12);//初始化IO口PG12,后为SCL
  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;    //推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
  GPIO_Init(GPIOD, &GPIO_InitStructure);   //初始化GPIOD5
  GPIO_SetBits(GPIOD,GPIO_Pin_5);//初始化IO口PD5,后为SDA
 
  delay_ms(200);

  OLED_WR_Byte(0xAE,OLED_CMD);//显示关闭 0xAF是开启  0xAE是关闭
  OLED_WR_Byte(0x00,OLED_CMD);//设置低列地址
  OLED_WR_Byte(0x10,OLED_CMD);//设置高列地址
  OLED_WR_Byte(0x40,OLED_CMD);//设置起始行地址(0x00~0x3F)
  
  OLED_WR_Byte(0x81,OLED_CMD);//对比度设置指令
  OLED_WR_Byte(0xCF,OLED_CMD);// 设置输出电流亮度
 
  OLED_WR_Byte(0xA1,OLED_CMD);//设置分段/列映射,IIC需要设置为0xA1
  OLED_WR_Byte(0xC8,OLED_CMD);//设置COM扫描方向   0xc0上下反置,COM0到COM N-1 左到右 0xc8正常 COM N-1到COM0  右到左
  OLED_WR_Byte(0xA6,OLED_CMD);//设置显示方式为正常显示
  
  OLED_WR_Byte(0xA8,OLED_CMD);//设置分辨率(1 to 64)
  OLED_WR_Byte(0x3f,OLED_CMD);//分辨率为128*64:0x3f
 
  OLED_WR_Byte(0xD3,OLED_CMD);//设置显示偏移
  OLED_WR_Byte(0x00,OLED_CMD);//默认值00 无偏移
 
  OLED_WR_Byte(0xd5,OLED_CMD);//设置显示时钟分频/振荡器频率
  OLED_WR_Byte(0x80,OLED_CMD);//将时钟设置为100帧/秒 
 
  OLED_WR_Byte(0xD9,OLED_CMD);//设置预充电时期
  OLED_WR_Byte(0xF1,OLED_CMD);//预充电设为15时钟,放电设为1时钟 
 
  OLED_WR_Byte(0xDA,OLED_CMD);//-设置COM硬件引脚配置,适应分辨率
  OLED_WR_Byte(0x12,OLED_CMD);
  
  OLED_WR_Byte(0xDB,OLED_CMD);//设置VCOMH
  OLED_WR_Byte(0x40,OLED_CMD);//设置VCOM取消选择级别 
  
  OLED_WR_Byte(0x20,OLED_CMD);//页面寻址模式(0x00/0x01/0x02)
  OLED_WR_Byte(0x02,OLED_CMD);//页寻址
 
  OLED_WR_Byte(0x8D,OLED_CMD);//充电泵设置可用或者不可用
  OLED_WR_Byte(0x14,OLED_CMD);//可用
  
  OLED_WR_Byte(0xA4,OLED_CMD);//0xa4,输出遵循RAM内容    0xa5,输出忽略RAM内容
  OLED_WR_Byte(0xA6,OLED_CMD);//设置显示方式,正常显示:0xA6,反相显示:0xA7 
  
  OLED_Clear();
  OLED_WR_Byte(0xAF,OLED_CMD);//设置完毕,显示开启
}

附:取模工具

取模工具

使用工具:PCtoLCD2002
在这里插入图片描述

配置

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章