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
文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    全新电路图符号大全,助你快速看懂图; 电路图,是一种以物理电学标准符号来绘制各电子元器件组成和关系的电路原理布局图,它被广泛应用于人类工程规划和电路研究。通过分析电路图,可以......
    301例电路图 此外还有常用的电气文字符号、图形符号大全附录哦! ......
    2051单片机没有专用的停止指令。 全部程序如下: MOV P1.#10100100B HERE: SJMP HERE 该最简程序已经写在图2中的单片机符号中。像右......
    亦然。 //Function to change one endian to another 五、STM32是大端还是小端模式? 如下图所示,从STM32手册介绍中可以发现,我们常用的STM32单片机符合“小弟......
    及设备名称。 程序设计时,需要调用相关的指令(如SINA_POS)来控制伺服电机的运动。 6、电气字母符号大全......
    电机、家用电器中,变频电机型号大全及参数影响着变频电机的使用场所,不清楚变频电机适合在哪里使用的,就更需要了解变频电机型号大全及参数对照表。   变频电机型号大全:   1、Y、Y2PT、YB系列......
    单片机C语言的知识汇总;一、概述 1、结合8051介绍单片机C语言的优越性:·无须懂得单片机的具体硬件,也能够编出符合硬件实际的专业水平的程序;    ·不懂得单片机的指令集,也能够编写完美的单片机......
    是{;} 在某引脚输出高电平的编程方法:(比如P1.3(PIN4)引脚) #include //该头文档中有单片机内部资源的符号化定义,其中包含P1.3 void main( void ) //void 表示......
    基于单片机的温湿度实时监控的程序设计;51单片机STC89C52RC是本方案的选用芯片,以其8位处理和极低的价格来看,是很适合进行本次实验。LCD显示屏本次选用的型号是1602A。 在实现51单片机......
    让相对应的功能部件进入设定的工作状态。 1.特殊功能寄存器的符号、字节地址、位地址和复位值 8051单片机有21个特殊功能寄存器(SFR),见下表1,每个特殊功能寄存器都是一个字节单元(有8位),它们的地址离散分布在80H......

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

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

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

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

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

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

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