目录

使用LCD12864播放BadApple

近日以一块多的价格购得数块1.8寸单色的屏幕QFG12864,驱动器是常见的ST7565。遂自制转接板,并准备试着拿这块屏幕播放Bad Apple

转接板制作

为了好好的玩起来这块QFG12864屏幕,花了屏幕几倍的价钱打样了屏幕的转接板,一次点亮。

https://img.yuanze.wang/posts/badapple-12864/screen1.jpg
转接板正面

https://img.yuanze.wang/posts/badapple-12864/screen2.jpg
转接板背面

https://img.yuanze.wang/posts/badapple-12864/demo.jpg
点亮效果

 QFG12864底板PCB文件

俗话说的好,有屏幕的地方就有Bad Apple。那我们也来用这块一块钱的屏幕播放Bad Apple

播放Bad Apple

显示部分不用多说,就是今天的主角QFG12864。单片机也是我们的老朋友STM32。使用单片机播放视频,首先需要有一个存储视频的地方,这里我们没有选用大家常用的SPI Flash,并没有使用串口实时发送的方式。由于我们使用的STM32速度足够快,并且有硬件的SPI接口,因此我们可以使用SD卡作为存储介质,使用fatfs文件系统,从SD卡里面直接读取数据。这样可以省去一个编程器,直接用电脑往SD卡里面复制数据即可。

硬件部分非常简单:一个单片机,一个SD卡和一个屏幕。SD卡使用的是硬件SPI1,屏幕是软件IO模拟的,定义可以从程序中找到。

在移植好了屏幕和SD卡的驱动并调试好fatfs之后,程序只需要读取一帧的数据送给LCD进行显示并无限循环即可。这里不对程序做过多的说明,仅贴出来一部分核心代码,完整的工程可以在文末下载附件查看。

注意
工程中的驱动为了兼容之前的OLED驱动,使用了与OLED驱动中的相同的函数名。
void PlayBadApple(void)
{
  unsigned int i,j;
  FIL file;
  OLED_clear();
  
  f_open(&file,"BadApple.bin",FA_READ);
  
  TIM3_Init(1000000 / FrameRate,71);//1us * 33333= 33.3ms
  
  for(i = 0;i < FrameCount;i ++)
  {
    f_lseek(&file,FrameSize*i);
    f_read(&file,DisBuf,FrameSize,&j);
    OLED_bmp((128-FrameXSize)/2,0,FrameXSize,FrameYSize,DisBuf);
    
    while(!Next\_Frame);
    Next\_Frame = 0;
  }
  OLED_clear();
  f_close(&file);
}

int main(void)
{
  delay_init();
  SetRemap();
  
  OLED_Init();
  OLED_8_16(0,0,"Hello World!");
  
  SD_HW_Config();
  while(SD_Init() != 0);
  
  f_mount(&fatfs,"",0);//挂载文件系统
  while(1)
  {
    PlayBadApple();
  }
}

 单片机程序工程

视频文件获取

下面便是本文的重头戏:如何获取STM32可以播放的视频文件。视频的本质是一帧一帧的图像连续播放,因此只需要将这一帧一帧图像截取出来,分别转换成可被单片机读取的数组并存到单片机的存储器中,这样只需要将每一帧按顺序送到LCD中显示,便可以实现视频的效果。首先,需要找到BadApple的视频文件。

https://img.yuanze.wang/posts/badapple-12864/videoinfo.png
视频信息

我使用的播放器是Pot Player,这款播放器的功能非常强大,其中就有我们需要的视频逐帧截图功能。在视频->图像截取->连续截图中,设置截取图像的格式为BMP(这样后面取模软件的速度会快不少),分辨率为86*64(固定纵向分辨率为64,横向分辨率根据视频分辨率可以计算为86),截图设置为按帧间距1帧截图,采集数量设为最大的9999。接下来,将视频进度条拖到最开始,点击开始截图后开始播放并播放完视频即可获得每一帧的图片文件。

注意
这个过程对电脑要求较高,配置不好的什么都别做,等待视频放完,否则可能会出现未响应的情况。

https://img.yuanze.wang/posts/badapple-12864/screenshot1.png
连续截图

截图文件夹中存放了每一帧的图片文件。

https://img.yuanze.wang/posts/badapple-12864/screenshot2.png
截图文件夹

接下来用到了Image2LCD这款取模工具。最新版的这个工具提供了一个批量取模的功能,只需要设置好参数并打开第一张图片,它就会把这个文件夹下面的所有文件都自动批处理,非常方便。

注意
取模的格式与OLED的相同。

https://img.yuanze.wang/posts/badapple-12864/image2lcd.png
Image2LCD

点击批量转换,即可将每一帧的图片生成bin文件。

https://img.yuanze.wang/posts/badapple-12864/screenshot3.png
转换完成后的文件

使用你喜爱的二进制编辑器,将它们合成一个bin文件,这就是我们需要播放的文件了。除了这个文件之外,还需要在程序里声明一些必要的数值,其中包括视频的宽、高、帧率、总帧数等。

#define FrameXSize 86
#define FrameYSize 64/8
#define FrameSize FrameXSize*FrameYSize
#define FrameCount 6567
#define FrameRate 30

下面提供一个我处理好的bin文件,这个文件与上述参数配套,可以直接拿来使用。

 BadApple.bin

效果展示

最终播放效果如视频所展示。