数码之家

 找回密码
 立即注册
搜索
查看: 7330|回复: 23

[STM] 玩点不一样的!卡罗拉车机VFD屏实现灰度显示

[复制链接]
发表于 2020-9-20 17:57:14 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册

x
VFD显示屏玩了快10年了,数码之家也有了新站了。感慨~
自从大学第一次接触到这玩意就立刻爱上其效果,无奈兜里没钱,矿坛老陈VFD只收了10块左右(现在遇上先50块起),现已绝迹。还有一些可玩性不佳的字符型屏、二十几块数码管屏、零零散散的老旧则武25664、12864等等,质量普遍不高,都是有明显老化痕迹的旧玩意儿。VFD以难驱动著称,需要逻辑3.3-5V,灯丝交流浮地,阳极栅极正高压或负高压,所以在老一些的屏幕上(2010年以前)普遍采用单管或双管自激的变压器方案,对于自动控制出身的我而言,费劲研究变压器是十分不明智的举动,于是这类屏幕都直接购买模组。后来出现了DC-DC驱动器+倍压整流的邪道,省去了变压器,灯丝用BTL推挽或电桥的方案,可以简化供电设计,也是我在使用的方案之一。

随后就到了今天的主角:卡罗拉车机VFD。这是一款256*50的点阵,已经有不少朋友玩过,例如:
https://www.mydigit.cn/forum.php?mod=viewthread&tid=119776

https://www.mydigit.cn/forum.php?mod=viewthread&tid=81043


IMG_9342.JPG
车机前面板

IMG_9343.JPG
背后样式

IMG_9346.JPG
电路板正面


这款屏幕的特点有三:
首先是全新。256*50的图形点阵,但完全没有烧蚀痕迹,模组买到手的时候还有保护膜,可见品质非常好;
其次是低价。目前咸鱼30元就能买到,货源相对充足(直接入手40块,留着慢慢玩);
第三是先进。VFD玻璃屏的集成度按从低到高分为三类:栅极阳极直接引出的全外置驱动式,集成了高压移位寄存器和锁存器的半集成式,集成了完整的扫描控制器的全集成式。这块屏幕就是全集成式,用MCU和屏玻璃直接通信就好像在和以前的一个模组通信一样,方便至极。并且!该屏幕的灯丝是直流驱动!DIY玩家要跪谢双叶了。VFD驱动难,核心就在浮地的灯丝上,这家伙直接直流驱动,一了百了(后会附上示波器图)。

模组详细数据的链接都来自这位网友的帖子(在此感谢,大大减少了研究指令的时间):https://www.mydigit.cn/forum.php?mod=viewthread&tid=119776

一般而言接下来的事情就是写个代码往屏幕上写数据就行了,但是我想玩点不一样的东西,毕竟STM32 CM3和CM4的性能都很强大,只是推个SPI就显得十分牛刀杀鸡。u8g2虽然好用但毕竟是第三方的东西,享受不到自己搭建软件框架的乐趣,于是我决定在这个屏幕上,实现还没人玩过的灰度显示。
先上效果(肉眼看效果会比图上好很多,毕竟扫描周期和手机曝光时间有些接近):

IMG_9351.jpg
显示4级灰度条纹,从左往右对应灰度值1-4

对于LED这类器件,灰度显示的原理统统是PWM占空比控制,原因是占空比描述了一个周期方波信号的RMS值比例,通过合理控制正脉宽,就能实现调光的效果。
为了不用公式把事情搞复杂,这里引出两个概念即可:
PWM频率fPWM,和PWM分辨率N(N值代表一个PWM周期内最多可有的占空比数量)
PWM频率是PWM信号的基频,就是我们所说的帧率;而PWM分辨率则是指正脉宽宽度变化的最小单位。则我们可以看到,当给定一个PWM频率和PWM分辨率的时候,可以得到产生PWM所使用的计数器最低时钟频率 fclk=fPWM * (N-1)
反之,当fclk固定,给出fPWM,即可得到最大可能拥有的分辨率。

那这和实现灰度有什么关系呢?
前面提到过,卡罗拉车机这款屏幕是一款全集成屏,意味着我无法随意控制它的扫描方式和扫描频率,而为了肉眼看到的画面没有闪烁感,fPWM不可能太低,意味着N不可能太大。那么有没有办法知道这块屏幕的扫描频率呢?相似屏的手册中给出了答案:
VFD_INT.png

这块屏有一个INT输出引脚,一旦配置打开,它将输出当前激活的扫描单元的位置信息:是第一个单元就为有效,否则为无效。可见,记录这个引脚的频率,就可以获得整块显示屏的扫描频率。上700元收购的二手老旧示波器(我想买泰克的2.5Gsps四通,然而它要4W块):

IMG_9352.JPG
扫描频率是189Hz左右(上方的波形),这就是上文提到的fclk。

此时如果切出5级灰度,即N=5,那么fPWM就是fclk / (5 - 1) ≈ 45Hz,属于一个比较可接受的范围。灰度级再多,屏幕就会不可忽视地闪烁。

接下来就是设计软件部分了,板子采用2012年买的STM32F103VET,配一个盗版STlink,先用旧板子初步测试
底层负责将显示数据pour到VFD上,需要有强实时性,同时不能占用CPU。其逻辑如下:
1、准备显存。256*50按每列7个字节安排,一屏数据需要256*7=1792字节,非零的灰度等级有N-1=4级,因此需要1792*4=7168字节的RAM作为底层显存。这部分显存是为最底层的数据收发使用的,其layout完全是为了发送效率,不便于高层API读写操作,因此还需要一个高层所使用的通用显存,为每个点单独分配一个uint8_t,这部分需要256*50=12800字节;
2、我们在每一次第一个扫描单元被激活的时候启动整屏数据的传输,传输完毕之后等待下一个激活信号的到来。这个激活信号就是INT,使用GPIO外部中断触发;
3、每次进入外部中断以后,等待上次传输结束(其实根本不用等),然后更新下一次要发送的数据位置和数据长度,拉低片选NCS,发送写显示数据指令,等待指令解码(按GP1212手册需要等待360ns,实测不等待也可以),并启动DMA传输;
4、等待DMA传输完成中断,拉高NCS,结束一次数据发送。
*这块屏幕SPI时钟最高频率在4.2MHz左右,再高会传输失败,因此传送完整屏的数据大约需要3.2ms左右。可见如果只用CPU而不用DMA,STM32的CPU将有超过一半的时间都在负责数据外发(SPI传输使用等待方式),或者频繁响应SPI传输中断(SPI传输使用中断方式),使用效率将大打折扣。

中层负责将通用显存中的数据映射到底层的显存中,需要把每一个字节切片,然后按照一定的pattern分发到底层的显存中,这部分很难用硬件完成,需要占用CPU,好在编译器优化开到O3也是非常快的。

直接上代码片段:
  1. /** Split into subframes */
  2.         ppixel = vfd_px.pix;
  3.         for (ii = 0; ii < VFD_COL_CNT; ++ii)
  4.   {
  5.     for (jj = 0; jj < VFD_ROW_CNT; ++jj)
  6.     {
  7.       /** Edit below to change subframe layout */
  8.       idxf = jj & 1 ? (ii & 1) ^ 0x03 : (ii & 1);
  9.       pxbuf = *ppixel++;
  10.                         
  11.       for (i = 0; i < VFD_GRAYSCALE_CNT; ++i)
  12.       {
  13.         if (pxbuf)
  14.         {
  15.           vfd_frame.sframe[idxf].vmem[ii*VFD_BYTES_PER_COL + jj / 8] |= 1 << (jj % 8);
  16.           pxbuf--;
  17.         }
  18.         else
  19.           vfd_frame.sframe[idxf].vmem[ii*VFD_BYTES_PER_COL + jj / 8] &= ~(1 << (jj % 8));
  20.                                 
  21.       if (++idxf == VFD_GRAYSCALE_CNT)
  22.         idxf = 0;
  23.     }
  24.   }
  25.         }
复制代码


中层同时还要负责提供一些图形和文字API给上层调用,例如显示个数字、画个圆、画个方块之类的,现在还没写,后续会慢慢实现(工作太忙。。。)。
中层的数据链路为:上层调用 -> 中层API -> 中层显存 -> 切片 -> 底层显存 -> VFD

灰度实现大概就这么多。
终极目的是用它做一个通用显示器,可以和树莓派对接显示终端,或者换STM32F4以后做一个复古游戏机什么的。别老做时钟万年历啦!现在都用手机,不如做一点与众不同的东西嘛。
后续会在GitHub上分享代码。如果希望了解更多的细节,可以邮件联系我:532493398@qq.com

打赏

参与人数 2家元 +28 收起 理由
guangqu + 8 厉害了,我的坛友
杨雪飞 + 20 謝謝分享

查看全部打赏

发表于 2020-9-20 19:20:12 | 显示全部楼层
又遇上大神。。。:praise::praise::praise:
回复 支持 反对

使用道具 举报

发表于 2020-9-21 09:41:41 | 显示全部楼层
兄弟可否把供电方案分享一下

打赏

参与人数 1家元 +20 收起 理由
10655188 + 20

查看全部打赏

回复 支持 反对

使用道具 举报

发表于 2020-9-21 10:05:13 | 显示全部楼层
手里貌似也有一个类似的车机,原本想在无聊的时候拆了玩玩,看楼主的介绍不想动手了、挺难弄的样子。
回复 支持 反对

使用道具 举报

发表于 2020-9-22 11:17:06 | 显示全部楼层
这个就厉害了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-23 01:01:53 来自手机浏览器 | 显示全部楼层
杨雪飞 发表于 2020-9-21 09:41
兄弟可否把供电方案分享一下

用的就是板子上自带的供电,先测软件
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-23 01:02:29 来自手机浏览器 | 显示全部楼层
慕名而来 发表于 2020-9-21 10:05
手里貌似也有一个类似的车机,原本想在无聊的时候拆了玩玩,看楼主的介绍不想动手了、挺难弄的样子。 ...

花样有花样玩法  普通也有普通的嘛,随自己想要的方法折腾就行
回复 支持 反对

使用道具 举报

发表于 2020-9-23 08:45:27 | 显示全部楼层
oakweasley 发表于 2020-9-23 01:01
用的就是板子上自带的供电,先测软件

楼主这一段-----   后来出现了DC-DC驱动器+倍压整流的邪道,省去了变压器,灯丝用BTL推挽或电桥的方案,可以简化供电设计,也是我在使用的方案之一。

电路是否真的可以比双管自激变压器方式简洁吗?想看一下。
回复 支持 反对

使用道具 举报

发表于 2020-9-23 09:55:04 | 显示全部楼层
oakweasley 发表于 2020-9-23 01:02
花样有花样玩法  普通也有普通的嘛,随自己想要的方法折腾就行

力所能及的玩玩单片机算了,太难弄的就不动了,硬是费力的弄就只有累而没有快乐了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-23 20:33:12 来自手机浏览器 | 显示全部楼层
杨雪飞 发表于 2020-9-23 08:45
楼主这一段-----   后来出现了DC-DC驱动器+倍压整流的邪道,省去了变压器,灯丝用BTL推挽或电桥的方案, ...

问题不在元件数量的多少,开关变压器的计算是个经验活,如果是搞电源的人应该变压器+自激简单,但对于其他领域的人而言,dc-dc学习成本更低,成功率高,灯丝直接用LM9022就行了

打赏

参与人数 1家元 +10 收起 理由
杨雪飞 + 10 謝謝分享

查看全部打赏

回复 支持 反对

使用道具 举报

发表于 2020-9-24 08:55:55 | 显示全部楼层
本帖最后由 杨雪飞 于 2020-9-24 08:57 编辑
oakweasley 发表于 2020-9-23 20:33
问题不在元件数量的多少,开关变压器的计算是个经验活,如果是搞电源的人应该变压器+自激简单,但对于其 ...


这个9022居然是灯丝和负压全都可以输出的,但是输入需要个方波。还得需要单片机或者555之类的给个输入。
pg_0001.png
回复 支持 反对

使用道具 举报

发表于 2020-9-24 10:24:23 | 显示全部楼层
厉害啊,看图是从左到右灰度的,能变成从上到下的灰度条吗?是否每个像素都能独立控制不同灰度而不互相影响呢?
回复 支持 反对

使用道具 举报

发表于 2020-9-24 11:55:05 | 显示全部楼层
VFD的屏显示效果好看是好看,但是存在老化问题,这个比较纠结
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-25 08:51:33 来自手机浏览器 | 显示全部楼层
nonzhe 发表于 2020-9-24 10:24
厉害啊,看图是从左到右灰度的,能变成从上到下的灰度条吗?是否每个像素都能独立控制不同灰度而不互相影响 ...

本身就是每个像素的灰度都能控制啊,显示彩条只是为了便于说明问题
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-25 08:52:06 来自手机浏览器 | 显示全部楼层
bg4iww 发表于 2020-9-24 11:55
VFD的屏显示效果好看是好看,但是存在老化问题,这个比较纠结

放心,只要不是7*24小时一直工作,爱好者而言不会有明显的老化问题
回复 支持 反对

使用道具 举报

发表于 2020-9-25 10:56:34 来自手机浏览器 | 显示全部楼层
oakweasley 发表于 2020-9-25 08:51
本身就是每个像素的灰度都能控制啊,显示彩条只是为了便于说明问题

就是说必须要有cpu不断进行刷新,不停写入数据?原来是写入后会锁定的,不写也会显示的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-26 10:57:52 | 显示全部楼层
nonzhe 发表于 2020-9-25 10:56
就是说必须要有cpu不断进行刷新,不停写入数据?原来是写入后会锁定的,不写也会显示的 ...

不写入也会保持的,但是对于实现灰度的场景就必须持续刷新了,否则灰度就显示不出来了
回复 支持 反对

使用道具 举报

发表于 2020-9-26 12:19:44 来自手机浏览器 | 显示全部楼层
oakweasley 发表于 2020-9-26 10:57
不写入也会保持的,但是对于实现灰度的场景就必须持续刷新了,否则灰度就显示不出来了 ...

那其实不用int也可以,不断写入就可以了啊
回复 支持 反对

使用道具 举报

发表于 2020-9-26 22:28:01 | 显示全部楼层
还没玩过,先收藏了,示波器不错。。比我的DS 8608A强多了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2024-4-24 01:57 , Processed in 0.156000 second(s), 14 queries , Redis On.

Powered by Discuz!

© 2006-2023 smzj.net

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