OLED显示图片和符号+普中51单片机+1.3寸I2C4针

发布时间:2024-08-05  

1 实验现象

2 实验原理

  OLED(Organic Light-Emitting Diode)有机发光二极管又称为有机激光显示,OLED显示技术具有自发光的特性,采用非常薄的有机材料涂层,和玻璃基板,当有电流通过时,这些有机发光材料就会发光,而且OLED由于同时具备自发光,不需要背光源(只上电源不会亮的,驱动程序和接线才会点亮),对比度高,厚度薄,视角广,反应速度快,可用于挠曲面板,使用温度范围广,结构及制程等优异之特性。 LCD都需要背光,而OLED不需要,因为它是自发光的。这样同样的显示OLED 效果要来得好一些。以目前的技术,OLED 的尺寸还难以大型化,但是分辨率确可以做到很高。

  将单个LED按128x64点阵排列,就是12864点阵屏,通过点亮特定位置的LED传达信息,这是LED屏的原理。操作128x64个LED需要的IO口比较多,对于单片机的资源造成很大的浪费,单片机与LED之间往往配置一个专用驱动芯片。单片机与驱动芯片之间通过串行总线通讯,而驱动芯片复制点亮LED。典型的芯片有SSD1306和SSD1106。SSD1306的每页包含了128个字节,总共8页,这样刚好是 128*64 的点阵大小。这点与1.3寸OLED驱动IC(SSD1106)稍有不同,SSD1106 每页是132个字节,也是8页。所以在用0.96寸OLED 移植1.3 寸OLED程序的时候需要将0.96寸的显示地址向右偏移2,这样显示就正常了;否则在用1.3 寸的时候1.3寸屏右边会有4个像素点宽度显示不正常或是全白,这点大家注意一下。其它的SSD1306和SSD1106 区别不大。

3 系统设计(略)

4 硬件设计(略)

 

5 软件设计

5.1 主程序(应用层main+器件层OLED+功能驱动层I2C)


#include "OLED.H"

#include "bmp.h"


int main(void)

{    

    u8 t=' ';            //空格,space

    OLED_Init();        //初始化OLED

    OLED_ColorTurn(0);    //0正常显示,1 反色显示

    OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示

    while(1) 

    {    

        //显示一张图片128*64

        OLED_DrawBMP(0,0,128,64,BMP12864_BIRD);

        delay_ms(500);

        OLED_Clear();

        

        //显示文字

        OLED_ShowChinese(0,0,0,16);        //学

        OLED_ShowChinese(18,0,1,16);    //习

        OLED_ShowChinese(36,0,2,16);    //单

        OLED_ShowChinese(54,0,3,16);    //片

        OLED_ShowChinese(72,0,4,16);    //机

        OLED_ShowChinese(90,0,5,16);    //技

        OLED_ShowChinese(108,0,6,16);    //术

        OLED_ShowString(16,2,"MCU+STC89C52",16);

        OLED_ShowString(20,4,"2023/01/25",16);

        OLED_ShowString(0,6,"ASCII:",16);  

        OLED_ShowString(63,6,"CODE:",16);

        OLED_ShowChar(48,6,t,16);

        if(t>'~')t=' ';

        OLED_ShowNum(103,6,t,3,16);

        t++;

        delay_ms(500);

        OLED_Clear();

    }          

}


5.2 OLED控制函数


#ifndef _OLED_H_

#define _OLED_H_


#include "I2C.H"


//OLED控制用函数

void delay_ms(unsigned int ms);

void OLED_ColorTurn(u8 i);

void OLED_DisplayTurn(u8 i);

void OLED_WR_Byte(u8 dat,u8 cmd);

void OLED_Set_Pos(u8 x, u8 y);

void OLED_Display_On(void);

void OLED_Display_Off(void);

void OLED_Clear(void);

void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 sizey);

u32 oled_pow(u8 m,u8 n);

void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 sizey);

void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 sizey);

void OLED_ShowChinese(u8 x,u8 y,u8 no,u8 sizey);

void OLED_DrawBMP(u8 x,u8 y,u8 sizex, u8 sizey,u8 BMP[]);

void OLED_Init(void);


#endif  


#include "oled.h"

#include "oledfont.h"  


#define OLED_CMD  0    //写命令

#define OLED_DATA 1    //写数据


//OLED的显存

//存放格式如下,128*8为一页,共8页.

//[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                

void delay_ms(unsigned int ms)

{                         

    unsigned int a;

    while(ms)

    {

        a=1800;

        while(a--);

        ms--;

    }

    return;

}


//反显函数

void OLED_ColorTurn(u8 i)

{

    if(i==0)

        {

            OLED_WR_Byte(0xA6,OLED_CMD);//正常显示

        }

    if(i==1)

        {

            OLED_WR_Byte(0xA7,OLED_CMD);//反色显示

        }

}


//屏幕旋转180度

void OLED_DisplayTurn(u8 i)

{

    if(i==0)

        {

            OLED_WR_Byte(0xC8,OLED_CMD);//正常显示

            OLED_WR_Byte(0xA1,OLED_CMD);

        }

    if(i==1)

        {

            OLED_WR_Byte(0xC0,OLED_CMD);//反转显示

            OLED_WR_Byte(0xA0,OLED_CMD);

        }

}


//发送一个字节

//向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();

}


//坐标设置

void OLED_Set_Pos(u8 x, u8 y) 

    x+=2;                //SH1106的起始地址为0x02列

    OLED_WR_Byte(0xb0+y,OLED_CMD);

    OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);

    OLED_WR_Byte((x&0x0f),OLED_CMD);

}         

//开启OLED显示    

void OLED_Display_On(void)

{

    OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令

    OLED_WR_Byte(0X14,OLED_CMD);  //DCDC ON

    OLED_WR_Byte(0XAF,OLED_CMD);  //DISPLAY ON

}

//关闭OLED显示     

void OLED_Display_Off(void)

{

    OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令

    OLED_WR_Byte(0X10,OLED_CMD);  //DCDC OFF

    OLED_WR_Byte(0XAE,OLED_CMD);  //DISPLAY OFF

}                        

//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!      

void OLED_Clear(void)  

{  

    u8 i,n;            

    for(i=0;i<8;i++)  

    {  

        OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)

        OLED_WR_Byte (0x02,OLED_CMD);      //设置显示位置—列低地址

        OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   

        for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA); 

    } //更新显示

}


//在指定位置显示一个字符,包括部分字符

//x:0~127

//y:0~63                 

//sizey:选择字体 6x8  8x16

void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 sizey)

{          

    u8 c=0,sizex=sizey/2;

    u16 i=0,size1;

    if(sizey==8)size1=6;

    else size1=(sizey/8+((sizey%8)?1:0))*(sizey/2);

    c=chr-' ';//得到偏移后的值

    OLED_Set_Pos(x,y);

    for(i=0;i    {

        if(i%sizex==0&&sizey!=8) OLED_Set_Pos(x,y++);

        if(sizey==8) OLED_WR_Byte(asc2_0806[c][i],OLED_DATA);//6X8字号

        else if(sizey==16) OLED_WR_Byte(asc2_1608[c][i],OLED_DATA);//8x16字号

//        else if(sizey==xx) OLED_WR_Byte(asc2_xxxx[c][i],OLED_DATA);//用户添加字号

        else return;

    }

}

//m^n函数

u32 oled_pow(u8 m,u8 n)

{

    u32 result=1;     

    while(n--)result*=m;    

    return result;

}                  

//显示数字

//x,y :起点坐标

//num:要显示的数字

//len :数字的位数

//sizey:字体大小          

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

{             

    u8 t,temp,m=0;

    u8 enshow=0;

    if(sizey==8)m=2;

    for(t=0;t    {

        temp=(num/oled_pow(10,len-t-1))%10;

        if(enshow==0&&t<(len-1))

        {

            if(temp==0)

            {

                OLED_ShowChar(x+(sizey/2+m)*t,y,' ',sizey);

                continue;

            }else enshow=1;

        }

         OLED_ShowChar(x+(sizey/2+m)*t,y,temp+'0',sizey);

    }

}

//显示一个字符号串

void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 sizey)

{

    u8 j=0;

    while (chr[j]!='')

    {        

        OLED_ShowChar(x,y,chr[j++],sizey);

        if(sizey==8)x+=6;

        else x+=sizey/2;

    }

}

//显示汉字

void OLED_ShowChinese(u8 x,u8 y,u8 no,u8 sizey)

{

    u16 i,size1=(sizey/8+((sizey%8)?1:0))*sizey;

    for(i=0;i    {

        if(i%sizey==0) OLED_Set_Pos(x,y++);

        if(sizey==16) OLED_WR_Byte(Hzk[no][i],OLED_DATA);//16x16字号

//        else if(sizey==xx) OLED_WR_Byte(xxx[c][i],OLED_DATA);//用户添加字号

        else return;

    }                

}



//显示图片

//x,y显示坐标

//sizex,sizey,图片长宽

//BMP:要显示的图片

void OLED_DrawBMP(u8 x,u8 y,u8 sizex, u8 sizey,u8 BMP[])

{     

  u16 j=0;

    u8 i,m;

    sizey=sizey/8+((sizey%8)?1:0);

    for(i=0;i

[1] [2] [3] [4]
关键字:OLED显示  普中  51单片机 引用地址:OLED显示图片和符号+普中51单片机+1.3寸I2C4针 声明:本文内容及配图由平台用户或入驻媒体撰写。文章观点仅代表作者本人,不代表EEWorld网站立场。文章及其配图仅供工程师学习之用,如有内容侵权或违规,请联系本站处理,邮箱地址:bbs_service@eeworld.com.cn
文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>