打印
[其他ST产品]

stm32的IIC驱动0.96OLED

[复制链接]
683|23
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
IIC原理介绍:
llC( Inter-Integrated Circuit(集成电路总线)IIC Bus,集成电路总线,I℃)——串行通信总线
基本概念
飞利浦公司在1980年代为了让主板、嵌入式系统或手机用以连接低速周边设备,如ROM、RAM、I/0端口、A/D、D/A等IC协议已经不需要支付专利费,但制造商仍然需要付费以获取IC从属设备地址
标准模式下可以达到100kb/s,快速模式下可以达到400kb/s
>特点——
>一种总线结构
>多主从架构——真正的多主机总线
每个连接到总线的器件都可以通过唯一的地址和其它器件通信,主机/从机角色和地址可配置,主机可以作为主机发送器和
主机接收器

IC可以在通讯过程中,改变主机
如果两个或更多的主机同时请求总线,可以通过冲突检测和仲裁防止总线数据被破坏>半双工
csoN GGn小卜


使用特权

评论回复
沙发
慢动作|  楼主 | 2023-9-25 19:15 | 只看该作者
IIC是一个总线的结构但不支持总线协议
硬件结构
两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL
所有接到I2G总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上

使用特权

评论回复
板凳
慢动作|  楼主 | 2023-9-25 19:16 | 只看该作者
IIC协议——通信过程
数据的有效性:在时钟的高电平周期内,SDA线上的数据必须保持稳定,数据线仅可以在时钟SCL为低电平时改变。

使用特权

评论回复
地板
慢动作|  楼主 | 2023-9-25 19:16 | 只看该作者
起始和结束条件——由主机发出的
起始条件:当SCL为高电平的时候,SDA线上由高到低的跳变结束条件:当SCL为高电平的时候,SDA线上由低到高的跳变
>总线在起始条件之后,视为忙状态,在停止条件之后被视为空闲状态

使用特权

评论回复
5
慢动作|  楼主 | 2023-9-25 19:17 | 只看该作者
应答
每当主机向从机发送完一个字节的数据,主机总是需要等待从机给出一个应答信号,以确认从机是否成功接收到
了数据
从机应答主机所需要的时钟仍是主机提供的,应答出现在每一次主机完成8个数据位传输后紧跟着的时钟周期,低
电平0表示应答,1表示非应答

使用特权

评论回复
6
慢动作|  楼主 | 2023-9-25 19:17 | 只看该作者
>数据帧格式
地址信号+真正的数据信号起始信号后:
传送一个从机的地址(7位),第8位是数据的传送方向位(R/T),用“O”表示主机发送数据(T)
“1”表示主机接收数据(R)
[1]主机向从机发送数据,数据传送方向在整个传送过程中不变

使用特权

评论回复
7
慢动作|  楼主 | 2023-9-25 19:17 | 只看该作者
OLED介绍:
一、0.96寸OLED屏幕介绍
本文采用的是4针的0.96寸OLED显示进行讲解,采用的是SPI协议,速度会比采用I2C协议的更快,但这两者的显示驱动都一样,本质上没有太大差别。屏幕整体分辨率为128*64,有黄蓝、白、蓝三种颜色可选,驱动芯片为SSD1306

使用特权

评论回复
8
慢动作|  楼主 | 2023-9-25 19:17 | 只看该作者
二、SSD1306驱动芯片
1)图像显示RAM(GDDRAM)

GDDRAM是位映射静态RAM,大小为 128x64 位。GDDRAM分为8页(PAGE0~PAGE7),每页内1个SEG对应1Byte数据,一页由 128 Byte 组成。即屏幕每8行像素点(8PIXEL)记为一页(PAGE),64行即为8页,则屏幕变为128列(ROW)8页(PAGE),若要显示整个屏幕,则需要1288个1字节数。

使用特权

评论回复
9
慢动作|  楼主 | 2023-9-25 19:17 | 只看该作者

使用特权

评论回复
10
慢动作|  楼主 | 2023-9-25 19:18 | 只看该作者
2)最为常见的GDDRAM寻址模式——页模式
页寻址模式下,寻址只在一页(PAGEn)内进行,地址指针不会跳到其他页。每次向GDDRAM写入1byte显示数据后,列指针会自动+1。当128列都寻址完之后,列指针会重新指向SEG0而页指针仍然保持不变。通过页寻址模式我们可以方便地对一个小区域内数据进行修改。

使用特权

评论回复
11
慢动作|  楼主 | 2023-9-25 19:20 | 只看该作者
一个数据字节写入GDDRAM时,当前列(SEG)同一页(PAGE)的所有行(COM)图像数据都被填充(即由列地址指针指向的整列(8位)被填充)。数据位D0写入顶行,数据位D7写入底行(由上到下,由低到高)。

使用特权

评论回复
12
慢动作|  楼主 | 2023-9-25 19:20 | 只看该作者
所以通常用u8 GRAM[128][8] 的数组来存放像素点的显示数据,128代表列,也就是x,8代表页也即y
屏幕左上角为x=0,y=0处;

使用特权

评论回复
13
慢动作|  楼主 | 2023-9-25 19:20 | 只看该作者
3)SSD1306常见驱动命令
主要分为:

基础指令
地址指令 (控制写入显存位置)
硬件指令 (控制PAGE与COM的映射关系,列col与SEG的映射,PAGE和列col指的是显存的方位,COM和SEG指的是显示屏幕的y,x方向上的驱动器)

时序指令 (设置参数控制屏幕刷新率)
滚动指令 (控制显示的字符滚动)

使用特权

评论回复
14
慢动作|  楼主 | 2023-9-25 19:21 | 只看该作者
OLED初始化代码
//基础指令
        OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel
        OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register
        OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display
       
        //地址命令       
        OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
        OLED_WR_Byte(0x02,OLED_CMD);//设置为页模式
       
        OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
        OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
       
       
        //硬件命令
        OLED_WR_Byte(0x40,OLED_CMD);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
       
        OLED_WR_Byte(0xCF,OLED_CMD);// Set SEG Output Current Brightness
        OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常
        OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常       
        OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
        OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty
       
        OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset        Shift Mapping RAM Counter (0x00~0x3F)
        OLED_WR_Byte(0x00,OLED_CMD);//-not offset
       
        OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration
        OLED_WR_Byte(0x12,OLED_CMD);
       
        //时序指令
        OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
        OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
       
        OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period
        OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
       
       
        OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh
        OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level
       
        OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
        OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable
       
        //基础指令
        OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
        OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)
        OLED_Clear();
        OLED_WR_Byte(0xAF,OLED_CMD);

使用特权

评论回复
15
慢动作|  楼主 | 2023-9-25 19:21 | 只看该作者
OLED细节之显示帧频
详细参考:

该模块是一种片上低功耗RC振荡器电路。可以生成操作时钟(CLK)

从内部振荡器或外部源CL引脚。该选择由CLS引脚完成。如果CLS引脚

拉高,选择内部振荡器,CL应保持打开。将CLS引脚拉低禁用

内部振荡器和外部时钟必须连接到CL引脚才能正常工作。当内部

选择振荡器,其输出频率Fosc可通过命令D5h A[7:4]改变。

使用特权

评论回复
16
慢动作|  楼主 | 2023-9-25 19:22 | 只看该作者
显示定时发生器的显示时钟(DCLK)来自CLK。除法因子“D”

可通过命令D5h从1编程到16
DCLK = F OSC / D
显示的帧频由以下公式确定。
D代表时钟分频比。通过命令D5h A[3:0]设置。分割比的范围是1到16

•K是每行显示时钟的数量。该值由
K=相位1周期+相位2周期+BANK0脉冲宽度=2+2+50=54通电复位
(有关“阶段”的详细信息,请参阅第8.6节“段驱动程序/通用驱动程序”)

•多路复用比率的数量由命令A8h设置。上电复位值为63(即64MUX)。
•F OSC是振荡器频率。可通过命令D5h A[7:4]进行更改。寄存器越高
设置会导致更高的频率。

DCLK与Ffrm 不同,Ffrm比DCLK多除了个K和MUX(64)

使用特权

评论回复
17
慢动作|  楼主 | 2023-9-25 19:23 | 只看该作者
FR同步
FR同步信号可以用来防止撕裂效应。

使用特权

评论回复
18
慢动作|  楼主 | 2023-9-25 19:23 | 只看该作者
OLED的写入速度取决于MCU开始写入图像的速度。如果MCU可以
在一帧周期内完成一帧图像的写入,属于快速写入MCU。满足MCU需求
完成的写入时间较长(超过一个帧但在两个帧内),这是一个缓慢的写入。
对于快速写入MCU:MCU应在FR脉冲上升沿后开始写入新的ram数据帧
应在下一个FR脉冲上升沿之前完成。
对于慢写MCU:MCU应该在第一个FR的下降沿之后开始写入新的帧ram数据
必须在第3个FR脉冲上升沿之前完成。

使用特权

评论回复
19
慢动作|  楼主 | 2023-9-25 19:23 | 只看该作者
分析上述OLED初始化代码:
OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec

使用特权

评论回复
20
慢动作|  楼主 | 2023-9-25 19:23 | 只看该作者
帧频为100,显示一帧时间要0.01s
快速写入的话,IIC传输128x64位数据的时间<0.01s,则IIC的SCL的周期要小于1.22us
一般IIC的SCL的低脉冲时间是高脉冲时间的两倍,用delay()函数一般都是us,这样看用delay函数来控制周期不可行,必定会导致动态画面撕裂。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

67

主题

699

帖子

0

粉丝