OLED显示实验

一.参考资料

  1. 战舰/精英STM32F1开发板
    《STM32F1开发指南-库函数版本》-第17章 OLED显示实验

  2. miniSTM32F1开发板

    《STM32不完全手册-库函数版本》 -第15章 OLED显示实验

  3. 探索者STM32F4开发板
    《STM32F4开发指南-库函数版本》 -第17章 OLED显示实验

二.OLED实验

1.OLED

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

OLED显示技术具有自发光的特性,采用非常薄的有机材料涂层和玻璃基板,当有电流通过时,这些有机材料就会发光,而且OLED显示屏幕可视角度大,并且能够节省电能,从2003年开始这种显示设备在MP3播放器上得到了应用。
LCD都需要背光,而OLED不需要,因为它是自发光的。这样同样的显示,OLED效果要来得好一些。以目前的技术,OLED的尺寸还难以大型化,但是分辨率确可以做到很高。

2.ALINETEK 0.96 寸OLED模块

  1. 模块有单色和双色两种可选,单色为纯蓝色,而双色则为黄蓝双色。
    单色模块每个像素点只有亮与不亮两种情况,没有颜色区分。

  2. 尺寸小,显示尺寸为0.96寸,而模块的尺寸仅为27mm26mm大小。

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

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

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

  6. 这里要提醒大家的是,该模块不和5.0V接口兼容,所以请大家在使用的时候一定要小心,别直接接到5V的系统上去,否则可能烧坏模块

    OLED模块

3.OLED模块工作模式选择

4种模式通过模块的BS1/BS2设置,BS1/BS2的设置与模块接口模式的关系如表所示:

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

4.OLED模块原理图

OLED模块原理图

5.OLED 8080并行接口信号线说明

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

OLED控制器为SSD1306

OLED 8080并行接口信号线说明

6.OLED8080并口读写过程

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

并口写时序图 并口读时序图

7.OLED模块显存

SSD1306的显存总共为128*64bit大小,SSD1306将这些显存分为了8页。每页包含了128个字节,总共8页,这样刚好是128*64的点阵大小。
模块显存

8.程序显示原理

在STM32的内部建立一个 缓存*(共1288个字节),在每次修改的时候,只是修改STM32上的缓存(实际上就是SRAM),在修改完了之后,一次性把STM32上的缓存数据写入到OLED的GRAM**。当然这个方法也有坏处,就是对于那些SRAM很小的单片机(比如51系列)就比较麻烦了。

9.SSD1306的命令

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

10.OLED初始化过程

OLED初始化过程
//初始化SSD1306                        
void OLED_Init(void)
{
 …//设置IO口模式,所有用到的io口设置为推挽模式。
GPIO_Init();
 …//初始化代码,写相关寄存器
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_Clear();
}

11.OLED写一个字节

//向SSD1306写入一个字节。
//dat:要写入的数据/命令
//cmd:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(u8 dat,u8 cmd)
{
   DATAOUT(dat);        
  if(cmd)
     OLED_RS_Set();
  else 
     OLED_RS_Clr();        
  OLED_CS_Clr();
  OLED_WR_Clr();     
  OLED_WR_Set();
  OLED_CS_Set();      
  OLED_RS_Set();     
}
OLED写一个字节

12.OLED更新缓存,显示内容。

u8 OLED_GRAM[128][8];   

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); 
  }   
}
地址

13.OLED画点函数

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

14.OLED字符显示函数

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

15.字符码表

const unsigned char oled_asc2_1206[95][12]={
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
{0x18,0x00,0x24,0xC0,0x1B,0x00,0x0D,0x80,0x32,0x40,0x01,0x80},/*"%",5*/
{0x03,0x80,0x1C,0x40,0x27,0x40,0x1C,0x80,0x07,0x40,0x00,0x40},/*"&",6*/
…
{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x40,0x06,0x40,0x00,0x00},/*"c",67*/
{0x00,0x00,0x03,0x80,0x04,0x40,0x24,0x40,0x3F,0xC0,0x00,0x40},/*"d",68*/
…
{0x00,0x00,0x40,0x20,0x7B,0xE0,0x04,0x00,0x00,0x00,0x00,0x00},/*"}",93*/
{0x40,0x00,0x80,0x00,0x40,0x00,0x20,0x00,0x20,0x00,0x40,0x00},/*"~",94*/
};
const unsigned char oled_asc2_1608[95][16]={      
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/ {0x0F,0x00,0x10,0x84,0x0F,0x38,0x00,0xC0,0x07,0x78,0x18,0x84,0x00,0x78,0x00,0x00},/*"%",5*/
{0x00,0x78,0x0F,0x84,0x10,0xC4,0x11,0x24,0x0E,0x98,0x00,0xE4,0x00,0x84,0x00,0x08},/*"&",6*/
…
{0x00,0x00,0x1C,0x00,0x10,0x00,0x10,0xFC,0x13,0x00,0x1C,0x00,0x10,0x00,0x00,0x00},/*"7",23*/
{0x00,0x00,0x0E,0x38,0x11,0x44,0x10,0x84,0x10,0x84,0x11,0x44,0x0E,0x38,0x00,0x00},/*"8",24*/
{0x00,0x00,0x07,0x00,0x08,0x8C,0x10,0x44,0x10,0x44,0x08,0x88,0x07,0xF0,0x00,0x00},/*"9",25*/
}

16.其他

PCtoLCD 字模选项 字节
最后修改:2020 年 02 月 06 日 11 : 44 AM
如果觉得我的文章对你有用,请随意赞赏