[点屏记录]用ESP32驱动夏普LJ64H052 EL显示屏
本文主要记录了点亮一块EL显示屏的过程。
This post describes the process of trying to drive an EL display using ESP32.
I 背景
EL显示器,全称电致发光显示器(Electroluminescent display),可以看作现代OLED的前身。其结构与OLED也很类似,只是采用无机物而不是有机半导体在电场激发下发光。由于其体积小,工作温度范围和视觉效果都比当时的LCD更优秀,这类显示器常见于80-90年代较高要求的场合,如工业和医疗设备。常见的EL显示器发光颜色一般为黄色或琥珀色,也曾出现过红绿双色的型号,只不过非常罕见,价格很高。由于个人很喜欢EL显示器的颜色,它一直是我重点收集的显示器件之一。下面是本人收集的部分EL显示器,多数来自拆机因此价格很便宜(正经EL显示器价格通常很高)。这些显示器分辨率从160x80/320x240/640x400到640x480不等,尺寸跨度也很大。
My EL collection
EL显示器背面通常有非常复杂的电路,因为这些显示器工作在高压交流电下,需要用升压电路产生100-200V的高压,并由高压行列驱动芯片实现驱动和扫描。这也是该类型显示器价格昂贵的原因之一。
多数EL显示器模组采用5V和12V两组直流电压输入,其中5V用于逻辑电路,12V用于升压和驱动电路。同时,多数模组仅包含基本的刷新和驱动电路,并不具有显示缓存和更高级的控制器(上图右下角最小的模块除外,这个模块集成了SED1335显示控制器,集成了字库,用于高档服务器的状态显示)。不同型号的EL模组接口和时序有一定差别,但基本都包含数据时钟(Data clock),行同步(HSync),场同步(VSync)和数据输入。为了降低传输时钟频率,不少分辨率较高的显示屏会采用多路数据输入,在一个时钟周期输入多个像素。我手上的显示模组,数据宽度从1bit到2/4/8bit都有。
本文尝试点亮的是一块SHARP LJ64H052显示模组,来自捡破烂来得到的岛津X光机控制面板。显示器分辨率为640*480,显示面积10.4英寸,为我目前收藏中最大的一块。由于牵扯到电平转换/时序等问题,点亮过程稍微花了点脑筋。以下给出显示器拆解/点亮过程记录和效果演示。
II 拆解
整体外观
岛津的Logo
控制按钮
内部情况。此显示器内部没有显示控制器,仅有一块电平转换板,一个触摸屏控制器和一个按键板。用了好几根很粗的电缆连接至主机(电缆早被剪了)
按键板上居然有两个蜂鸣器,频率不一样,估计为了互相切换发出警报音。日本人还真是蛋疼233
拆开显示器,才发现触摸居然是红外的。这个东西原理也比较有意思,但本文暂不探讨
触摸传感器里面的电路板。顺带一提,传感器的黑色塑料外壳其实是能透过红外线,但无法透过可见光的材料,兼具了过滤环境光的作用
控制器
红外发射管(透明)和红外接收管(不透明)阵列
发射管驱动
显示器本体
显示器反面,可以看到主控板和两块巨大的FPC
型号丝印
显示控制器LZ95N37,基本在打酱油,只能控制一下刷新,甚至自检功能都不带(多数模组可用跳线进入自检模式,会在没有外部输入的情况下自行点亮并产生一些测试图案)
升压电路,采用了超薄变压器
显示屏与外部连接的唯一接口,2.0mm 2x10P排针,供电和信号都在上面
巨大的FPC,行驱动芯片在反面。在设计显示屏时,工程师把显示屏和排线设计成中心对称,因此安装控制板的时候即使转180度也能正常工作
III 驱动
这次,我采用了ESP32进行显示屏驱动。因为ESP32自带的I2S模块可以配置为并行LCD输出,可以很方便地驱动多数扫描式显示器,并且自动刷新,完全不需要软件参与。ESP32的I2S可以支持最多24个并行输出,但通道数必须是8的倍数(虽然不是所有通道都要输出到引脚上),且同步信号也必须占用数据位。
本次驱动的SHARP LJ64H052为8位并行输入,除此之外还有行场同步两个信号,因此一个数据周期可输出8个像素,但需要占用ESP32中16bit即2字节的DMA存储空间。存储一帧画面,不算消隐区域,总计需要640*480/8*2=75KiB的内存,若需要实现双缓存则需要150KiB存储。ESP32的数据内存共计328K,因此还是绰绰有余的。但不足之处在于,内存的利用率其实只有一半,因为我们为了存储同步信号,每8个像素就浪费掉了一字节的数据。
ESP32-idf中,采用DMA描述结构体(lldesc_t)实现DMA的数据传输。每个lldesc_t实例包含了存放数据包的内存区域起始地址,该区域的长度等属性,并保存了下一个lldesc_t实例的地址。因此可以将多个描述串联成链表,实现多个数据包大数据量的传输。当需要发送数据时,在事先配置好其他寄存器的前提下,将该lldesc_t实例传递至相应外设,即可开始传输。外设会自动传输数据并根据发送长度和下一个描述符的地址,自动切换到下一个数据块。如果将最后一个lldesc_t实例中的下一个描述符地址设置成链表第一个描述符的地址,则整个链表会变成一个循环队列链表,外设会在没有CPU干预的情况下自动重复发送数据。通过这种方式,即可配置I2S实现显示屏的自动刷新。
在大体看完数据手册后,我很快使用ESP32的I2S给了显示屏一个基本的同步信号,并把数据脚全部拉高,不出意外显示屏被点亮了。这时候可以清楚地看到长期工作留下的烧屏痕迹。EL的烧屏现象很严重,固定图案点亮一会就会留下暂时的痕迹。
随后我尝试给一些棋盘格之类的数据,但显示一直不正常。我这时候才意识到这块显示屏对输入电平的要求较高,ESP32的3.3V电平是不足以稳定驱动的。翻箱倒柜找到两颗陈年的直插封装74HC244做了个电平转换,这下终于有正常点的画面了。
不过,还是能明显看到,显示棋盘格的时候,部分显示区域存在不正常现象。这是咋回事呢~
又一次阅读数据手册,手册是日文的,本人很菜,只看得懂里面的汉字,因此比较费劲。相比于其他显示器,本次驱动的夏普显示器比较特殊(也可称之为奇葩)。它的数据手册里用CP2表示数据时钟,CP1表示行同步(HSync),S表示场同步(VSync)。显示器的整个显示周期中不包含任何行消隐和场消隐周期,一个显示周期的数据时钟数量需要严格控制为640*240/4=38400。若需要实现消隐,则需要在刷完一行的最后一个像素后停掉数据时钟。另外,行同步的脉冲宽度也有非常严格的要求(下图中红色框的区域),哪怕差一点也会导致显示不正常。最后,这个显示器的刷新是上下两半同时进行的,因此一个时钟周期输入的数据,分别代表了上半部分(0-239行)和下半部分(240-479)行中一行内的4个像素点。大概这样设计也是为了提升刷新率吧。
顺便一提,这个手册写得也很有日企风味,下面的变更记录表很有特色,而且前前后后改了整整9年
言归正传。ESP32的I2S一旦开始传输,其时钟输出就无法停止,因此很难实现手册中的时序,除非采用发送完成中断和软件控制GPIO的方式。然而事实上,这个问题并不是无解的。根据数据手册,时序图红框中的tr并没有最小限制,但ts13却有最小限制。因此我们只要在任意时间拉高CP1,并想办法在一行数据的最后一个时钟周期内,下一行第一个时钟上升沿来临之前100ns把CP1拉低即可满足时序。由于达到60Hz刷新率所需的时钟频率约为640*480*60/8=2.304MHz,单个时钟周期为434ns,远大于100ns,可以用一个简单的RC电路,控制I2S输出的CP1的脉冲宽度,使其满足时序要求。
通过试验,我在ESP32的CP1输出和电平转换器之间串联一个10nF电容和100R电阻构成的高通滤波器,将数据时钟设为3.33MHz,并在一行中最后一个数据时钟周期把CP1拉高一个周期。通过RC电路和电平转换器输出的CP1实际高电平宽度约为145ns,与下一行第一个时钟上升沿的距离为1000/3.33-145ns=155ns,大于100ns,满足时序要求。实际情况也表明显示问题得到了修复,棋盘格画面正常。
迫不及待加载了一张EVA的界面进去,内味就有了。
值得一提的是,EL显示器在发光时,点亮像素周围的像素也会因为电场耦合产生微微的辉光,有一种类似辉光管的朦胧美,非常漂亮。这也是LCD和OLED很难模拟出的特色吧。
把这一堆破烂塞回原先的外壳中,一个NERV专属控制终端便诞生了(虽然没有任何实际功能
再附一段视频,是采用SPIFFS存储连续图像,实现动态显示的效果
关于代码方面,以下是几点说明:
- 本人水平较菜,代码参考了一些例程,仅为点亮,因此比较乱,不作任何可用性的保证。如果对您有用那就太好了。
- 原先希望写一个通用的EL驱动框架,但发现不同显示器的时序差异还是挺大,最后就放弃了。用在其他显示模组时需要按照实际情况更改I2S输出口映射/I2S位宽/buffer数据写入格式等
- ESP32为32位单片机,但I2S的DMA数据单位为字节,因此DMA输出时会存在大小端匹配问题。程序中采用conv_addr(),在写数据进buffer之前进行顺序转换,纠正显示错误
- I2S的fifo_conf.tx_fifo_mode和conf_chan.tx_chan_mode至关重要,配不好则数据输出顺序和内容都不对
- 程序中实现了多个显示缓存的逻辑,但实际测试最多实现双缓存显示,三个的话可能因为可用的DMA内存不够,会导致崩溃。目前还没找到原因。
- EL显示器的余辉非常长,因此在双缓存模式下将两个缓存连成循环队列,分别给不同像素值,则可以实现灰度显示。基本看不出闪烁,效果较好。
IV 后续
- Bad Apple安排上
- 添加图形库
- 计划用这块屏改装一个串口/Telnet/SSH终端,而且必须要有DEC VT320那样的平滑滚动~
附录:
Sharp LJ64H052数据手册(日文)
测试代码(包含点亮和SPIFFS读取图片序列,使用WROOM32模块,ESP-IDF v4.2-dev-1995-g636b964c8)