OLED显示屏驱动:8080并口,IIC,SPI三种驱动方式

您所在的位置:网站首页 显示器hz有哪几种模式 OLED显示屏驱动:8080并口,IIC,SPI三种驱动方式

OLED显示屏驱动:8080并口,IIC,SPI三种驱动方式

2024-07-14 12:09:33| 来源: 网络整理| 查看: 265

文章目录 一.OLED驱动原理介绍二.8080并口驱动方式三.IIC驱动方式四.SPI驱动方式五. 感谢支持

    本文介绍了对OLED的几种驱动方式,8080并口,IIC,SPI三种驱动方式,采用的单片机是STM32F407.

一.OLED驱动原理介绍

    OLED模块的驱动芯片为SSD1306,其显存大小总共为 12864bit 大小,SSD1306 将 这些显存分为了 8 页,其对应关系如表 17.1.3 所示: SSD1306显存表     可以看出,SSD1306 的每页包含了 128 个字节,总共 8 页,这样刚好是 12864 的点阵大小。因为每次写入都是按字节写入的,这就存在一个问题,如果我们使用只写方式操作模块,那么,每次要写 8 个点,这样,我们在画点的时候,就必须把要设置的点所在的字节的每个位都搞清楚当前的状态(0/1?),否则写入的数据就会覆盖掉之前的状态,结果就是有些不需要显示的点,显示出来了,或者该显示的没有显示了。这个问题在能读的模式下,我们可以先读出来要写入的那个字节,得到当前状况,在修改了要改写的位之后再写进 GRAM,这样就不会影响到之前的状况了。但是这样需要能读 GRAM,对于 4 线 SPI 模式/IIC 模式,模块是不支持读的,而且读->改->写的方式速度也比较慢。

    所以我们采用的办法是在 STM32F4 的内部建立一个 OLED 的 GRAM(共 128*8 个字节),在每次修改的时候,只是修改 STM32F4 上的 GRAM(实际上就是 SRAM),在修改完了之后,一次性把 STM32F4 上的 GRAM 写入到 OLED 的 GRAM。当然这个方法也有坏处,就是对于那些 SRAM 很小的单片机(比如 51 系列)就比较麻烦了。 SSD1306 的命令比较多,这里我们仅介绍几个比较常用的命令,这些命令如表 17.1.4 所示: SSD1306常用命令表     我们再来介绍一下 OLED 模块的初始化过程,SSD1306 的典型初始化框图如下图: 在这里插入图片描述

二.8080并口驱动方式

    介绍一下模块的 8080 并行接口,8080 并行接口的发明者是 INTEL,该总线也被广泛应用于各类液晶显示器,使得 MCU 可以快速的访问 OLED。ALIENTEK OLED 模块的 8080 接口方式需要如下一些信号线: CS:OLED 片选信号。 WR:向 OLED 写入数据。 RD:从 OLED 读取数据。 D[7:0]:8 位双向数据线。 RST(RES):硬复位 OLED。 DC:命令/数据标志(0,读写命令;1,读写数据)。     模块的 8080 并口读/写的过程为:先根据要写入/读取的数据的类型,设置 DC 为高(数据)/低(命令),然后拉低片选,选中 SSD1306,接着我们根据是读数据,还是要写数据置 RD/WR为低,然后: 在 RD 的上升沿, 使数据锁存到数据线(D[7:0])上; 在 WR 的上升沿,使数据写入到 SSD1306 里面; SSD1306 的 8080 并口写时序图如图 17.1.3 所示: 在这里插入图片描述 在这里插入图片描述 OLED配置及驱动程序:

/*******************OLED.c代码*************************/ //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];//定义SRAM缓存区 //更新显存到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); //更新到OLED } } //通过拼凑的方法向OLED输出一个8位数据 //data:输出的数据 void OLED_Data_Out(u8 data) { u16 dat = data & 0X0F; GPIOC->ODR &= ~(0XF ODR |= dat PC[9:6] GPIO_Write(GPIOC, dat > 4) & 0X01; //D4 PBout(6) = (data >> 5) & 0X01; //D5 PEout(5) = (data >> 6) & 0X01; //D6 PEout(6) = (data >> 7) & 0X01; //D7 } //向SSD1306写入一个字节 //dat:写入的数据/命令 //cmd:0:命令,1:数据 void OLED_WR_Byte(u8 dat, u8 cmd) { OLED_Data_Out(dat); OLED_RS = cmd; OLED_CS = 0; OLED_WR = 0; OLED_WR = 1; OLED_CS = 1; OLED_RS = 1; } //开启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 } // OLED清屏 void OLED_Clear(void) { u8 i, n; for (i = 0; i < 8; i++)for (n = 0; n < 128; n++)OLED_GRAM[n][i] = 0X00; OLED_Refresh_Gram();//¸更新显存到LCD } //画点 //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 COM0;N:驱动路数 OLED_WR_Byte(0xDA, OLED_CMD); //设置COM口硬件引脚配置 OLED_WR_Byte(0x12, OLED_CMD); //[5:4]配置 OLED_WR_Byte(0x81, OLED_CMD); //对比度设置 OLED_WR_Byte(0xEF, OLED_CMD); //1~255;默认0X7F (亮度设置,越大越亮) OLED_WR_Byte(0xD9, OLED_CMD); //设置预充电周期 OLED_WR_Byte(0xf1, OLED_CMD); //[3:0],PHASE 1;[7:4],PHASE 2; OLED_WR_Byte(0xDB, OLED_CMD); //设置VCOMH 电压倍率 OLED_WR_Byte(0x30, OLED_CMD); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc; OLED_WR_Byte(0xA4, OLED_CMD); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏) OLED_WR_Byte(0xA6, OLED_CMD); //设置显示方式;bit0:1,反相显示;0,正常显示 OLED_WR_Byte(0xAF, OLED_CMD); //开启显示 OLED_Clear();//OLED清屏 } /*******************OLED.h代码*************************/ //-----------------OLED端口定义---------------- #define OLED_CS PBout(7) #define OLED_RST PGout(15) #define OLED_RS PDout(6) #define OLED_WR PAout(4) #define OLED_RD PDout(7) #define OLED_CMD 0 //写命令 #define OLED_DATA 1 //写数据 /*******************main()函数代码*************************/ int main(void) { OLED_Init(); //初始化OLED while (1) { OLED_ShowChar(100, 30, 'K', 16, 1);//显示字符 OLED_ShowString(64, 52, "CODE:", 12);//显示字符串 OLED_ShowFloatNum(10, 30, 0.1213, 16, 1);//显示小数 OLED_ShowChinese(26, 10, 3, 1);//显示汉字 OLED_Refresh_Gram(2);//更新显示到OLED,此句非常重要,将数据写到SSD1306的GRAM区域 delay_ms(1000); } } 三.IIC驱动方式

一些驱动方式与显示代码均与上面一致,因此这里只介绍IIC写数据/命令驱动代码,也即重写OLED_WR_Byte(u8 dat,u8 cmd)函数,其他均不变!

//向SSD1306写入一个字节 //dat:要写入的数据/命令 //cmd:数据/命令标志 0,表示命令;1,表示数据 void WriteCmd(u8 command) //写命令函数 { IIC_Start(); IIC_Send_Byte(0x78);//OLED地址 IIC_Wait_Ack(t); IIC_Send_Byte(0x00);//写命令寄存器地址 IIC_Wait_Ack(); IIC_Send_Byte(command); IIC_Wait_Ack(); IIC_Stop(); } void WriteData(u8 data) //写数据函数 { IIC_Start(); IIC_Send_Byte(0x78);//OLED地址 IIC_Wait_Ack(); IIC_Send_Byte(0x40);//写数据寄存器地址 IIC_Wait_Ack(); IIC_Send_Byte(data); IIC_Wait_Ack(); IIC_Stop(); } void OLED_WR_Byte(u8 dat,u8 cmd) //为了直接替换上面,做一个封装函数 { if(cmd) WriteData(dat); else WriteCmd(dat); }

这里采用的是模拟IIC通信方式,在main函数中要先配置IIC初始化

四.SPI驱动方式

SPI模式使用的信号线有如下几条: CS:OLED 片选信号。 RST(RES):硬复位 OLED。 DC:命令/数据标志(0,读写命令;1,读写数据)。 SCLK:串行时钟线。在 4 线串行模式下,D0 信号线作为串行时钟线 SCLK。 SDIN:串行数据线。在 4 线串行模式下,D1 信号线作为串行数据线 SDIN。 在 4 线串行模式下,只能往模块写数据而不能读数据。 在 4 线 SPI 模式下,每个数据长度均为 8 位,在 SCLK 的上升沿,数据从 SDIN 移入到 SSD1306,并且是高位在前的。DC 线还是用作命令/数据的标志线。在 4 线 SPI 模式下,写操作的时序如图 17.1.6 所示: 在这里插入图片描述 一些驱动方式与显示代码均与上面一致,因此这里只介绍SPI写数据/命令驱动代码,也即重写OLED_WR_Byte(u8 dat,u8 cmd)函数,其他均不变!

//向SSD1306写入一个字节 //dat:要写入的数据/命令 //cmd:数据/命令标志 0,表示命令;1,表示数据 //STM32F407采用硬件SPI发送数据(也可采用模拟SPI方式发送数据,在后续的博客中会有介绍) void OLED_Write_Byte(uint8_t dat) { SPI1_ReadWriteByte(dat); //调用硬件SPI写数据函数 } //写数据 void OLED_Write_Data(uint8_t dat) { CS=0; DC=1; OLED_Write_Byte(dat); } //写命令 void OLED_Write_Cmd(uint8_t cmd) { CS=0; DC=0; OLED_Write_Byte(cmd); } //为了直接替换上面,做一个封装函数 void OLED_WR_Byte(u8 dat,u8 cmd) { if(cmd) OLED_Write_Data(dat); else OLED_Write_Cmd(dat); }

    小结:OLED的驱动方式非常简单,应用起来也非常的方便,分辨率也较高,作为平时辅助开发的小工具也是极好的。在上文中对于各种字符的显示均给出了驱动程序,可以非常方便的调用,另外对于字符取模也有很多可用的小软件,大家可自行应用。 至此,OLED显示屏的几种驱动方式均已介绍完,也预示着第一篇博客的完结。作为刚入行半年的嵌入式小白,小心翼翼的编辑每一行文字。但由于技术水平有限,难免会有诸多错误之处,还希望得到诸位大神的批评指教,也希望借此平台可以和大家畅所欲言,共同进步!

五. 感谢支持

    完结撒花!希望看到这里的小伙伴能点个关注,我后续会持续更新,也欢迎大家广泛交流。     码字实属不易,如果本文对你有10分帮助,就赏个10分把,感谢各位大佬支持!

在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭