0.96寸OLED屏显示测试和代码详细分析SPI通信

news2024/11/25 20:26:37

第一次尝试点亮

程序代码地址,密码:1234。
买了一个两色的oled,然后下载了资料,手里有一个8266的arduino,所以为了方便就直接用了。使用arduino主要原因,单片机keil太大,来回找文件修改引脚比较麻烦。实际在spi的通信方面的原理都是一样。
首次尝试,遇到问题,
1,资料中的引脚号需要修改
2,点阵取模得到的各种字符的**font.h文件和工程文件(.ino)**需要放在同级文件夹内。介绍中建议是放在arduino的lib文件夹中,但为了方便,也可以直接读取,所以直接移动一个文件夹就行。而且这个只是示例字符文件,没必要保存。
在这里插入图片描述
3,需要注意,如果只是给了电源电压,OLED也是不会亮的。个人本来怀疑屏坏了,后来接上信号线后,下完程序,发现能正常显示,不知道为什么手机拍的颜色有点儿失真。
在这里插入图片描述

驱动SSD1306读取工作时序分析

在这里插入图片描述
从时序图中可以看出,主要包含6种时间:时钟周期,地址设置时间,芯片选择时间,读写数据时间,时钟周期中高低时间,上升下降沿时间
时钟周期:大于100ns=10-7s,也就是时钟频率小于10MHz,
时钟周期中低电平和高电平时间:大于15ms
地址(数据/命令)设置/保持时间、写/读数据时间:设置是传送数据还是传送命令,会发现两种时间的值是一样的。从根本上来讲写入命令和写入地址都是进行信息传递。
上升沿和下降沿时间:最大是40ns,理论上,理想的波形应该是矩形波,也就是上升和下降沿是0s。

时间的整体分析:
首先,第一个时间是片选时间cs起作用,毕竟没选择好设备,发送数据或命令都无意义;由于数据或命令的传送都是在时钟的上升沿完成,所以在上升沿的那段时间,必须保证D/C(数据/命令)和数据传送的电平稳定。

常用设置分析(实际就是对驱动SSD1306的理解)

OLED基本参数

0.96寸双色显示屏,支持IIC和spi通信,128*64pixels,8page显示内存,相当于将屏幕的行按照字节数分为8份

驱动手册的命令使用和查找方式

来源:可以通过很多途径,有些只是给了部分常用内容,若想知道详细的手册可以去一些关于硬件手册的网站(例如半导小芯等)查询下载,下面是截取一部分命令表格说明使用方式
在这里插入图片描述

初始化使用的命令

下面的OLED_WR_Byte是定义的函数,MCU把程序写入到驱动,进而控制显示屏。不同的编程软件和MCU来看,程序的表现形式可能不同,但基本命令是一样的。这些命令都可以通过手册找到。
几个比较重要和常需要变化的命令:
1,设置对比度:这里感觉就是亮度,命令如下图,根据上面查看手册命令的方式,可以知道需要发送两次命令,第一次的0x81只是告诉驱动下个自己的命令是对比度的值
在这里插入图片描述
2,显示有关命令包括屏幕打开(AF)/关闭(AE),数据位0(A7)还是1(A6)亮,上下,左右(26/27)滚动,都可通过手册中查到
在这里插入图片描述

地址显示位置命令

参考手册中9 Command Table中的3 Addressing Setting Command Table
这个控制画面的显示位置,需要控制内存地址的模式,列开始,行开始和结束
首先知道,有8个page,相当于可以存储8个128*64的显示缓存

内存地址模式有三种Page addressing modeHorizontal addressing modeVertical addressing mode

在这里插入图片描述

	OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
	OLED_WR_Byte(0x02,OLED_CMD);//也就是A[1:0]=10b

Page addressing mode模式

这种模式:到每个page结尾指针会自动到开始,但并没有到下一个page
在这里插入图片描述
这种模式设置起始列位置需要两个命令
在这里插入图片描述
设置page起始
在这里插入图片描述

Horizontal addressing mode

这种地址分布是到行结尾自动跳转到开始,且page也自动到下一个,到最后page结束又会指向第一个page。在这里插入图片描述
设置列的起始和结束
在这里插入图片描述
设置page的起始
在这里插入图片描述

下面模式的地址分布从上到下,从左到右
在这里插入图片描述

在这里插入图片描述

字节数据(data/command)传送

在这里插入图片描述
下图程序中的设置和上图的数据传送时序图刚好匹配
在这里插入图片描述

字符数据显示

整体方法,对字符取模,在初始化设置完成的情况下,将字模矩阵数据传入驱动
ASCII字母标
在这里插入图片描述

	void OLED_Set_Pos(unsigned char x, unsigned char y) 
{ 
	/*
	x±íʾ¿ªÊ¼ÏÔʾµÄÏñËØÆðʼλÖÃ
	y±íʾÏÔʾÔÚÄÇÒ»Ò³
	*/
	OLED_WR_Byte(0xb0+y,OLED_CMD);     //ÉèÖõØÖ·Ò³£¬y¡Ê[0£¬7]
	//½«ÏÔʾµÄ¿ªÊ¼µØÖ·ÖеĸßËÄ룬ºÍµÍËÄλ·Ö¿ªºóдÈë¸øOLED
	//¶ø8λµÄ·¶Î§
	OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);  //ÉèÖÃÏÔʾλÖᪿªÊ¼ÁеØÖ·µÄµÍËÄλ
	OLED_WR_Byte((x&0x0f)|0x01,OLED_CMD);    //ÉèÖÃÏÔʾλÖᪿªÊ¼ÁеØÖ·¸ßËÄλ
}   	
/*参数含义(c51程序)
x,显示位置的横坐标x
y,显示位置纵坐标y
下面程序中几个参数是宏定义过的,
size=16(字模16*8),OLED_DATA=1(传送的是数据)
*/
void OLED_ShowChar(u8 x,u8 y,u8 chr)
{      	
	unsigned char c=0,i=0;	
		c=chr-' ';					//字符在ascii位置	
		if(x>Max_Column-1)  //如果显示到最右边
			{x=0;y=y+2;}	//到最左边,向下移动两个像素
		if(SIZE ==16)
			{
			OLED_Set_Pos(x,y);	//设置字符显示的起始地址
			for(i=0;i<8;i++)    //将一个字节的8个位按位传送出去
				OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);   //F8X16是取字模的数组,这个传送方式要看具体的取模方式
			OLED_Set_Pos(x,y+1);  //向下移动一个地址页page
			for(i=0;i<8;i++)
				OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
			}
		else {	
				OLED_Set_Pos(x,y+1);
				for(i=0;i<6;i++)
				OLED_WR_Byte(F6x8[c][i],OLED_DATA);
				
			}
}

想要分析上面显示代码的位置分配原因,需要考虑取字模的方式
在这里插入图片描述


{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01},/*"-",0*/
/* (8 X 16 , 隶书 )*/

从字模库中找到字符“-”的矩阵反推出取模方式
请添加图片描述

取模方式,低位先取到
在这里插入图片描述
下面是驱动中的像素分配地址方式,
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

			/*传入显示的数据*/
			OLED_Set_Pos(x,y);	//设置字符显示的起始地址
			for(i=0;i<8;i++)    //将一个字节的8个位按位传送出去
				OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);   //F8X16是取字模的数组,这个传送方式要看具体的取模方式
			OLED_Set_Pos(x,y+1);  //向下移动一个地址页page
			for(i=0;i<8;i++)
				OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
				
			/*设置地址OLED_Set_Pos中的纵轴方向设置,下面手册中命令可以看出*/
			OLED_WR_Byte(0xb0+y,OLED_CMD);	

这里设置的特定的模式,第二个16进制位表示进入的page
在这里插入图片描述

上面一段代码的写入字节过程如下图所示,F8X16[c*16+i],其中c*16是一个字符占16字节,所以得到了字符索引,一个字符中的16个字节需要按字节送入,所以才有偏置i。当前8个字节的数据传送完,需要在驱动中换page。**OLED_Set_Pos(x,y+1);**的作用不只是换一行,而是以字节为单位换行,也就是换page
在这里插入图片描述

字符串传送

//实际上就是将字符串看作指针,对每个字符遍历显示,直到最后一位
void OLED_ShowString(u8 x,u8 y,u8 *chr)
{
	unsigned char j=0;
	while (chr[j]!='\0')
	{		OLED_ShowChar(x,y,chr[j]);
			x+=8;   //每个字符横向占8个位
			//到屏幕最右边若不够放下一个字符,会跳转到下一行显示,y+=2是因为,一个字符高度是两个字节
		if(x>120){x=0;y+=2;} 
			j++;
	}
}

个人感觉和认知

整体来看,好像有很多命令。但按照手册中的介绍初始化还是很方便的。
数据手册的查看很重要。显示屏的正常显示需要很清楚知道硬件取模和软件驱动的数据写入方式
屏幕的显示很依赖字符或图片的取模方式和硬件的实际接线方式。
对于驱动的控制有两种方式:传入命令或数据。传入命令或数据的判断是通过给显示屏一个引脚高低电平控制的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1014974.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在ubuntu20下使用花生壳映射vscode SSH

1、在ubuntu20下安装花生壳 下载花生壳&#xff1a;花生壳客户端官方下载 - 贝锐花生壳官网 选择ubuntu 或者 wget "https://dl.oray.com/hsk/linux/phddns_5.2.0_amd64.deb" -O phddns_5.2.0_amd64.deb 安装 :sudo dpkg -i phddns_5.2.0_amd64.deb" -O phddns…

【sgGoogleTranslate】自定义组件:基于Vue.js用谷歌Google Translate翻译插件实现网站多国语言开发

sgGoogleTranslate源码 <template><div :id"$options.name"> </div> </template> <script> export default {name: "sgGoogleTranslate",props: ["languages", "currentLanguage"],data() {return {//…

图解曲线积分的对称性

1.图解曲线积分的对称性 1.1 第一类曲线积分的一般对称性 二重积分、三重积分、第一类曲线积分、第一类曲面积分的一般对称性其原理都类似 平面曲线和空间曲线的原理一样&#xff0c;以下内容以空间曲线为例 图中所示为积分区域 Γ \Gamma Γ&#xff0c;函数 f ( x , y , z…

利用 Python PyPDF2库轻松提取PDF文本(及其他高级操作)

当需要从PDF文件中提取文本时&#xff0c;Python中的PyPDF2库是一个非常有用的工具。无论您是需要分析PDF文档中的内容还是需要在文档中搜索特定的信息&#xff0c;PyPDF2都可以帮助您轻松实现这些任务。 在本文中&#xff0c;我们将探讨如何使用PyPDF2库提取PDF文件中的文本&…

vue学习之vue cli创建项目

安装 node.js https://nodejs.org/en 安装 vue cli npm install -g @vue/cli --registry=https://registry.npm.taobao.org创建项目 执行创建命令,回车vue create vue-cli-learning选择 “Manually select features”,回车 “空格” 关闭 Linter / Formatter 选项,回车

开源库源码分析:OkHttp源码分析(二)

开源库源码分析&#xff1a;OkHttp源码分析&#xff08;二&#xff09; 导言 上一篇文章中我们已经分析到了OkHttp对于网络请求采取了责任链模式&#xff0c;所谓责任链模式就是有多个对象都有机会处理请求&#xff0c;从而避免请求发送者和接收者之间的紧密耦合关系。这篇文章…

【数据结构】链表面试题

203.移除链表元素 206.反转链表 876.链表的中间结点 牛客.链表中倒数第k个结点 21.合并两个有序链表 牛客.链表分隔 牛客.链表的回文结构 160.相交链表 141.环形链表 142.环形链表2 1. 移除链表元素 题目描述 思路&#xff1a; 定义一个指针cur遍历整个链表&#xff0c;一个ta…

阿里云 linux 的nginx 配置uni-app的H5前端项目vue,后端接口阿里云。

背景 vue项目调用接口是阿里云的&#xff0c;H5网站也要部署到阿里云&#xff0c;2个不同的服务器&#xff0c;需要做nginx部署与api代理。 端口配置 首先当然是买个阿里云服务器&#xff0c;这里是配置是linux系统&#xff0c;配置访问的域名 &#xff0c;再接着&#xff1…

【李沐深度学习笔记】数据操作

本课观看地址 数据操作p1 N维数组样例 N维数组是机器学习和神经网络的主要数据结构 1-d向量就是样本的各特征抽象成一个向量&#xff1b;2-d矩阵的每一行是一个样本&#xff0c;每一行都是一个样本的特征向量 3-d可以表示RGB图片&#xff0c;RGB图像是一个三维数组&#xff…

MarkText如何实现图床-解决md上传到csdn图片不显示的问题

安装picgo-core-这样做无法自动上传截图 npm install picgo -g配置-此处以github为例 picgo set uploader github生成token settings>Developer settings>Personal access tokens>Token(classic) 配置MarkText 点击左下角的设置在弹出的窗口后选择左边的Image在右…

学习Bootstrap 5的第十三天

目录 提示框 如何创建提示框 实例 指定提示框的位置 实例 弹出框 如何创建弹出框 实例 指定弹出框的位置 实例 关闭弹出框 实例 提示框 提示框是一个小小的弹窗&#xff0c;在鼠标移动到元素上显示&#xff0c;鼠标移到元素外就消失。 如何创建提示框 Bootstrap…

VIRTIO-SCSI代码分析(2)VIRTIO 驱动分析

QEMU模拟出VIRTIO SCSI设备后&#xff0c;在虚拟机中呈现SCSI设备和PCIE设备。而在虚拟机中&#xff0c;PCIE设备与VIRTIO PCI驱动匹配触发virtio_pci_probe()注册生成virtio设备&#xff0c;而virtio设备与虚拟机中的virtio驱动匹配触发对应probe函数最终注册对应的驱动。 这里…

T5 和 mT5

T5Architecture&#xff1a;The Best One1. Main Body2. Embedding3. Pertrain and Finetune4. Multi-Task Pertrain and Finetune5. T5总结 mT5 T5&#xff1a;https://arxiv.org/pdf/1910.10683.pdf T5 blog: https://ai.googleblog.com/2020/02/exploring-transfer-learning…

无涯教程-JavaScript - AGGREGATE函数

描述 返回列表或数据库中的聚合。 AGGREGATE函数可以将不同的聚合函数应用于列表或数据库,并且可以选择忽略隐藏的行和错误值。 AGGREGATE函数具有两种不同的格式- 参考格式数组格式 参考格式 语法 AGGREGATE (function_num, options, ref1, [ref2] …)争论 Argument描述…

Linux驱动中断与时间篇——中断下半部的三种方法

文章目录 什么是中断下半部softirq软中断实例 tasklettasklet使用tasklet实例 work queue 什么是中断下半部 当产生一个中断时&#xff0c;会进入中断处理程序。 但中断处理程序必须快速、异步、简单的对硬件做出迅速响应并完成那些时间要求很严格的操作。 因此&#xff0c;对…

课程学习成绩评分F2计算器

前言&#xff1a; 由于大二的时候计算成绩太麻烦了&#xff0c;特别是综测评定小组还需要验证其他同学的是否正确&#xff0c;对于这种重复性高的工作&#xff0c;首先要想到的就是用计算机来实现&#xff0c;想起来上学期学了一点Java&#xff0c;就想简单的写一个程序。 C …

【PowerQuery】PowerBI Pro账户的自动刷新

在数据和模型通过发布或者上传方式上传到PowerBI Pro中,如何来进行数据刷新呢?数据源依然在本地,而数据模型已经发布到PowerBI Pro云端服务中。如果数据源更新,我们的模型如何进行自动刷新呢? PowerBI Pro如果需要基于本地数据源更新进行模型更新需要部署相应的数据网关服…

Pytorch学习笔记(模型训练)

模型训练 在同一个包下创建train.py和model.py&#xff0c;按照步骤先从数据处理&#xff0c;模型架构搭建&#xff0c;训练测试&#xff0c;统计损失&#xff0c;如下面代码所示 train.py import torch.optim import torchvision from torch import nn from torch.utils.da…

Leetcode165. 比较版本号

力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 代码如下&#xff1a; class Solution {public int compareVersion(String version1, String version2) {int i 0, j 0;while(i < version1.length() || j < version2.length()){long num1 0…

交换两数整有几种途径

原本以为利用变量或者异或可以交换两个整数&#xff1b;今天学到&#xff0c;加减也可以实现两个整数的交换。 (本笔记适合熟悉一种编程语言的 coder 翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程…