OLED的波形曲线、进度条、图片显示(STM32 HAL库 模拟SPI通信 5线OLED屏幕)详细篇
少废话,先上效果图
屏幕显示效果

全家福

一、基础认识及引脚介绍
屏幕参数:
尺寸:0.96英寸
分辨率:128*64
驱动芯片:SSD1306
驱动接口协议:SPI
引脚说明:

二、 SSD1306芯片介绍
SSD1306是一款带控制器的用于OLED点阵图形显示系统的单片CMOS OLED/PLED驱动器。它由128个SEG(列输出)和64个COM(行输出)组成。
SSD1306嵌入了对比度控制器、显示RAM和振荡器,从而减少了外部组件的数量和功耗。它有256级亮度控制。数据/命令可以通用硬件选择3种通信方式:6800/8000串口、IIC接口和SPI接口。适用于手机子显示器、MP3播放器、计算器等多种便携应用。
模块有多种通信方式,包括串口、IIC、SPI,其选择通过硬件固化,如果使用IIC通信方式时可以选择两个IIC地址,其分别为0x78和0x7A。
三、 通信方式(4线SPI)
所谓的4线SPI并非是收发一体的标准4线SPI协议,标准的4线SPI为SCLK、CS、MOSI、MISO,模块所述大的4线SPI是单向的,即MISO(主入从出)变成了D/C(数据命令选择脚)。
该4线串行接口由串行时钟SCLK、串行数据SDIN、数据命令选择线D/C#、片选信号CS#组成.在四线SPI模式下,D0为SCLK,D1为SDIN。
其真实使用的是标准的3线SPI,也就是省略了MISO(主入从出)数据线。
数据命令选择:DC为高时表示数据,DC为低时表示写命令
片选:CS脚为低电平是选中,如果不通信时将脚输出高电平
数据通信:在SCLK的每一个上升边上,SDIN按D7,D6,…D0,高位先写出
通信时序图

四、编程(CubeMX部分)
(一) CubeMX基础配置
选择芯片(STM32F103C8T6)

打开外部的高速和低速晶振

所占用的引脚

开启SWD调试

所占用的引脚

时钟树设置
设置系统时钟为最高速度,72MHZ

(二) GPIO初始化
初始化电平分析
D0:SCLK,时钟线,上升沿有效,所以默认输出高电平
D1:SDIN,数据线,默认输出电平随意
RST:复位脚,低电平复位,默认电平为低
DC:数据/命令选择脚,默认输出电平随意
CS:片选引脚,默认输出高电平
引脚选择
使用单片机是STM32F103C8T6

考虑到已经使用的IO和硬件上的布局,最好是将一个模块的相关线放在一起,所以选择如下接线方式:
D0 ----> B5
D1 ----> B6
RST ----> B7
DC ----> B8
CS ----> B9
(三) CubeMX GPIO配置

所使用的IO

(四) 整体配置图

五、 编程(程序部分)
(一) 分析原理
有IIC通信方式为什么要有SPI,我看可以简单对比一下:
IIC通信方式:两条数据线,通信数据较慢
SPI通信方式:四条数据线,通信数据脚快
这就看项目需要,如果需要刷屏速度的话当然选用SPI方式优秀

在此之前要知道,OLED SPI通信中不需要单片机读取OLED模块的任何数据,所以单片机按照一定的规则向SPI线上写数据就可以了。在通信中单片机充当SPI的主机,OLED模块为SPI的从机。因为主机不需要接收从机数据,所以标准的四线SPI中MISO线就没必要存在了。通信使用的是标准的三线SPI,即CS、CLK、MOSI。
根据这个时序图就可以了解如何变成,在CS为低电平时就是芯片通信启动;D/C是数据或者命令的选择,也就是主机拉高拉低可以控制写的数据是指令还是数据;SCLK(D0)是时钟引脚,MOSI (D1 SDIN)为数据已经。当SCLK上升沿的瞬间,从机将会读取MOSI上的电平。发送一个字节时,是高位在前低位在后的。
所以发送一个字节大的函数,这实现了单向的数据传输SPI
实现步骤:
l 先保证时钟线默认为低电平
l 循环发送8位数据,发送最高位数据:
| 设置时钟线为低电平
| 判断发送的数据是1还是0,1则发送高电平,0则低低电平
| 设置时钟线为高电平(此时有上升沿)
l 数据左移一位,让次高位在最高位上
l 循环发送8位数据,发送次高位数据:
| 设置时钟线为低电平
| 判断发送的数据是1还是0,1则发送高电平,0则低低电平
| 设置时钟线为高电平(此时有上升沿)
l 数据左移一位,……
l ……
l 保证时钟线最终为高电平
代码,需要交流可加本人微信,见文章结尾
数据和命令分发:
OLED SPI方式为了更快的数据交互,有一个专门的引脚作为数据和命令选择脚,而IIC还要靠发送数据去做判断,可想而知他们的速率会有相差。
D/C引脚就是数据/命令选择,低电平写命令,高电平写数据
设计思路:
l 如果是命令,则拉高DC引脚
l 如果不是命令,则拉低DC引脚
l CS引脚拉低表示选中从机,开启通信
l 发送一个数据,则调用了前面的标准3线SPI通信函数
l 拉高DC引脚
l 拉高CS引脚,关闭通信
代码,需要交流可加本人微信,见文章结尾
六、OLED进阶版及曲线显示
(一)驱动分析
想要了解OLED显示曲线就必须了解其显示本质,更加底层细致的分析寄存器及显示原理。
0.96寸的12864 OLED屏幕由128*64个发光二极管组成。
这是数据手册的截图

注意图总的黑色和绿色,它只是告诉你可以反向,也就是0编号的位置可以换成127编号而已。
由此可见屏幕总共分为8页(page),每页占用Y轴的8行发光二极管和X轴的128个发光二极管,所以一页总共占用8*128=1024个发光二极管。
所以在真实的图中表示:

这是数据手册中其中一页的表示
这是基于没有做反转时的介绍,如果反转了就不是这样了。反转是在程序初始化是调用的,后面分析的初始化函数有介绍

其中“Each lattice represents one bit of image data”的翻译是“每个格子代表一个图像数据位”,因为一页刚好8个Y方向的各种,对应的刚好是U8类型,所以我们通常用一个U8表示一页里的一个列的显示,一页中共有128个列,所以一页总共需要1*128=128个U8类型数据。并且从图中可以看出,最下面的是最高位。
举个栗子:
假如我们拿第二页的第一列来说,其值的二进制为11110000,其实点亮的是如下图的红色部分。

这也就说明高位点亮的是下面的位置。
(二)初始化函数及逐条分析
1 void my_oled_init(){
2 my_oled_rst();
3 my_oled_write_byte(0xAE,OLED_CMD);//关闭显示
4
5 my_oled_write_byte(0x00,OLED_CMD);//X轴低位,起始X轴为0
6 my_oled_write_byte(0x10,OLED_CMD);//X轴高位
7 my_oled_write_byte(0x40,OLED_CMD);//Y轴,可设区间[0x40,0x7F],设置为0了
8
9
10 my_oled_write_byte(0xA1,OLED_CMD);//设置X轴扫描方向,0xa0左右反置 ,0xa1正常(左边为0列)
11 my_oled_write_byte(0xC8,OLED_CMD);//设置Y轴扫描方向,0xc0上下反置 ,0xc8正常(上边为0行)
12 my_oled_write_byte(0xA6,OLED_CMD);//位值表示的意义,0xa6表示正常,1为点亮,0为关闭,0xa7显示效果相反
13
14
15 my_oled_write_byte(0x81,OLED_CMD);//命令头,调节亮度,对比度,变化很小,但是仔细可以观察出来
16 my_oled_write_byte(0xFF,OLED_CMD);//可设置区间[0x00,0xFF]
17
18 my_oled_write_byte(0xA8,OLED_CMD);//命令头,设置多路复用率(1 to 64)
19 my_oled_write_byte(0x3f,OLED_CMD);//--1/64 duty
20
21 my_oled_write_byte(0xD3,OLED_CMD);//命令头,设置显示偏移移位映射RAM计数器(0x00~0x3F)
22 my_oled_write_byte(0x00,OLED_CMD);//不偏移
23
24 my_oled_write_byte(0xd5,OLED_CMD);//命令头,设置显示时钟分频比/振荡器频率
25 my_oled_write_byte(0x80,OLED_CMD);//设置分割比率,设置时钟为100帧/秒
26
27 my_oled_write_byte(0xD9,OLED_CMD);//命令头,--set pre-charge period
28 my_oled_write_byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
29
30 my_oled_write_byte(0xDA,OLED_CMD);//命令头,--set com pins hardware configuration
31 my_oled_write_byte(0x12,OLED_CMD);
32
33 my_oled_write_byte(0xDB,OLED_CMD);//命令头,--set vcomh
34 my_oled_write_byte(0x40,OLED_CMD);//Set VCOM Deselect Level
35
36 my_oled_write_byte(0x20,OLED_CMD);//命令头,设置寻址模式
37 my_oled_write_byte(0x10,OLED_CMD);//页面寻址模式(重置) (0x00/0x01/0x02)
38
39 my_oled_write_byte(0x8D,OLED_CMD);//命令头,--set Charge Pump enable/disable
40 my_oled_write_byte(0x14,OLED_CMD);//--set(0x10) disable
41
42 my_oled_write_byte(0xA4,OLED_CMD);//恢复到RAM内容显示(重置)
43
44 my_oled_clear();//清屏
45
46 my_oled_write_byte(0xAF,OLED_CMD); //开启显示
47
48 }
局部分析:
设置寻址模式

A[1:0] = 00b,水平寻址模式
A[1:0] = 01b,垂直寻址模式
A[1:0] = 10b,页面寻址模式(重置)
A[1:0] = 11b,无效
00b,水平寻址模式

01b,垂直寻址模式

10b,页面寻址模式

寻址模式对应着我们的取模:

我们取模软件设置的刷新方式:
从左到右从上到下:对应了页面寻址模式
纵向8点下高位:纵向右8个点,最下面的点为最高位
其它相关逐条分析内容,可加本人微信获取,见文末
(三) 寄存器配置补充(详细)
需要资料可加本人微信,见文末
原文链接:https://www.cnblogs.com/dongxiaodong/p/14321569.html
如需资料可加本人微信

微信号:dongxiaodongwx
OLED的波形曲线、进度条、图片显示(STM32 HAL库 模拟SPI通信 5线OLED屏幕)详细篇的更多相关文章
- Winform之跨线程访问控件(在进度条上显示字体)
此文章对于遇到必须使用线程但是没有办法在线程内操作控件的问题的处理 有很好的解决方案(个人认为的.有更好的方案欢迎交流.) 在做跨线程访问之前我们先了解下我们所做的需要达到的效果: 这个是批量的将x ...
- HTML5效果:Canvas 实现圆形进度条并显示数字百分比
实现效果 1.首先创建html代码 <canvas id="canvas" width="500" height="500" styl ...
- 基于uploadify.js实现多文件上传和上传进度条的显示
uploadify是JQuery的一个插件,主要实现文件的异步上传功能,可以自定义文件大小限制.文件类型.是否自动上传等属性,可以显示上传的进度条.官网地址是http://www.uploadify. ...
- C# 时间控件 竖直进度条 饼图显示 仪表盘 按钮基础控件库
Prepare 本文将使用一个NuGet公开的组件来实现一些特殊的控件显示,方便大家进行快速的开发系统. 在Visual Studio 中的NuGet管理器中可以下载安装,也可以直接在NuGet控制台 ...
- iOS开发:代码通用性以及其规范 第一篇(附带,自定义UITextView\进度条\双表显示\瀑布流 代码设计思路)
在iOS团队开发中,我见过一些人的代码,也修改过他们的代码.有的人的代码写的非常之规范.通用,几乎不用交流,就可以知道如何修改以及在它基础上扩展延生.有的人的代码写的很垃圾,一眼看过去,简直会怀疑自己 ...
- commons-fileupload实现上传进度条的显示
本文将使用 apache fileupload ,spring MVC jquery 实现一个带进度条的多文件上传, 由于fileupload 的局限,暂不能实现每个上传文件都显示进度条, ...
- ajax 上传文件,显示进度条,进度条100%,进度条隐藏,出现卡顿就隐藏进度条,显示正在加载,再显示上传完成
<form id="uploadForm" method="post" enctype="multipart/form-data"&g ...
- jquery实现拖拽进度条并显示百分比的特效
#box{position: relative; width: 200px; height: 50px; border: 1px solid #eee; margin: 50px auto 0;} # ...
- jquery实现拖拽进度条并显示百分比
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xht ...
随机推荐
- 工具-Git与GitHub-GitHub使用(99.5.3)
@ 目录 1.在github中添加公钥 2.克隆项目 3.在本地工作区新建分支,修改文件并提交 4.推送到远程仓库 5.从远程分支上拉取代码 关于作者 1.在github中添加公钥 首次使用git必须 ...
- RabbitMQ史上最全文章
老规矩,本篇文章 不做 RabbitMQ 的 编码讲解 ,只介绍 文章学习的一些优秀文章 重点在于不要循规蹈矩,教程 这样走,你不一定要按他这样走,按自己的方式来,学习效率会更高,网上的教程有很多,今 ...
- C# 数据结构与算法 操作系统原理 计算机网络原理 数据库开发学习
https://www.cnblogs.com/edisonchou/p/3843287.html PDF https://files.cnblogs.com/files/netlock/%E6%95 ...
- Windows 64位下安装Redis 以及 可视化工具Redis Desktop Manager的安装和使用
二.下载Windows版本的Redis 由于现在官网上只提供Linux版本的下载,所以我们只能在Github上下载Windows版本的Redis Windows版本的Redis下载地址:https:/ ...
- [LeetCode]160. Intersection of Two Linked Lists判断交叉链表的交点
方法要记住,和判断是不是交叉链表不一样 方法是将两条链表的路径合并,两个指针分别从a和b走不同路线会在交点处相遇 public ListNode getIntersectionNode(ListNod ...
- [LeetCode]690. Employee Importance员工重要信息
哈希表存id和员工数据结构 递归获取信息 public int getImportance(List<Employee> employees, int id) { Map<Integ ...
- 5个有趣且不必要的 JavaScipt 技巧
前一段时间,我创建了一个标题为"7个可爱的Web开发技巧"的帖子.在这里,我描述了一些有趣的技巧,您可以使用3种主要的Web技术之一来实现这些技巧-html,css和JavaScr ...
- Java常用类学习笔记总结
Java常用类 java.lang.String类的使用 1.概述 String:字符串,使用一对""引起来表示. 1.String声明为final的,不可被继承 2.String ...
- flume伪分布式安装
flume伪分布式安装: 1.导包:apache-flume-1.7.0-bin.tar.gz 2.配置环境变量:/etc/profile export FLUME_HOME=/yang/apache ...
- CentOS8_在线安装_网络源_网络镜像源填写格式_以及其他笔记
CentOS8_在线安装_网络源_网络镜像源填写格式_以及其他笔记 转载注明来源: 本文链接 来自osnosn的博客,写于 2020-10-1. 参考: Centos8.0.1905 在线安装源选择 ...