基于IIC通信的显示器OLED编程详解(一篇搞懂)

这篇具有很好参考价值的文章主要介绍了基于IIC通信的显示器OLED编程详解(一篇搞懂)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言:

上一篇博客介绍了IIC通信,这篇我们就来玩玩oled模块。当然选用的是IIC接口,因为市面上还有一种是SPI接口的。对于oled长啥样,采用了什么材料,工艺怎么怎么样等等这里就不作任何介绍,搞得眼花缭乱的,对我们用它做开发也没任何帮助,同时节省读者阅读时间。为什么会有这种想法,就是因为发现一些博客在无关紧要的东西方面写了大半篇幅,而在实现原理方面草草了之,再放点代码,贴个效果实现图就算完事了,虚的一批。所以想自己写点东西,话不多说,下面直接开干,上技术活。

强调: 相关IIC通信代码请参考我的上篇博客

1、写模式——写命令与写数据

当我们拿到一个硬件产品准备做开发时,毫无疑问首先要做的就是参考产品说明书。找到我们实现某项功能需要参考的点。OLED是一个电子显示屏,我们用它无非就是显示一些数字,文字,图片。归根到底这些都属于数据,单片机通过IIC协议与oled进行通信,实现数据传输。这就需要按照IIC总线数据格式(如图)进行,有一种“在道上走,就要按照道上的规矩办事"的感觉。
基于IIC通信的显示器OLED编程详解(一篇搞懂)

(1)说明:

  • S:开始状态 即:start();
  • Slave Address:从地址,如上图红色框内,根据说明书可以为b0111100或b0111101,当R\W为0时为写模式。所以可以选择从地址:01111000,即0x78。
  • ACK 应答信号
  • 上图第四部分(蓝色框内),根据说明书从地址发送完后,发送的就是控制字节和数据字节。当控制字节Co位为0时,发送的信息只包含数据字节。当D/C位为0时数据字节作为命令,为1时作为数据。所以图中控制字节可以为:00000000=0x00(后面数据字节为写入指令),01000000=0x40(后面数据字节为写入数据)。
  • 写入指令/数据
  • ACK应答信号
  • STOP 终止信号

(2)编码:

void Oled_Write_Cmd(char Cmd)
{
	IIC_Start();
	IIC_Send_Byte(0x78);
	IIC_AcK();
	IIC_Send_Byte(0x00);
	IIC_Ack();
	IIC_Send_Byte(Cmd);
	IIC_Ack();
	IIC_Stop();
}
void Oled_Write_Data(char Data)
{
	IIC_Start();
	IIC_Send_Byte(0x78);
	IIC_AcK();
	IIC_Send_Byte(0x40);
	IIC_Ack();
	IIC_Send_Byte(Data);
	IIC_Ack();
	IIC_Stop();
}
//IIC通信相关代码参考上篇博客

2、寻址模式

向oled写入了命令也写入了数据。那还有一个就是我要在哪个位置显示。OLED是分辨率为128*64的点矩阵,或是说嵌入式128 x 64位SRAM显示缓冲区。关于它的寻址模式有三种,分别为页寻址模式,水平寻址模式和垂直寻址模式。常用的是页寻址模式,所以对于后面两种在这里就不作介绍。页地址模式如下图所示:
基于IIC通信的显示器OLED编程详解(一篇搞懂)
在页面寻址模式下,完成内存中的读或写后,列地址指针自动增加1。如果列地址指针到达列结束地址(COL 127),则列地址指针将被重置为列起始地址(COL 0),而页面地址指针将不会被更改(依然为某个PAGE)。用户必须设置新的页面和列地址,才能访问下一页的RAM内容。
通过看上图我们也可以发现,需要注意三点

  • 如何配成页寻址模式
    前面提到,oled的寻址模式有三种,因此我们需要做些配置,硬件才知道我们选用的是哪种模式。查阅说明书可知如图:
    基于IIC通信的显示器OLED编程详解(一篇搞懂)

通过上图我们可以发现,页寻址模式是默认的,也就是可以不用配置。但如果我们要配也就是把A1=1,A0=0(根据紫色框内);通过黄框内的内容我们知道需要发送指令地址:1、0x20;2、0x02(星号任意,全配为0方便)

  • 页地址(PAGE)
    基于IIC通信的显示器OLED编程详解(一篇搞懂)
    如上图,X2,X1,X0总共有2的3次方种组合,对应PAGE0—PAGE7。以PAGE0为例,则X2X1X0=000,D7~D0=10110000,对应指令地址0xB0。
  • 列地址(COL)
    基于IIC通信的显示器OLED编程详解(一篇搞懂)
    如上图红框内,列地址有两个,一个高四位,一个低四位。高四位(0x10~0x1f),
    低四位(0x00~0x0f)。高四位16种可能,低四位也有16种,两者结合总共16*16超过了128(oled总共128列)。所以我们一般使用高四位0x10 ~0x17。可以这样理解,128列分为高位管8个大部分,每一个大部分管低位16位(如图)
    基于IIC通信的显示器OLED编程详解(一篇搞懂)
    比如我们想在最后一列显示,配置如下指令地址。先是确定高四位:00010111=0x17,后是确定低四位:00001111=0x0f。(是不是有种在二维平面坐标内,要同时确定x和y的坐标,才能准确确定一个点的位置的味道?)

3、获得我们想要的数据:

这里要使用到字模软件(咋用的?去找百度,不是介绍重点)。我用的是C51单片机,取模方式选择C51模式。以在Oled上显示Hello为例。得到的点阵为:

/*--  文字:  H  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,
/*--  文字:  e  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x24,0x24,0x24,0x24,0x17,0x00,
/*--  文字:  l  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,
/*--  文字:  l  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,
/*--  文字:  o  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,

上述显示每个字体对应点阵高皆为16。而通过前面的分析我们发现:OLED分辨率
为128 * 64=128 * 8 * 8。也就是一个PAGE共有128列,一个字节对应8位,剩下的高就为8了。很明显上述点阵一个字体需要占用两个PAGE。所以也就是在我们编程时候要去注意字体的高占用了多少个PAGE。用代码定义上述点阵如下:

/*--  文字:  H  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
char H1[8] = {0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08};
char H2[8] = {0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20};
/*--  文字:  e  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
char e1[8] = {0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00};
char e2[8] = {0x00,0x1F,0x24,0x24,0x24,0x24,0x17,0x00};
/*--  文字:  l  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
char l1[8] = {0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00};
char l2[8] = {0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00};
/*--  文字:  o  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
char o1[8] = {0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00};
char o2[8] = {0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00};

4、代码编写

功能实现:在OLED屏幕中央显示一个Hello字样

  1. IIC通信代码
  2. 写命令和写数据函数封装
  3. 获取数据代码
  4. 初始化函数封装
void Oled_Init(void){
	Oled_Write_Cmd(0xAE);//--display off
	Oled_Write_Cmd(0x00);//---set low column address
	Oled_Write_Cmd(0x10);//---set high column address
	Oled_Write_Cmd(0x40);//--set start line address  
	Oled_Write_Cmd(0xB0);//--set page address
	Oled_Write_Cmd(0x81); // contract control
	Oled_Write_Cmd(0xFF);//--128   
	Oled_Write_Cmd(0xA1);//set segment remap 
	Oled_Write_Cmd(0xA6);//--normal / reverse
	Oled_Write_Cmd(0xA8);//--set multiplex ratio(1 to 64)
	Oled_Write_Cmd(0x3F);//--1/32 duty
	Oled_Write_Cmd(0xC8);//Com scan direction
	Oled_Write_Cmd(0xD3);//-set display offset
	Oled_Write_Cmd(0x00);//
	Oled_Write_Cmd(0xD5);//set osc division
	Oled_Write_Cmd(0x80);//
	Oled_Write_Cmd(0xD8);//set area color mode off
	Oled_Write_Cmd(0x05);//
	Oled_Write_Cmd(0xD9);//Set Pre-Charge Period
	Oled_Write_Cmd(0xF1);//
	Oled_Write_Cmd(0xDA);//set com pin configuartion
	Oled_Write_Cmd(0x12);//
	Oled_Write_Cmd(0xDB);//set Vcomh
	Oled_Write_Cmd(0x30);//
	Oled_Write_Cmd(0x8D);//set charge pump enable
	Oled_Write_Cmd(0x14);//
	Oled_Write_Cmd(0xAF);//--turn on oled panel		
}
  1. 清屏函数封装
void Oled_Clear()
{
	unsigned char i,j;
	for(i=0;i<8;i++){
		Oled_Write_Cmd(0xB0 + i);//PAGE0 -- PAGE7
		//每个page从0列
		Oled_Write_Cmd(0x00);
		Oled_Write_Cmd(0x10);
		for(j=0;j<128;j++){
			Oled_Write_Data(0);
		}
}
}
  1. 显示字体函数封装
void display(char *adress)
{
	int i;
	for(i=0;i<8;i++){
				Oled_Write_Data(adress[i]);
		}
}
  1. 主函数
void main()
{
	//1、OLED初始化
	Oled_Init();
	//2. 选择一个位置
	//2.1 确认页寻址模式
	Oled_Write_Cmd(0x20);
	Oled_Write_Cmd(0x02);
	Oled_Clear();
	//2.2 选择PAGE3   1011 0011
	//0xB3
	Oled_Write_Cmd(0xB3);
	Oled_Write_Cmd(0x00);
	Oled_Write_Cmd(0x13);
	display(H1);
	display(e1);
	display(l1);
	display(l1);
	display(o1);
	
	Oled_Write_Cmd(0xB4);
	Oled_Write_Cmd(0x00);
	Oled_Write_Cmd(0x13);
	display(H2);
	display(e2);
	display(l2);
	display(l2);
	display(o2);
	while(1);
}

效果展示:
基于IIC通信的显示器OLED编程详解(一篇搞懂)
当然了你想要显示一张图片操作原理是一样的,就是要选择图片取模,这里就不再赘述了。效果如下:
基于IIC通信的显示器OLED编程详解(一篇搞懂)
关于这个图片128*64。所以最好封装个函数,用个双重循环,代码会显得更简洁点。

结语
有什么问题的话,欢迎留言讨论!文章来源地址https://www.toymoban.com/news/detail-488368.html

到了这里,关于基于IIC通信的显示器OLED编程详解(一篇搞懂)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于IDD技术的虚拟显示器开发实现

    IDD是Indirect Display Driver的缩写,它提供了一种快速开发出虚拟显示器的技术。所谓虚拟显示器,是指我们利用软件技术,在没有外接物理显示器的环境下,虚拟出显示器设备。每个虚拟的显示器都可以显示不同的图像内容,我们可以将虚拟显示器扩展,复制或者独立使用。 虚

    2024年04月09日
    浏览(80)
  • 基于ESP32的RGB点阵显示器

            分享一个之前制作的RGB彩灯点阵控制器。     硬件介绍:     1.主控芯片ESP32;     2.RGB灯为内置控制IC类型的,IC型号为WS2812B;     3.点阵的大小为12X10,分别使用ESP32的10个IO来控制点阵的10个显示行;     4.设置有BH1750光照传感器,对环境光线强度进行检测

    2024年02月09日
    浏览(59)
  • 基于Verilog HDL LCD1602显示器的设计

    昨天刚结束FPGA的课程设计,做的题目是用Verilog HDL编写LCD1602字符显示程序,并在开发板DE2-115上进行演示,实现的功能是显示移动字符和滚动字符,并通过一个开关来控制模式的切换。此次课程设计参考了网站上许多前辈大佬的文章,在他们的基础上进行修改。但发现许多的

    2024年02月01日
    浏览(66)
  • 基于51单片机带显示器的音乐盒设计

    点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/87512938?spm=1001.2014.3001.5503 源码获取 摘 要 单片微型计算机室大规模集成电路技术发展的产物,属于第四代电子计算机它具有高性能、高速度、体积小、价格低廉、稳定可靠、应用广泛的特点。他的

    2024年02月06日
    浏览(42)
  • 毕业设计 基于51单片机控制LED点阵显示器的设计

    序 🔥 毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的

    2024年02月02日
    浏览(68)
  • 详细介绍如何基于ESP32实现低功耗的电子纸天气显示器--附完整源码

    实现界面展示          这是一款天气显示器,由支持 wifi 的 ESP32 微控制器和 7.5 英寸电子纸(又名电子墨水)显示器供电。当前和预测的天气数据是从 OpenWeatherMap API 获取的。传感器为显示屏提供准确的室内温度和湿度。 该项目在睡眠时消耗约 14μA,在约 10 秒的清醒期

    2024年02月10日
    浏览(38)
  • 通过FPGA实现基于RS232串口的指令发送并控制显示器中目标位置

    目录 1.算法理论概述 串口通信模块 指令解析模块 位置控制模块 显示器驱动模块 2.部分核心程序 3.算法运行软件版本 4.算法运行效果图预览 5.算法完整程序工程         通过FPGA实现基于RS232串口的指令发送并控制显示器中目标位置是一种常见的应用场景,用于实现对显示器

    2024年02月16日
    浏览(53)
  • RK3588实用技巧:查看显示器支持的分辨率,基于weston修改分辨率输出

    若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/133685938 红胖子网络科技博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…   RK3588基于weston,不能自适应

    2024年02月08日
    浏览(72)
  • ManjaroLinux扩展显示器,连接显示器。

    如何设置多显示器的显示 在这里可以使用xrandr来进行设置。 1.插入显示器的接口 这时,我们把刚买的显示器的接口接到显示器上面,确保显示器和笔记本直接的连接没有问题。 2.查看显示器是否连接成功 我们输入命令 回车后可以看到如下扩展显示器的设备接口名称以及可显

    2024年02月11日
    浏览(50)
  • 显示器原理(1):CRT显示器

    大家好,这个系列将会从历史、参数角度来详细讲解显示器及跟显示器有关的技术。 首先,我们先列出一个目录,方便大家理解显示器的参数在哪里起效,这里列出的都是常见的,不常见的我们也会讲,这里就不列出了 这张表格在后几期会用到,我会详细讲解色域、刷新率

    2024年02月09日
    浏览(115)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包