STM32 驱动OLED显示屏(8080驱动)

一.OLED简介

      OLED,即有机发光二极管(Organic Light-Emitting Diode),LCD 都需要背光,而 OLED 不需要,因为它是自发光的。这样同样的显示, OLED 效果要来得好一些。 以目前的技术, OLED 的尺寸还难以大型化,但是分辨率确可以做到很高。

OLED优点:1.自发光,不需要背光  2.功耗更低,节能 3.对比度高,色彩鲜艳

OLED缺点:1.烧屏  2.价格昂贵  3.低频频闪 

ALINETEK 的 OLED 显示模块,该模块有以下特点:                                                                  1) 模块有单色和双色两种可选,单色为纯蓝色,而双色则为黄蓝双色。
2) 尺寸小,显示尺寸为 0.96 寸,而模块的尺寸仅为 27mm*26mm 大小。
3) 高分辨率,该模块的分辨率为 128*64。
4) 多种接口方式,该模块提供了总共 5 种接口包括: 6800、 8080 两种并行接口方式、 3
线或 4 线的串行SPI 接口方式、 IIC 接口方式
(只需要 2 根线就可以控制 OLED 了!)。

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

二.8080时序

并口总线时序,常用于屏幕驱动IC,由英特尔提出

//OLED模式设置
//0: 4线串行模式  (模块的BS1,BS2均接GND)
//1: 并行8080模式 (模块的BS1,BS2均接VCC)
#define OLED_MODE 	1 
		    						  
//---------------------------OLED端口定义--------------------------  					   
#define OLED_CS  PDout(6)
#define OLED_RST PGout(15) 	
#define OLED_RS  PDout(3)
#define OLED_WR  PGout(14)		  
#define OLED_RD  PGout(13)	   

//PC0~7,作为数据线
 #define DATAOUT(x) GPIO_Write(GPIOC,x);//输出  
  
//使用4线串行接口时使用 
#define OLED_SCLK PCout(0)
#define OLED_SDIN PCout(1)
		     
#define OLED_CMD  0	//写命令
#define OLED_DATA 1	//写数据

1.写时序图/读时序

#define DATAOUT(x) GPIO_Write(GPIOC,x);//输出 


//向SSD1306写入一个字节。
//dat:要写入的数据/命令
//cmd:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(u8 dat,u8 cmd)
{    
 	OLED_RS=cmd;
	OLED_CS=0;	 //数据拉低片选线,选择SSD1306 
	OLED_WR=0;	 //拉低WR写线,准备数据
	DATAOUT(dat);//在低电平期间准备数据	
	OLED_WR=1;   //拉高WR,数据发送到SSD1306
	OLED_CS=1;	 //取消片选  
	OLED_RS=1;	 //释放RS线,恢复默认
} 

2.指令

指令(HEX)

各位描述

名称

说明

D7

D6

D5

D4

D3

D2

D1

D0

0xAE/0xAF

1

0

1

0

1

1

1

X0

设置显示开关

X0 = 0,关闭显示

X0 = 1,开启显示

0xB0~0xB7

1

0

1

1

0

X2

X1

X0

设置页地址

X[2:0]:0~7对应页0~7

B0是页0,B1是页1...

0x00~0x0F

0

0

0

0

X3

X2

X1

X0

设置列地址(L4)

设置8位列地址的低四位

0x10~0x1F

0

0

0

1

X3

X2

X1

X0

设置列地址(H4)

设置8位列地址的高四位

 OLED是128*64,前面的128是用两位来表示列地址,0x00-0x0F是低4位,0x10-0x1F是高4位。  

 表格中的下面三行合起来就可以表示SSD1306的GRAM写入位置。

3.GRAM

图形显示数据RAM是一个位映射静态RAM(可以理解为“FIFO”,与物理位置有映射关系),保存要显示的位模式。内存大小为128 * 64位,可分为8页,从页0到页7,用于黑白128 * 64点阵显示。

 页地址模式

对GRAM进行操作时,列地址指针会自动递增。当列地址指针到达列结束地址时,重置为开始地址,但页地址指针不变。用户必须设置新的页面和列地址,以便访问下一页GRAM内容。

配置页地址模式

三种设置内存地址模式:页地址模式,水平地址模式和垂直地址模式。

1. 发送内存地址模式命令0x20  2. 发送页地址模式命令0x02

显示覆盖问题

建立一个OLED的GRAM

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

//存放格式如下.
//[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 
	
#define OLED_CMD  0	//写命令
#define OLED_DATA 1	//写数据	   
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); 
        }
	}   
}

4.画点函数实现代码

GRAM和OLED屏幕坐标对应关系表

//画点 
//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;	    
}

 5.字符显示原理

1.如何显示在OLED

1.显示字符,必须先有其点阵数据,点阵数据的集合,叫做字库

2.单片机根据点阵数据按取模方向进行描点还原,就能显示字符

3.ASCII字符宽度 = 汉字宽度的一半

      竖着看                  

16*16大小,字符A的点阵数据数组:
uint8_t oled_ascii_1608[]=
{
  0x00,0x04,0x00,0x3C,0x03,0xC4,0x1C,0x40,
  0x07,0x40,0x00,0xE4,0x00,0x1C,0x00,0x04
} ;

uint8_t temp, t1, t;
uint8_t y0 = y;			// 保存y的初值 

for(t = 0; t < 16; t++)    //总共16个字节,要遍历一遍
{
    temp = oled_ascii_1608[t];	// 依次获取点阵数据 

    for(t1 = 0; t1 < 8; t1++)
    {
        if(temp & 0X80)        	 // 这个点有效,需要画出来 1000 0000
	        oled_draw_point(x, y, mode);
	    else				    //  这个点无效,不需要画出来
		    oled_draw_point(x, y, !mode);
 
        temp <<= 1;            	//低位数据往高位移位,最高位数据直接丢弃 
        y++;                   	//y坐标自增 

        if((y-y0) == 16)    	//显示完一列了 
        {
            y = y0;             //y坐标复位 
            x++;                //x坐标递增 
	        break;              //跳出 for循环 
        }
    }
}

 三.驱动实现

  • 14
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值