OLED显示屏显示设置内容

1,148 阅读3分钟

这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战

STM32

前言

=====

目前单片机、机器人或者嵌入式常用的就是LCD或者OLED屏,在前面的一篇文章里已经详细的介绍了LCD1602,在以下内容里我会详细介绍一下。普遍来说,OLED显示屏的使用会比LCD显示屏麻烦一些,所以我在介绍LCD1602的时候使用用51单片机,而在这篇介绍OLED显示屏里会用STM32。

一、介绍

基本简介

OLED(Organic Light-Emitting Diode,又称有机电激发光显示、有机发光半导体)是有机发光二极管的英文缩写。其是一种利用多层有机薄膜结构产生电致发光的器件,它很容易制作,只需要低的驱动电压,这些特征使得OLED在满足平面显示器的应用上显得非常突出。OLED显示屏比LCD更轻薄、亮度高、功耗低、响应快、清晰度高、柔性好、发光效率高。单色屏幕的像素是一个像素就是一个发光二极管。OLED是”自发光”,像素本身就是光源,所以对比度极高,显示效果很犀利,绝无朦朦胧胧、拖泥带水之感,深受爱好者追捧,可惜当前技术所限制,无法大尺寸化,价格比TFT液晶屏高得多。

几种原理图

图片

图片

图片

图片

图片

图片

图片

外形

图片

图片

二、使用实战

准备

硬件准备

  1. STM32F103RCT6核心板

  2. 0.96OLED显示屏

  3. 杜邦线

软件准备

  1. Keil 5

  2. 显示屏取模软件 字模软件

  3. Keil-STM32F1xx芯片包

  4. STM32F10x固件库

  5. 串口调试助手、STM串口下载软件、USB转串口驱动

程序


//反显函数
void OLED_ColorTurn(u8 i)
{
  if(i==0)
    {
      OLED_WR_Byte(0xA6,OLED_CMD);//正常显示
    }
  if(i==1)
    {
      OLED_WR_Byte(0xA7,OLED_CMD);//反色显示
    }
}

//起始信号
void I2C_Start(void)
{
  OLED_SDIN_Set();
  OLED_SCLK_Set();
  OLED_SDIN_Clr();
  OLED_SCLK_Clr();
}

//结束信号
void I2C_Stop(void)
{
  OLED_SCLK_Set();
  OLED_SDIN_Clr();
  OLED_SDIN_Set();
}

//等待信号响应
void I2C_WaitAck(void) //测数据信号的电平
{
  OLED_SCLK_Set();
  OLED_SCLK_Clr();
}

//写入一个字节
void Send_Byte(u8 dat)
{
  u8 i;
  for(i=0;i<8;i++)
  {
    OLED_SCLK_Clr();//将时钟信号设置为低电平
    if(dat&0x80)//将dat的8位从最高位依次写入
    {
      OLED_SDIN_Set();
    }
    else
    {
      OLED_SDIN_Clr();
    }
    OLED_SCLK_Set();//将时钟信号设置为高电平
    OLED_SCLK_Clr();//将时钟信号设置为低电平
    dat<<=1;
  }
}

//发送一个字节
//向SSD1306写入一个字节。
//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();
}


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

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

//更新显存到OLED  
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);   //设置高列起始地址
     for(n=0;n<128;n++)
     OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA);
  }
}
//清屏函数
void OLED_Clear(void)
{
  u8 i,n;
  for(i=0;i<8;i++)
  {
     for(n=0;n<128;n++)
      {
       OLED_GRAM[n][i]=0;//清除所有数据
      }
  }
  OLED_Refresh();//更新显示
}

//画点 
//x:0~127
//y:0~63
void OLED_DrawPoint(u8 x,u8 y)
{
  u8 i,m,n;
  i=y/8;
  m=y%8;
  n=1<<m;
  OLED_GRAM[x][i]|=n;
}

//清除一个点
//x:0~127
//y:0~63
void OLED_ClearPoint(u8 x,u8 y)
{
  u8 i,m,n;
  i=y/8;
  m=y%8;
  n=1<<m;
  OLED_GRAM[x][i]=~OLED_GRAM[x][i];
  OLED_GRAM[x][i]|=n;
  OLED_GRAM[x][i]=~OLED_GRAM[x][i];
}


//画线
//x:0~128
//y:0~64
void OLED_DrawLine(u8 x1,u8 y1,u8 x2,u8 y2)
{
  u8 i,k,k1,k2,y0;
  
  if((x1<0)||(x2>128)||(y1<0)||(y2>64)||(x1>x2)||(y1>y2))return ;
  if(x1==x2)    //画竖线
  {
      for(i=0;i<(y2-y1);i++)
      {
        OLED_DrawPoint(x1,y1+i);
      }
  }
  else if(y1==y2)   //画横线
  {
      for(i=0;i<(x2-x1);i++)
      {
        OLED_DrawPoint(x1+i,y1);
      }
  }
  else      //画斜线
  {
    k1=y2-y1;
    k2=x2-x1;
    k=k1*10/k2;
    for(i=0;i<(x2-x1);i++)
      {
        OLED_DrawPoint(x1+i,y1+i*k/10);
      }
  }
}
//显示字符串
//x,y:起点坐标  
//size1:字体大小 
//*chr:字符串起始地址 
void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 size1)
{
  while((*chr>=' ')&&(*chr<='~'))//判断是不是非法字符!
  {
    OLED_ShowChar(x,y,*chr,size1);
    x+=size1/2;
    if(x>128-size1)  //换行
    {
      x=0;
      y+=2;
    }
    chr++;
  }
}

//m^n
u32 OLED_Pow(u8 m,u8 n)
{
  u32 result=1;
  while(n--)
  {
    result*=m;
  }
  return result;
}

显示2个数字
x,y :起点坐标   
len :数字的位数
size:字体大小
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size1)
{
  u8 t,temp;
  for(t=0;t<len;t++)
  {
    temp=(num/OLED_Pow(10,len-t-1))%10;
      if(temp==0)
      {
        OLED_ShowChar(x+(size1/2)*t,y,'0',size1);
      }
      else 
      {
        OLED_ShowChar(x+(size1/2)*t,y,temp+'0',size1);
      }
  }
}

//显示汉字
//x,y:起点坐标
//num:汉字对应的序号
void OLED_ShowChinese(u8 x,u8 y,u8 num,u8 size1)
{
  u8 i,m,n=0,temp,chr1;
  u8 x0=x,y0=y;
  u8 size3=size1/8;
  while(size3--)
  {
    chr1=num*size1/8+n;
    n++;
      for(i=0;i<size1;i++)
      {
        if(size1==16)
            {temp=Hzk1[chr1][i];}//调用16*16字体
        else if(size1==24)
            {temp=Hzk2[chr1][i];}//调用24*24字体
        else if(size1==32)       
            {temp=Hzk3[chr1][i];}//调用32*32字体
        else if(size1==64)
            {temp=Hzk4[chr1][i];}//调用64*64字体
        else return;
              
            for(m=0;m<8;m++)
              {
                if(temp&0x01)OLED_DrawPoint(x,y);
                else OLED_ClearPoint(x,y);
                temp>>=1;
                y++;
              }
              x++;
              if((x-x0)==size1)
              {x=x0;y0=y0+8;}
              y=y0;
       }
  }
}

//num 显示汉字的个数
//space 每一遍显示的间隔
void OLED_ScrollDisplay(u8 num,u8 space)
{
  u8 i,n,t=0,m=0,r;
  while(1)
  {
    if(m==0)
    {
      OLED_ShowChinese(128,24,t,16); //写入一个汉字保存在OLED_GRAM[][]数组中
      t++;
    }
    if(t==num)
      {
        for(r=0;r<16*space;r++)      //显示间隔
         {
          for(i=0;i<144;i++)
            {
              for(n=0;n<8;n++)
              {
                OLED_GRAM[i-1][n]=OLED_GRAM[i][n];
              }
            }
           OLED_Refresh();
         }
        t=0;
      }
    m++;
    if(m==16){m=0;}
    for(i=0;i<144;i++)   //实现左移
    {
      for(n=0;n<8;n++)
      {
        OLED_GRAM[i-1][n]=OLED_GRAM[i][n];
      }
    }
    OLED_Refresh();
  }
}

//配置写入数据的起始位置
void OLED_WR_BP(u8 x,u8 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);
}

//x0,y0:起点坐标
//x1,y1:终点坐标
//BMP[]:要写入的图片数组
void OLED_ShowPicture(u8 x0,u8 y0,u8 x1,u8 y1,u8 BMP[])
{
  u32 j=0;
  u8 x=0,y=0;
  if(y%8==0)y=0;
  else y+=1;
  for(y=y0;y<y1;y++)
   {
     OLED_WR_BP(x0,y);
     for(x=x0;x<x1;x++)
     {
       OLED_WR_Byte(BMP[j],OLED_DATA);
       j++;
     }
   }
}