oled显示教程_oled屏幕检测图片

oled显示教程_oled屏幕检测图片目录OLED显示实验(8080接口方式)OLED接口说明读写流程简述SSD1306的8080并口读写时序解析OLED显存的排列OLED基本操作流程OLED库函数使用说明OLED库函数使用示例写入

OLED显示实验(8080接口方式)

OLED接口说明

 

 

oled显示教程_oled屏幕检测图片

读写流程简述

先根据要写入/读取的数据的类型,设置 DC 为高(针对数据)/低(针对命令),然后拉低片选(选中 SSD1306芯片),接着我们根据是读数据,还是要写数据置 RD/WR为低或者高,如果是写数据或者写命令,就在RD的上升沿,使数据/命令锁存到数据线(D[7:0])上;如果是读数据或者读状态,就在WR的上升沿,使状态/数据所存至数据线(D[7:0])上。

SSD1306 的 8080 并口读写时序解析

oled显示教程_oled屏幕检测图片

 

 

oled显示教程_oled屏幕检测图片

OLED显存的排列

oled显示教程_oled屏幕检测图片

 

在单片机的内部建立一个OLED的GRAM(需要128*8 个字节),在每次修改的时候,只是修改单片机上的GRAM(实际上就是 SRAM),在修改完了之后,一次性把单片机内部的 GRAM写入到OLED的GRAM中。

OLED基本操作流程

oled显示教程_oled屏幕检测图片

 

OLED官方库函数的功能

OLED操作库函数

void OLED_WR_Byte(u8 dat,u8 cmd)     

写一个字节

void OLED_Display_On(void)

显示开

void OLED_Display_Off(void)

显示关

void OLED_Refresh_Gram(void)

更新OLED的GRAM

void OLED_Init(void)

OLED初始化

void OLED_Clear(void)

清空OLED的GPAM/清屏操作

void OLED_DrawPoint(u8 x,u8 y,u8 t)

画点操作

void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot)

矩形区域填充操作

void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode)

显示字符

void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size)

显示数字

void OLED_ShowString(u8 x,u8 y,const u8 *p,u8 size)

显示字符串

OLED官方库函数解析

数据写入操作函数

//dat:要写入的数据/命令  
//cmd:数据/命令标志 0,表示命令;1,表示数据;  
void OLED_WR_Byte(u8 dat,u8 cmd)  
{  
    DATAOUT(dat); // 以字节为单位写入PortC端口中         
    OLED_RS=cmd; // 写入数据/命令  
    OLED_CS=0; // 使能片选功能         
    OLED_WR=0;     
    OLED_WR=1; // WR=0,WR=1,是为了实现上升沿  
    OLED_CS=1; // 关闭片选段     
    OLED_RS=1; // DC电平恢复至初始状态      
}  

   

数据写入操作函数的使用

当我们在使用void OLED_Refresh_Gram(void) 函数将我们的128*8的数组写入OLED的GRAM中时,我们必须触发OLED中的WR的上升沿,以便将OLED的数据按字节为单位从D[7:0]写入OLED中。

//更新显存到LCD         
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);   
    }     
}  

 

画点操作函数

//画点   
//x:0~127  
//y:0~63  
//t:1 填充 0,清空                    
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;  // 清空
}  

 

画点操作函数的使用

#include "oled.h"  
#include "stm32f10x.h"  
#include "delay.h"  
  
int main()  
{  
    u8 x=10, y=10, mode=1;  
      
    delay_init(); // 定时器初始化  
    OLED_Init(); // OLED初始化  
    delay_ms(10); // 等待初始化  
      
    while(1)  
    {  
        OLED_DrawPoint(x, y, mode);  
          
        x++;y++;  
        OLED_Refresh_Gram(); // 将数据更新至OLED的GRAM的缓存中  
          
        x &= 0x1F;  
        y &= 0x1F;  
    }  
}  

 

矩形区域填充函数解析

//x1,y1,x2,y2 填充区域的对角坐标  
//确保x1<=x2;y1<=y2 0<=x1<=127 0<=y1<=63           
//dot:0,清空;1,填充     
void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot)    
{    
    u8 x,y;    
    for(x=x1;x<=x2;x++) // 进行行的填充  
    {  
        for(y=y1;y<=y2;y++) // 进行列的填充  
                   OLED_DrawPoint(x,y,dot);  
    }                                                         
    OLED_Refresh_Gram();//更新显示  
}  

 

矩形区域填充函数的使用

#include "oled.h"  
#include "stm32f10x.h"  
#include "delay.h"  
  
int main()  
{  
    u8 x=10, y=10, mode=1;  
      
    delay_init(); // 定时器初始化  
    OLED_Init(); // OLED初始化  
    delay_ms(10); // 等待初始化  
      
    while(1)  
    {  
        OLED_ShowString(10,10,"Hello World",16); // 用2412字体写入(单个字符占24行12列)  
        OLED_ShowString(10,26,"Today:",24); // 用1608字体写入(单个字符占16行8列)  
        OLED_Fill(10,50,30,70,1); // 填充(10,50)到(30,70)的区域  
        OLED_Refresh_Gram(); // 将128*64的数据装入OLED的GRAM中  
    }  
}  

 

oled显示教程_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++) // 更新csize个字节的信息  
    {     
        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) // 判断最高位是否为1  
                          OLED_DrawPoint(x,y,mode);  
            else   
                          OLED_DrawPoint(x,y,!mode);  
            temp<<=1; // 不断向左移位(与上面的判断相呼用来将temp中为1的点点亮)  
            y++;  
            if((y-y0)==size) // 当读到结尾就停(读取长度=字体的长度)  
            {  
                y=y0; // 从第一行开始读  
                x++; // 列+1  
                break;  
            }  
        }      
    }            
}  

 

显示字符函数的使用

#include "oled.h"  
#include "stm32f10x.h"  
#include "delay.h"  
  
int main()  
{  
    u8 x=10, y=10, mode=1;  
      
    delay_init(); // 定时器初始化  
    OLED_Init(); // OLED初始化  
    delay_ms(10); // 等待初始化  
      
    while(1)  
    {  
        OLED_ShowString(10,10,"Hello World",16); // 用1608字体写入(单个字符占16行8列)  
        OLED_ShowChar(10,26,"T",24); // 用2412字体写入(单个字符占24行12列)  
        OLED_Refresh_Gram(); // 将128*64的数据装入OLED的GRAM中  
    }  
}  

 

显式数字的函数

//m^n函数  
u32 mypow(u8 m,u8 n)  
{  
    u32 result=1;      
    while(n--)result*=m;      
    return result;  
}                   
//显示2个数字  
//x,y :起点坐标    
//len :数字的位数  
//size:字体大小  
//mode:模式   0,填充模式;1,叠加模式  
//num:数值(0~4294967295);             
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size)  
{             
    u8 t,temp;  
    u8 enshow=0;                             
    for(t=0;t<len;t++)  
    {  
        temp=(num/mypow(10,len-t-1))%10;  
        if(enshow==0&&t<(len-1))  
        {  
            if(temp==0)  
            {  
                OLED_ShowChar(x+(size/2)*t,y,' ',size,1);  
                continue;  
            }else enshow=1;   
               
        }  
        OLED_ShowChar(x+(size/2)*t,y,temp+'0',size,1); // 显示数字对应的ASCII码
    }  
}   
// 其实显示数字就是显示数字对应的ASCII字符

 

显式数字函数的使用

#include "oled.h"  
#include "stm32f10x.h"  
#include "delay.h"  
  
int main()  
{  
    u8 x=10, y=10, mode=1;  
      
    delay_init(); // 定时器初始化  
    OLED_Init(); // OLED初始化  
    delay_ms(10); // 等待初始化  
      
    while(1)  
    {  
        OLED_ShowString(10,10,"Hello World",16); // 用2412字体写入(单个字符占24行12列)  
        OLED_ShowString(10,26,"Today:",24); // 用1608字体写入(单个字符占16行8列)  
        OLED_ShowNum(10,50,20200904,8,12); // 将数字转换为字符进行写入  
        OLED_Refresh_Gram(); // 将128*64的数据装入OLED的GRAM中  
    }  
}  

 

oled显示教程_oled屏幕检测图片

 

显式字符串的函数

//显示字符串(注意:字符串还有一个未显式显示的’\0’,因此才会出现如下if中的情况)
//x,y:起点坐标    
//size:字体大小   
//*p:字符串起始地址   
void OLED_ShowString(u8 x,u8 y,const u8 *p,u8 size)  
{     
    while((*p<='~')&&(*p>=' '))//判断是不是非法字符!  
    {         
        if(x>(128-(size/2))) // 如果字符总长度大于128-(size/2)
           {x=0;y+=size;}  // 直接进行下一行字符的显示
        if(y>(64-size)) // 如果字符总列数超出了64-size
           {y=x=0;OLED_Clear();}  // 清空GRAM中旧的缓存
        OLED_ShowChar(x,y,*p,size,1); // 更新OLED中GRAM的缓存
        x+=size/2; // 直接进行下一列字符的显示
        p++;  
    }    
      // ‘ ‘是ASCII码的第一个字符,用char-‘ ‘ 得出的是char在ASCII中的相对位置
}  
// 注意:这里的一个字符的列宽为size/2,行宽为size

 

显式字符串函数的使用

#include "oled.h"  
#include "stm32f10x.h"  
#include "delay.h"  
  
int main()  
{  
    u8 x=10, y=10, mode=1;  
      
    delay_init(); // 定时器初始化  
    OLED_Init(); // OLED初始化  
    delay_ms(10); // 等待初始化  
      
    while(1)  
    {  
        OLED_ShowString(10,10,"Hello World",16); // 用1608字体写入(单个字符占16行8列)  
        OLED_ShowString(10,26,"Today:",24); // 用2412字体写入(单个字符占24行12列)  
        OLED_ShowString(10,50,"2020/9/4",12); // 用1206字体写入(单个字符占12行6列)  
        OLED_Refresh_Gram(); // 将128*64的数据装入OLED的GRAM中  
    }  
}  

 

oled显示教程_oled屏幕检测图片

 

OLED简单显示实验

#include "delay.h"  
#include "sys.h"  
#include "oled.h"  
      
 int main(void)  
 {    
     u8 t;  
    delay_init();            //延时函数初始化    
        delay_init();            // 初始化定时器    
    OLED_Init();            //初始化OLED   
        delay_ms(10); // 延迟10ms  
        OLED_ShowString(0,0,"ALIENTEK",24);    
    OLED_ShowString(0,24, "0.96' OLED TEST",16);    
    OLED_ShowString(0,40,"ATOM 2015/1/14",12);    
    OLED_ShowString(0,52,"ASCII:",12);    
    OLED_ShowString(64,52,"CODE:",12);    
    
    OLED_Refresh_Gram();        //更新显示到OLED   
   
    while(1)   
    {         
        OLED_ShowChar(48,48,t,16,1);//显示ASCII字符      
        OLED_Refresh_Gram();  
        t++;  
        if(t>'~')t=' ';  
        OLED_ShowNum(103,48,t,3,16);//显示ASCII字符的码值   
    }       
      
}  

 

OLED自定义显示的原理

我们知道正点原子提供给我们的库函数操作其实就是先刷新一个128*64大小的数组,然后将个更新过的数组通过刷新GRAM的函数写入OLED的GRAM中。数组如下:

//OLED的显存  
//存放格式如下.  
//[0]0 1 2 3 ... 127      
//[1]0 1 2 3 ... 127      
//[2]0 1 2 3 ... 127      
//[3]0 1 2 3 ... 127      
//[4]0 1 2 3 ... 127      
//[5]0 1 2 3 ... 127      
//[6]0 1 2 3 ... 127      
//[7]0 1 2 3 ... 127             
u8 OLED_GRAM[128][8];  

 

我们的显存中有128*64个像素点,就相当于有128*64个状态点,每个状态点仅仅有两种状态:亮/灭,对应的二进制为1/0。因此相当于有128*64个bits比特,当我们用16进制表示时,我们用1byte表示8个bits,因此数组中一共有128*8个元素,每个元素为一个字节,分别控制8个像素点的状态。

数组中每个字节与像素点的对应关系

 

 

oled显示教程_oled屏幕检测图片

例如:我们的画布时10*10一共100个像素点,我们需要20个byte,即20个元素的数组,数组的size是怎么来的呢?

oled显示教程_oled屏幕检测图片

图示如下:

 

oled显示教程_oled屏幕检测图片

当我们在10*10的像素点阵中取如下点:

oled显示教程_oled屏幕检测图片

 

我们会得到如下包含20个元素的数组:

{0x2C,0x00,0x40,0x00,0x02,0x00,0x61,0x00,0x01,0x00,0x41,0x00,0x40,0x00,0x06,0x00,0x40,0x00,0x08,0x00}

OLED自定义显示的程序设计

#include "oled.h"  
#include "stm32f10x.h"  
#include "delay.h"  
  
u8 Image[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x19,0x20,0x00,0x00,0x00,0x00,0x00,0x90,  
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,  
0x00,0x08,0x00,0x00,0x00,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x80,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  
0x00,0x01,0x00,0x00,0x00,0x00,0x20,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x80,0x00,0x00,0x00,0x80,0x10,0x00,0x00,0xC0,0x00,0x00,0x80,0x00,0x00,0x40,0x40,0x00,0x00,0x00,0x20,0x00,0x00,0x00,  
0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x00,0x80,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x02,0x60,0x00,0x00,0x00,0x40,  
0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x20,0x04,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x40,0x00,0x00,0x00,  
0x00,0x04,0x00,0x00,0x00,0x04,0x08,0x20,0x08,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x80,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,  
0x00,0x00,0x04,0x00,0x06,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x40,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};  
  
void OLED_Show(u8 x,u8 y,u16 bytenumber, u8 height, u8* Image, u8 mode);  
  
int main()  
{  
    u8 x=10, y=10, mode=1;  
      
    delay_init(); // 定时器初始化  
    OLED_Init(); // OLED初始化  
    delay_ms(10); // 等待初始化  
      
    while(1)  
    {  
        OLED_Show(10,10,350, 50, Image, 1);  
        OLED_Refresh_Gram(); // 将128*64的数据装入OLED的GRAM中  
    }  
}  
  
/* 万能的OLED自定义显示图像的函数 */
// x,y:图像左上角的坐标
// bytenumber:像素点的个数
// height:像素点的高度,即每一列总共有几行
// Image:包含图像数据的一维数组首地址
// mode:当像素点的值为1时,是点亮数据点还是清除数据点
void OLED_Show(u8 x,u8 y,u16 bytenumber, u8 height, u8* Image, u8 mode)  
{  
    u16 i=0;  
    u8 y0=y, temp=0, j=0;  
      
    for(i=0; i<bytenumber; i++)  
    {  
        temp=Image[i];  
        for(j=0; j<8; j++)  
        {  
            if(temp&0x80)  
                OLED_DrawPoint(x,y,mode);  
            else  
                OLED_DrawPoint(x,y,!mode);  
            temp <<= 1;  
            y++;  
            if(y-y0 == height)  
            {  
                y=y0;  
                x++;  
                break;  
            }  
        }  
    }  
}  

 

其中,图像如下:

oled显示教程_oled屏幕检测图片

 

图像对应数据如下:

{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x19,0x20,0x00,0x00,0x00,0x00,0x00,0x90,  
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,  
0x00,0x08,0x00,0x00,0x00,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x80,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  
0x00,0x01,0x00,0x00,0x00,0x00,0x20,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x80,0x00,0x00,0x00,0x80,0x10,0x00,0x00,0xC0,0x00,0x00,0x80,0x00,0x00,0x40,0x40,0x00,0x00,0x00,0x20,0x00,0x00,0x00,  
0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x00,0x80,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x02,0x60,0x00,0x00,0x00,0x40,  
0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x20,0x04,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x40,0x00,0x00,0x00,  
0x00,0x04,0x00,0x00,0x00,0x04,0x08,0x20,0x08,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x80,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,  
0x00,0x00,0x04,0x00,0x06,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x40,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}

 

运行结果如下:

 

oled显示教程_oled屏幕检测图片

今天的文章oled显示教程_oled屏幕检测图片分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/62918.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注