目录

  • 1 OLED模块介绍
    • 1.1 模块
    • 1.2 SSD1306简介
    • 1.2 SSD1306引脚
    • 1.3 SSD1306接口配置
  • 2 驱动(oled_ctrl.v)
  • 3 一个简单的应用
  • 附件

很久以前玩的OLED,现在整理一下。

1 OLED模块介绍

1.1 模块

OLED:organic/polymer light emitting diode 高分子有机电激发光二极管
OLED模块原理图:

OLED模块结构图:

市面上统一尺寸的配置和设计大差不差的,OLED生产商大部分都是中景园电子,官网可以下载OLED 显示屏裸屏的资料。

以驱动芯片为SSD1306的屏为例:
OLED 显示屏裸屏外观:

驱动芯片SSD1306尺寸很小,6.76*0.86mm。仔细看在液晶屏下面一点点可以看到一个长条就是了。

1.2 SSD1306简介

SSD1306是一款带控制器的单片CMOS OLED/PLED驱动,用于OLED点阵图形显示系统。它由128个segment和64个common组成。该集成电路是为普通阴极型OLED面板设计的。

SSD1306内置了对比度控制、显示RAM和振荡器,减少了外部组件的数量和功耗。它有256级亮度控制。数据/命令从通用MCU通过硬件可选的6800/8000串行兼容并行接口,I2C接口或串行外设接口发送。它适用于许多小型便携式应用,如手机子显示器、MP3播放器和计算器等。

1.2 SSD1306引脚

SSD1306单片机接口由8个数据引脚和5个控制引脚组成。不同接口模式下的引脚分配如下表所示。

1.3 SSD1306接口配置

不同的MCU模式可以通过BS[2:0]引脚上的硬件选择来设置。根据原理图可知这款的BS[2:0]=3’b010。设置为I2C驱动。

I2C写数据与命令的时序:

contorl byte: 8’h40(数据),8’h00(指令)
关于I2C时序,这里注意几个关键参数就行,其他的都是标准接口:

  • I2C时钟周期最小为2.5us,即400KHz。
  • 刷新率:
    取I2C时钟频率fI2Cf_{I^2C}fI2C​=350KHz。I2C驱动模块系统时钟为4倍I2C时钟频率fsysf_{sys}fsys​=1.4MHz。
    从触发一次写到写完成大概需要130个系统时钟。
    完成一次刷新需要1048次I2C写,其中1024个数据以及24个指令。
    所以刷新率为:
    frefresh=fsys/130/1048≈10.276Hzf_{refresh} = f_{sys} / 130 / 1048 \approx 10.276Hzfrefresh​=fsys​/130/1048≈10.276Hz

关于配置空间,注意:

  1. 显存地址与数据排列


    将整个显示像素点128*64分为8行,127列的8bit数据,数据的低位对应低坐标点。
  2. 设置页寻址模式的下列起始地址(00h~0Fh)
  3. 设置页面寻址模式的高列起始地址(10h~1Fh)
  4. 设置页面寻址方式的页面起始地址(B0h~B7h)

2 驱动(oled_ctrl.v)

初始化主要指令:

case (R_init_cmd_cnt)7'd0 :O_i2c_data <= {8'h00,8'hAE};//--turn off oled panel7'd1 :O_i2c_data <= {8'h00,8'h00};//---set low column address7'd2 :O_i2c_data <= {8'h00,8'h10};//---set high column address7'd3 :O_i2c_data <= {8'h00,8'h40};//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)7'd4 :O_i2c_data <= {8'h00,8'h81};//--set contrast control register7'd5 :O_i2c_data <= {8'h00,8'hCF};// Set SEG Output Current Brightness7'd6 :O_i2c_data <= {8'h00,8'hA1};//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常7'd7 :O_i2c_data <= {8'h00,8'hC8};//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常7'd8 :O_i2c_data <= {8'h00,8'hA6};//--set normal display7'd9 :O_i2c_data <= {8'h00,8'hA8};//--set multiplex ratio(1 to 64)7'd10:O_i2c_data <= {8'h00,8'h3F};//--1/64 duty7'd11:O_i2c_data <= {8'h00,8'hD3};//-set display offset   Shift Mapping RAM Counter (0x00~0x3F)7'd12:O_i2c_data <= {8'h00,8'h00};//-not offset7'd13:O_i2c_data <= {8'h00,8'hD5};//--set display clock divide ratio/oscillator frequency7'd14:O_i2c_data <= {8'h00,8'h80};//--set divide ratio, Set Clock as 100 Frames/Sec7'd15:O_i2c_data <= {8'h00,8'hD9};//--set pre-charge period7'd16:O_i2c_data <= {8'h00,8'hF1};//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock7'd17:O_i2c_data <= {8'h00,8'hDA};//--set com pins hardware configuration7'd18:O_i2c_data <= {8'h00,8'h12};//7'd19:O_i2c_data <= {8'h00,8'hDB};//--set vcomh7'd20:O_i2c_data <= {8'h00,8'h40};//Set VCOM Deselect Level7'd21:O_i2c_data <= {8'h00,8'h20};//-Set Page Addressing Mode (0x00/0x01/0x02)7'd22:O_i2c_data <= {8'h00,8'h02};//7'd23:O_i2c_data <= {8'h00,8'h8D};//--set Charge Pump enable/disable7'd24:O_i2c_data <= {8'h00,8'h14};//--set(0x10) disable7'd25:O_i2c_data <= {8'h00,8'hA4};// Disable Entire Display On (0xa4/0xa5)7'd26:O_i2c_data <= {8'h00,8'hA6};// Disable Inverse Display On (0xa6/a7) 7'd27:O_i2c_data <= {8'h00,8'hAF};default : /* default */;
endcase

数据刷新:

case (R_data_cnt)11'd0:O_i2c_data <= {8'h00,8'hB0};11'd1:O_i2c_data <= {8'h00,8'h00}; 11'd2:O_i2c_data <= {8'h00,8'h10};// page 011'd131:O_i2c_data <= {8'h00,8'hB1};11'd132:O_i2c_data <= {8'h00,8'h00}; 11'd133:O_i2c_data <= {8'h00,8'h10};// page 111'd262:O_i2c_data <= {8'h00,8'hB2};11'd263:O_i2c_data <= {8'h00,8'h00}; 11'd264:O_i2c_data <= {8'h00,8'h10};// page 211'd393:O_i2c_data <= {8'h00,8'hB3};11'd394:O_i2c_data <= {8'h00,8'h00}; 11'd395:O_i2c_data <= {8'h00,8'h10};// page 311'd524:O_i2c_data <= {8'h00,8'hB4};11'd525:O_i2c_data <= {8'h00,8'h00}; 11'd526:O_i2c_data <= {8'h00,8'h10};// page 411'd655:O_i2c_data <= {8'h00,8'hB5};11'd656:O_i2c_data <= {8'h00,8'h00}; 11'd657:O_i2c_data <= {8'h00,8'h10};// page 511'd786:O_i2c_data <= {8'h00,8'hB6};11'd787:O_i2c_data <= {8'h00,8'h00}; 11'd789:O_i2c_data <= {8'h00,8'h10};// page 611'd917:O_i2c_data <= {8'h00,8'hB7};11'd918:O_i2c_data <= {8'h00,8'h00}; 11'd919:O_i2c_data <= {8'h00,8'h10};// page 7default : O_i2c_data <= R_i2c_data; //binary dataendcase

刷新的过程。设置好page的地址,然后从第一列开始写128个数据到显存,完成这个page的刷新。

  • 首先B0B7:设置GDDRAM页面起始地址(PAGE0PAGE7)用于使用X[2:0]的页面寻址模式。
  • 8’h00:设置页面寻址模式的列起始地址的低四位为4’b0000
  • 8’h10:设置页面寻址模式的列起始地址的高四位为4’b0000

关于I2C的读写,采用的是正点原子写的I2C读写模块,正点原子针不戳。

完整代码见附件。

3 一个简单的应用

上位机使用Python实现,代码:

import serial
import time
import pyautogui
import cv2
# import matplotlib.pyplot as plt
import numpy as np
import threadingserialPort = "COM3"
baudRate = 921600
timeout1 = 0.5
frame_cnt = 0try:ser = serial.Serial(serialPort, baudRate, timeout=timeout1)
except:print("串口打开失败!")
else:print("参数设置:串口=%s ,波特率=%d" % (serialPort, baudRate))def fun_refresh(): global frame_cntprint("frame_cnt:%d" % frame_cnt)frame_cnt = frame_cnt + 1img = pyautogui.screenshot()    # x,y,w,himg_128x64 = np.asarray(img)[0:1024:16, 0:1920:15, :]# cv2.imshow(img_128x64)gray = cv2.cvtColor(np.asarray(img_128x64), cv2.COLOR_RGB2GRAY)ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU)head_hex_str = bytes.fromhex('55 55 55')ser.write(head_hex_str)for i in range(0, 8):for j in range(0, 128):a = np.array(binary[i * 8:(i + 1) * 8, j] / 255).astype(int)c = a[::-1]Bi_conver_op = 2 ** np.arange(a.shape[0])  # shape=[1,6]b = c.dot(Bi_conver_op[::-1].T)string = str(hex(b))if len(string) == 3:string1 = '0' + string[2]else:string1 = string[2] + string[3]ser.write(bytes.fromhex(string1))t = time.time()print("time(ms): %d" % int(round(t * 1000)))global timertimer = threading.Timer(0.1, fun_refresh)timer.start()timer = threading.Timer(1, fun_refresh)
timer.start()time.sleep(600)
timer.cancel()
ser.close()

上位机功能:每隔0.1s截取屏幕1920*1080p,并转换成128*64p,并使用opencv完成灰度转化以及二值化处理,最后通过串口发送数据。帧头为0x55_55_55。

oled_display:缓存数据帧并对数据帧采用乒乓处理。

oled_ctrl:初始化OLED并完成OLED的刷新,刷新时输出每个page数据的地址,从oled_display获得要显示的数据。

i2c_dri:I2C驱动。

效果:

附件

  • 工程:
    链接:https://pan.baidu.com/s/1jRdPJOrJ0g3FqO9D6fZyPg
    提取码:open
  • 资料:
    链接:https://pan.baidu.com/s/1QmSNjwLDqDJCRPrtUOtIYA
    提取码:open

0.96OLED显示原理及FPGA驱动程序相关推荐

  1. 基于STM32CubeMX的stm32f103c6t6液晶0.96OLED显示字母数字汉字图片显示

    在STM32CubeMX里建工程,利用HAL库stm32F103c6t6连0.96寸的OLED液晶显示数字字母汉字图片.stm32f103c8t6,stm32f103zet6系列都可以参考下面的即可成 ...

  2. 基于STM32的0.96OLED基本显示学习,及 上下或左右的滑动显示长字符(使用硬件刷屏模式),OLED显示变量值操作详细解析

    基于STM32的0.96OLED基本显示学习,及 上下或左右的滑动显示长字符(使用硬件刷屏模式),OLED显示变量值操作详细解析 简   介 一.项目说明 二.学习入门 1)开始了解例程 三.实战过程 ...

  3. 项目3—数码管0~9999显示(包含数码管原理)

    数码管原理: 数码管按段数可分为七段数码管和八段数码管,八段数码管比七段数码管多一个发光二极管单元(多一个小数点显示):按能显示多少个"8"可分为1位.2位.3位.4位.5位.6位 ...

  4. stm32f103程序——0.96OLED(修改显示汉字函数)

    网盘链接:https://pan.baidu.com/s/1ov-lE3sD2nMpV33Q9E7omw 提取码:2333 一.写作说明 1.1 前言 备注:本文所使用的液晶屏为0.96OLED IP ...

  5. Arduino控制超声波检测与0.96OLED及串口显示

    Arduino控制超声波检测与0.96OLED及串口显示代码使用库共享(包括超声波检测与U8glib): 使用元件: 0.96寸 12864 I2C OLED 128x64规格 超声波检测模块 湿度模 ...

  6. ESP8266+0.96OLED驱动显示(I2C)

    文章目录 ESP8266 一.简介 二.管脚定义 三.代码 ESP8266 一.简介 这篇我们说一下ESP8266来驱动OLED显示屏显示,这里使用的是I2C的屏幕,像Arduino中有好几个库可以驱 ...

  7. 基于stc15f104w的软件iic显示0.96oled

    头一回用CSDN写文章诶~ iic启动部分和停止部分 写入数据部分 写入字节部分 写入命令和数据 Oled写入命令/数据 填充图像数据 设置光标 Oled初始化 iic启动部分和停止部分 void i ...

  8. Android10.0 Binder通信原理(一)Binder、HwBinder、VndBinder概要

    摘要:本节主要来讲解Android10.0 Binder.HwBinder.VndBinder的关联与各自作用 阅读本文大约需要花费10分钟. 文章首发微信公众号:IngresGe 专注于Androi ...

  9. 【边学边记_12】——VGA原理与FPGA实现

    VGA原理与FPGA实现 推荐参考小梅哥视频学习 使用FPGA驱动VGA不适合用来显示复杂多变的图像内容,但是却常用于显示实时图像内容,例如显示图像传感器实时采集到的图像.此种方式数据流由图像传感器实 ...

  10. 【STM32CubeMX】教程二_IIC驱动0.96oled屏幕(SSD1306)

    [STM32CubeMX]教程二_IIC驱动0.96oled屏幕(SSD1306) 文章目录 [STM32CubeMX]教程二_IIC驱动0.96oled屏幕(SSD1306) 前言 一.IIC通讯 ...

最新文章

  1. JAVA 子父类的特点
  2. 2020-12-29 Matlab自动化控制-Adrc自抗扰控制参数调节
  3. python中frame用法_python操作dataFrame基本知识点
  4. Python练习 | Python 可迭代对象 迭代器
  5. c++代码转为go_Go调用C/C++
  6. CF827F-Dirty Arkady‘s Kitchen【堆】
  7. ant中的table行列不对齐问题,以及换行,隐藏等问题
  8. 看完后,搞懂ARP的工作原理,其实并不难(好文)
  9. GDB+coredump定位段错误
  10. 蓝牙耳机播放音频无声问题的解决方案
  11. 超快激光啁啾放大技术的原理及应用
  12. 开发中使用第三方工具/服务
  13. 7层计算机网络体系结构,【计算机网络7层体系结构】
  14. STM32几种流行开发环境的优缺点
  15. python改变图片透明度_Python PIL.Image之修改图片背景为透明
  16. windows服务器硬盘怎么扩容,windows2016 扩容硬盘
  17. 脑科学发展到今天,距离记忆编辑提取还有多远
  18. 解决win10每次重启后桌面图标排列混乱的问题。
  19. Xilinx AXI Crossbar相关调试记录
  20. 阿拉丁年会 - 小程序开发者年度盛会 报告内容摘要

热门文章

  1. 弘辽科技:复购率太低怎么办呢?
  2. 新唐N76E003与ST公司STM8S003F3芯片对比 史上最全的没有之一
  3. 给mBlock添加扩展模块
  4. 2019 年(B题)巡线机器人
  5. IDEA插件系列(100):CPU Usage Indicator插件——显示CPU使用情况
  6. java基本数据类型
  7. Ubuntu 安装 OpenCV(亲测有效)
  8. UG工程图模板创建步骤
  9. 自制solidworks图框步骤_SolidWorks教你如何快速制作工程图模板
  10. 删除服务器远程桌面痕迹,清除3389连接后留下的日志,清除3389远程桌面连接记录...