FireBeetle 实现变幻线

2022-01-076388
AI 快速预览详细 收起
本文介绍了如何使用DFRobot的FireBeetle通过VGA接口实现经典的“变换线”屏保程序。文章首先解释了CRT显示器的工作原理和屏保的重要性,然后详细描述了硬件配置和代码实现。通过随机生成点的位置和速度向量,模拟经典的“变换线”屏保效果。最终在电视机上展示了实际运行结果。这个项目适用于复古技术爱好者和电子DIY项目。
CRT(阴极射线显像管)显示器的显像原理主要是由灯丝加热阴极,阴极发射电子,然后在加速极电场的作用下,经聚焦极聚成很细的电子束,在阳极高压作用下,获得巨大的能量,以极高的速度去轰击荧光粉层。这些电子束轰击的目标就是荧光屏上的三原色。为此,电子枪发射的电子束不是一束,而是三束,它们分别受电脑显卡R、 G、 B三个基色视频信号电压的控制,去轰击各自的荧光粉单元,从而在显示屏上显示出完整的图像。
在图形界面的操作系统下,显示屏上显示的色彩多种多样,当用户停止对电脑进行操作时,屏幕显示就会始终固定在同一个画面上,即电子束长期轰击荧光层的相同区域,长时间下去,会因为显示屏荧光层的疲劳效应导致屏幕老化,甚至是显像管被击穿。因此从Windows3.X时代至今,屏幕保护程序一直作为保护CRT显示屏的最佳帮手,通过不断变化的图形显示使荧光层上的固定点不会被长时间轰击,从而避免了屏幕的损坏。【参考1】
比如,下面这个照片就是游戏《吃豆人》的烧屏,《吃豆人》历史久远,画面对比度高且单一,又是热门游戏,所以很多老机台烧屏都十分严重。【参考2】
FireBeetle 实现变幻线图1
随着时代的发展,液晶屏成为了显示器的主流,屏保除了展示信息已经没有太多意义了(当然,它的存在还能保证当你休眠的时候不会有人手欠帮你按下关机)。Windows XP 开始,内置了一个非常经典的“变换线”屏保。这次的实验就是使用DFRobot 的FireBeetle通过VGA 接口实现这个功能。使用的硬件和库配置请参考之前的《FireBeetle 做一个 VGA 时钟》【参考3】一文:
FireBeetle 实现变幻线图2
关键部分参考了《模拟经典屏保“变幻线”》【参考4】,主要是绘制直线。
代码如下:
  1. #include "fabgl.h"
  2. // VGA 显示
  3. fabgl::VGA16Controller DisplayController;
  4. Canvas cv(&DisplayController);
  5. #define HIGH 480
  6. #define WIDTH 640
  7. #define RADIUS 20
  8. #define PN 5
  9. typedef struct
  10. {
  11.   int x;
  12.   int y;
  13.   int velocity_x;
  14.   int velocity_y;
  15. } VPOINT;
  16. static VPOINT vpoint[PN];
  17. void setup() {
  18.   Serial.begin(115200);
  19.   DisplayController.begin();
  20.   // 设定分辨率
  21.   DisplayController.setResolution(VGA_640x480_60Hz);
  22.   int             a;
  23.   cv.setPenColor(0xFF,0,0);
  24.   for (int i = 0; i < PN; i++)
  25.   {
  26.     vpoint[i].x = rand() % (WIDTH - RADIUS) + RADIUS;
  27.     vpoint[i].y = rand() % (HIGH - RADIUS) + RADIUS;
  28.     a = rand() % 361;
  29.     vpoint[i].velocity_x = (int)((RADIUS / 5) * cos(a));
  30.     vpoint[i].velocity_y = (int)((RADIUS / 5) * sin(a));
  31.   }
  32.   for (int i = 0; i < PN - 1; i++)
  33.   {
  34.     cv.drawLine(vpoint[i].x, vpoint[i].y,vpoint[i + 1].x, vpoint[i + 1].y);
  35.   }
  36.   cv.drawLine(vpoint[0].x, vpoint[0].y, vpoint[PN - 1].x, vpoint[PN - 1].y);
  37. }
  38. void loop() {
  39.   cv.clear();
  40.   for (int i = 0; i < PN; i++)
  41.   {
  42.     if ((vpoint[i].x <= 0) || (vpoint[i].x >= WIDTH))
  43.       vpoint[i].velocity_x = -vpoint[i].velocity_x;
  44.     if ((vpoint[i].y  <= 0) || (vpoint[i].y  >= HIGH))
  45.       vpoint[i].velocity_y = -vpoint[i].velocity_y;
  46.     vpoint[i].x += vpoint[i].velocity_x;
  47.     vpoint[i].y += vpoint[i].velocity_y;
  48.     for (int j = 0; j < PN - 1; j++)
  49.     {
  50.       cv.drawLine(vpoint[j].x, vpoint[j].y, vpoint[j + 1].x, vpoint[j + 1].y);
  51.     }
  52.     cv.drawLine(vpoint[0].x, vpoint[0].y, vpoint[PN - 1].x, vpoint[PN - 1].y);
  53.   }
  54. }
复制代码
在电视机上的显示结果:
FireBeetle 实现变幻线图3

完整代码:

参考:

创作许可协议

本项目采用 None(不开放任何权利,保留所有权利) 进行许可。

评论(1)
zoologist
zoologist
作者
工作的视频在:
[media=x,500,375]https://www.bilibili.com/video/BV1VF411v7Pc/[/media]
- 没有更多了 -