ESP32 RTOS I2C driver for OLED SH1106-LESSON2-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 12802|回复: 2

ESP32 RTOS I2C driver for OLED SH1106-LESSON2

[复制链接]
发表于 2017-2-20 21:36 | 显示全部楼层 |阅读模式
本帖最后由 vincen20 于 2017-2-20 21:40 编辑

ESP-IDF ESP32  RTOS  I2C  driver  for OLED SH1106
显示屏在开发中越来越重要,在开发中LCD,OLED,等显示屏的使用越来越多,最近在购买了一块1.3寸I2C接口的OLED显示屏。本以为可以使用现成的库文件,结果需要做大量修改,于是决定自己编写一个简单sh1106的驱动。
通信协议I2C,在此不再解释,网上有大量的资料可以参考。
本次使用的是esp32idf 2.0版本的开发环境,只里面已有关于I2C的驱动例子,为了使用方便的程序,
首先硬件准备
ESP32 (需要焊接好底板)、1.3 寸SH1106 OLED 显示屏(I2C接口)、USBTTL、3.3v DC电源。
软件环境
安装有ESP-IDF的系统(本次使用的是虚拟机 ubuntu server 16.04LTS-64位)、minicom串口调试工具、代码编写软件,可以参考ESP-IDF编译环境搭建的文档
资料准备
SH1106操作手册

SH1106 I2C
确定设备地址
IMG_2683.JPG
根据手册知(PAGE 13,Protocol),设备有2个预先固化在芯片内的7位地址(0111   100 and 0111    101)所以,一个芯片上的相同2个GPIO口可以同时接2个SH1106显示屏。
图片1.png
可以参考图片 最后一位SA0是由引脚确定的,如果引脚接高电平地址就是0x7A,如果接第电平,在该芯片中高低电平具体是多少伏可以参考PAGE 36 ,DC characteristics。在购买的芯片上也有提示地址是0x78,SA0接的是低电平或者悬空。

写规则
图片2.png
图片说明(S: 开始信号 A:应答信号 P:停止信号SA0:地址线DC:控制字节位from ‘s’:有从机发出信号)
由于OLED设备是显示屏幕,大多数的操作都是往显示屏中写入数据,这里就使用写命令为例子。
根据I2C规则,在操作之前都需要向从机(从机,被寻址的设备。主机开始I2C以产生时钟信号的设备)发出地址请求。然后等待从机响应应答信号(图片中的A),然后开始发送控制字节、等待从机应答,发送下一个字节,等待应答。。。。最后发送停止信号结束传输。
为了方便程序编写,每次我们只传输一条命令,因此流程为
主机发出开始信号发送从机地址|(读写位)-》控制字节-》数据-》停止信号
在每一个》后需要等待从机的应答信号
SH1106中,在地址位后的第8位是读写标示,0为写,1为读取数据,所以我们直接发送078就代表了2层含义,1是地址是0x78且SA0没有连接,2是对芯片是写操作。
控制字节的编码为
图片3.png
C0=0,最后一个控制位。C0=1下2个字节是数据和一个控制字节。由于本次采用的是每次只发送一个数据命令,所以这里的C0取0
DC=0,表示传输的是命令操作。DC=1表示传输的显示数据。所以就有这些的命令
如果传输的是命令控制字节就是0x00,如果传输的是显示的数据控制字节就是0x40。
显示屏命令,参考说明
准备字库,可以从网上下载现成的字符,也可以自行定义图像等
在显示启动时需要初始化一些命令,可参考文档。
IMG_2682.JPG
ESP-IDF I2C.H文件
大多数网上都是自行模拟的I2C协议,这里使用的是官方提供的库文件,下面介绍几个用到的函数。
使用前需要升级ESP-IDF到2.0版本,并添加包含文件 #include “driver/i2c.h”.
//写入命令
i2c_master_start(i2c_cmd_handle_t);//
i2c_master_write_byte(i2c_cmd_handle_t,0x78,ACK_EN);//发送从机地址,并等待从机响应
i2c_master_write_byte(i2c_cmd_handle_t,0x00,ACK_EN);//发送控制字节,并等待从机响应
i2c_master_write_byte(i2c_cmd_handle_t,CMDS,ACK_EN);//发送指令,并等待从机响应
I2c_master_stop((i2c_cmd_handle_t);//
//向OLED RAM 写入数据
i2c_master_start(i2c_cmd_handle_t);//
i2c_master_write_byte(i2c_cmd_handle_t,0x78,ACK_EN);//发送从机地址,并等待从机响应
i2c_master_write_byte(i2c_cmd_handle_t,0x40,ACK_EN);//发送控制字节,并等待从机响应
i2c_master_write_byte(i2c_cmd_handle_t,Datas,ACK_EN);//发送数据,并等待从机响应
I2c_master_stop((i2c_cmd_handle_t);//

解决完发送命令后,需要考虑的是向显示屏发送显示数据,这里ASCII编码表为列子,原理是这样的,首先通过其他方式按照ASCII编码表顺序生产字库文件,可以是通过其他程序生产,也可以下载,下载的需要检查是否满足屏幕显示要求,在编程时候将字符转换为ASCII编码,然后根据ASCII的顺序可以读取到指定字符的显示数据。最后我们只需要把组成这些字符的字节发送出去就可以,有时候需要把高低为进行颠倒。
图片4.png
在进行完屏幕初始化,设置开始坐标后(初始化流程请参考SH1106文档)
例如,要显示字符S,我们只需要向显示屏发送 0x76,0x98,0x98,0x98,0x98,0x27,但是需要将高低位进行交换,实际需要发送0x67,0x890x89,0x89,0x72.然后可以进行程序烧写,看屏幕上是否显示有S字符。字符显示后就可以显示字符串,以及一些自定义的图像。
下载文档
SH1106_V2.3.pdf (736.37 KB, 下载次数: 43)
参考代码
其他参考
IMG_2685.JPG
发表于 2020-3-17 13:51 | 显示全部楼层
mark一下,方便学习
发表于 2020-11-3 09:27 | 显示全部楼层
楼主你好:sh1106驱动的1.3寸 spi 7脚oled有库文件吗??怎么驱动
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 04:39 , Processed in 0.279471 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表