使用LCD12864播放BadApple
近日以一块多的价格购得数块1.8寸单色的屏幕QFG12864
,驱动器是常见的ST7565。遂自制转接板,并准备试着拿这块屏幕播放Bad Apple
。
转接板制作
为了好好的玩起来这块QFG12864
屏幕,花了屏幕几倍的价钱打样了屏幕的转接板,一次点亮。
俗话说的好,有屏幕的地方就有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
的视频文件。
我使用的播放器是Pot Player
,这款播放器的功能非常强大,其中就有我们需要的视频逐帧截图功能。在视频->图像截取->连续截图中,设置截取图像的格式为BMP
(这样后面取模软件的速度会快不少),分辨率为86*64
(固定纵向分辨率为64
,横向分辨率根据视频分辨率可以计算为86
),截图设置为按帧间距1
帧截图,采集数量设为最大的9999
。接下来,将视频进度条拖到最开始,点击开始截图后开始播放并播放完视频即可获得每一帧的图片文件。
截图文件夹中存放了每一帧的图片文件。
接下来用到了Image2LCD
这款取模工具。最新版的这个工具提供了一个批量取模的功能,只需要设置好参数并打开第一张图片,它就会把这个文件夹下面的所有文件都自动批处理,非常方便。
OLED
的相同。点击批量转换,即可将每一帧的图片生成bin
文件。
使用你喜爱的二进制编辑器,将它们合成一个bin文件,这就是我们需要播放的文件了。除了这个文件之外,还需要在程序里声明一些必要的数值,其中包括视频的宽、高、帧率、总帧数等。
#define FrameXSize 86
#define FrameYSize 64/8
#define FrameSize FrameXSize*FrameYSize
#define FrameCount 6567
#define FrameRate 30
下面提供一个我处理好的bin文件,这个文件与上述参数配套,可以直接拿来使用。
效果展示
最终播放效果如视频所展示。