0.96OLED显示原理及FPGA驱动程序

这篇具有很好参考价值的文章主要介绍了0.96OLED显示原理及FPGA驱动程序。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


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

1 OLED模块介绍

1.1 模块

OLED:organic/polymer light emitting diode 高分子有机电激发光二极管
OLED模块原理图:
0.96OLED显示原理及FPGA驱动程序

OLED模块结构图:
0.96OLED显示原理及FPGA驱动程序

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

以驱动芯片为SSD1306的屏为例:
OLED 显示屏裸屏外观:
0.96OLED显示原理及FPGA驱动程序

驱动芯片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个控制引脚组成。不同接口模式下的引脚分配如下表所示。
0.96OLED显示原理及FPGA驱动程序

1.3 SSD1306接口配置

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

I2C写数据与命令的时序:
0.96OLED显示原理及FPGA驱动程序

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

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

关于配置空间,注意:

  1. 显存地址与数据排列
    0.96OLED显示原理及FPGA驱动程序
    0.96OLED显示原理及FPGA驱动程序
    将整个显示像素点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 panel
    7'd1 :O_i2c_data <= {8'h00,8'h00};//---set low column address
    7'd2 :O_i2c_data <= {8'h00,8'h10};//---set high column address
    7'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 register
    7'd5 :O_i2c_data <= {8'h00,8'hCF};// Set SEG Output Current Brightness
    7'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 display
    7'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 duty
    7'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 offset
    7'd13:O_i2c_data <= {8'h00,8'hD5};//--set display clock divide ratio/oscillator frequency
    7'd14:O_i2c_data <= {8'h00,8'h80};//--set divide ratio, Set Clock as 100 Frames/Sec
    7'd15:O_i2c_data <= {8'h00,8'hD9};//--set pre-charge period
    7'd16:O_i2c_data <= {8'h00,8'hF1};//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
    7'd17:O_i2c_data <= {8'h00,8'hDA};//--set com pins hardware configuration
    7'd18:O_i2c_data <= {8'h00,8'h12};//
    7'd19:O_i2c_data <= {8'h00,8'hDB};//--set vcomh
    7'd20:O_i2c_data <= {8'h00,8'h40};//Set VCOM Deselect Level
    7'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/disable
    7'd24:O_i2c_data <= {8'h00,8'h14};//--set(0x10) disable
    7'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 0
    11'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 1
    11'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 2
    11'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 3
    11'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 4
    11'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 5
    11'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 6
    11'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 7
    default : O_i2c_data <= R_i2c_data; //binary data
    endcase

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

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

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

完整代码见附件。

3 一个简单的应用

0.96OLED显示原理及FPGA驱动程序

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

import serial
import time
import pyautogui
import cv2
# import matplotlib.pyplot as plt
import numpy as np 
import threading

serialPort = "COM3"
baudRate = 921600
timeout1 = 0.5
frame_cnt = 0

try:
    ser = serial.Serial(serialPort, baudRate, timeout=timeout1)
except:
    print("串口打开失败!")
else:
    print("参数设置:串口=%s ,波特率=%d" % (serialPort, baudRate))

def fun_refresh(): 
    global frame_cnt
    print("frame_cnt:%d" % frame_cnt)
    frame_cnt = frame_cnt + 1
    img = pyautogui.screenshot()    # x,y,w,h
    img_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 timer
    timer = 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驱动。

效果:
0.96OLED显示原理及FPGA驱动程序文章来源地址https://www.toymoban.com/news/detail-444242.html

附件

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

到了这里,关于0.96OLED显示原理及FPGA驱动程序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • OLED 液晶屏显示模块(0.96寸)

           OLED,即有机发光二极管(Organic Light-Emitting Diode),又称为有机电激光显示(Organic Electroluminesence Display, OELD)。因为具备轻薄、省电等特性,因此从 2003 年开始,这种显示设备在 MP3 播放器上得到了广泛应用,而对于同属数码类产品的 DC与手机,此前只是在一些展会上

    2024年02月05日
    浏览(27)
  • 【mcuclub】0.96寸oled显示屏

     proteus8.9版本中没有OLED,通常用LCD12864模拟代替,而proteus8.13中有OLED,大家有兴趣可以下载测试 OLED(Organic Light-Emitting Diode),又称为有机电激光显示、有机发光半导体。OLED显示技术具有自发光的特性,采用非常薄的有机材料涂层和玻璃基板,当有电流通过时,这些有机材料

    2024年03月28日
    浏览(23)
  • 0.96寸OLED显示(7针款SPI)

    文章最后附源代码链接 SSD1306单片机接口由8个数据引脚和5个控制引脚组成。不同接口模式下的引脚分配如表所示。在BS[2:0]引脚上通过硬件选择可设置不同的MCU模式。 通常我们所用的OLED屏有白色、蓝色、黄蓝双色等几种;屏的大小为0.96寸,像素点为128*64,所以我们也称之为

    2024年02月01日
    浏览(22)
  • 0.96寸OLED显示汉字图片及简单GIF

    只是做一些简单显示,具体逻辑大家自行添加。 网上的OLED驱动很多,我懂的也不是很深,这里就不说了,我这里用的是中景园的驱动。这里重点说怎么改可以显示这些东西。 首先我们需要两个重要的东西,一个是字取模软件,另一个是图片的处理取模软件。感谢大佬。 首先

    2024年02月01日
    浏览(27)
  • 中景园0.96寸 OLED 显示屏 学习笔记

    OLED ,即 有机 发光二极管( Organic Light Emitting Diode )。OLED由于同时具备 自发光,不需背光源、对比度高、厚度薄 、视角广、反应速度快、可用于挠曲性面板、使用温度范围广、构造及制程较简单等优异之特性,被认为是下一代的平面显示器新兴应用技术。 LCD都需要背光,而

    2023年04月08日
    浏览(13)
  • stm32实现0.96oled图片显示,菜单功能

    本期内容,我们将学习0.96寸oled的进阶使用,展示图片,实现菜单切换等功能,关于oled的基础内容,这里我不做介绍,大家可以学习 : 夜深人静学32系列17——OLED ,里面讲述了oled的基本知识并实现了一个简单页面的编写。 这个菜单一共有三个等级, 一级菜单:原神启动界

    2024年02月03日
    浏览(52)
  • 【STM32+HAL库】---- 硬件IIC驱动0.96OLED

    代码借鉴学习于以下文章: STM32 使用硬件IIC驱动0.96寸4针IOLED显示器(HAL库) 略... 点击查看代码 首先在 main.c 中引入头文件 随即根据要求在 main函数 中添加对应功能函数即可 【 注意 】使用时应将编译器编码选项选择为 GBK系列 ,否则编译报错,尤其注意通过keil修改后,再

    2024年02月19日
    浏览(17)
  • STM32使用IIC协议驱动0.96寸OLED屏

    IIC是常用的协议之一,它通过不同的地址来区分设备,并且端口需要是开漏模式,并且需要接上拉电阻  要使用IIC驱动OLED,首先要配置IIC 然后编写写入函数 ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT) 为判断事件的函数 有以下多种事件 OLED初始化 上图分别为 (起始位

    2024年02月03日
    浏览(19)
  • 0.96寸OLED12864屏幕控制(原理+代码)

     末尾附cubemx文件与keil文件。 SPI/IIC 接口模块 模块接口定义: 1. GND 电源地 2. VCC 电源正(3~ 5.5V ) 3. D0           OLED 的 D0 脚,在 SPI 和 IIC 通信中为时钟管脚 4. D1           OLED 的 D1 脚,在 SPI 和 IIC 通信中为数据管脚 5. RES        OLED 的 RES# 脚,用来复位(低电平

    2024年02月05日
    浏览(13)
  • STM32配合CubeMX硬件SPI驱动0.96寸OLED

    目录 一、简单介绍 1.1 OLED 1.2 SPI协议 接口 优点 缺点 数据传输 二、实战 2.1 工程配置 2.2 测试工程 2.3 波形分析 三、驱动OLED 3.1 初始化代码 3.2 清屏函数 3.3 设置坐标函数 3.4 显示字符函数 3.5 显示字符串函数 3.6 显示图片函数 附录 驱动代码文件 oled.c oled.h f6x8.h 1.1 OLED 有机发

    2024年02月02日
    浏览(16)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包