一、前言
最近正好学习SD卡,顺手在LED屏上做个badapple玩玩。以为很简单,也耗费了一些时间,故作此记录。希望可以帮到朋友们。
二、准备
我将从各个模块的实现一一讲解,更偏向于思路。OK,我们开始吧。
1. 实现LED基本读写函数
首先你得实现屏幕的一些基本函数,我们这以实现128X64的图像为例。代码做了详细注释,重要的是理解其中逻辑。
/************************************************
功能:在屏幕上显示一幅128X64的图像
参数:X:图像启始位置的横坐标
y: 图像启始位置的纵坐标
text:存储图像数据的数组
************************************************/
void disp_image_64x128(int x,int y,char *text)
{
unsigned int k;
lcd_address(x,y,64,128); //在X,Y处划定范围
//每一个像素点可用1位表示,128X64/8=1024byte
for(k=0;k<1024;k++) //依次传入图像数组
{
mono_transfer_data_16(text[k],QG,BG);//QG,BG 为前景色和背景色
}
}
/************************************************
功能: 将传入数据转义为图像颜色数据
参数:mono_data:传入数据
font_color: 前景色
back_color: 背景色
************************************************/
void mono_transfer_data_16(int mono_data,int font_color,int back_color)
{
int i;
for(i=0;i<8;i++) //从高位开始判断一个字节的每一位
{
if(mono_data&0x80)
{
transfer_data_16(font_color); //当数据是 1 时,显示字体颜色
}
else
{
transfer_data_16(back_color); //当数据是 0 时,显示底色
}
mono_data<<=1; //循环移动
}
}
2.实现SD卡读写和FATFS移植
因为传入数据过大,我们需要SD卡来存储大量的图片数据。然后需要引入文件系统来读入数据。
这里我主要参考的是正点原子。因代码过多,不便讲解,给大家留下链接。
视频讲解
资料下载
3.准备素材
注:所需软件和素材已打包,文末有链接。给我个赞吧。
3.1得到图片
大家可以从B站找到badapple的高清视频然后通过视频剪辑软件截取帧动画。我用的KMPlayer软件。
①导入视频
②按下图操作
这里我们选择的128X64的尺寸,帧率为1S10帧,大家也可以按照自己的需求调整。
④点击开始,等待结束后,可以在KMPlayer软件安装目录下的Capture文件夹下找到捕获图片。
3.2得到bin文件
①图片全部捕获完成后,使用Image2Lcd将bmp批量转换成bin文件。
这里说明一下这个软件需要注意的点,红色框按照我的方式更改,绿色框需要根据自己屏幕的扫描方式自行更改。其他选项默认就行。
大家需要知道自己屏幕扫描的方式,如果不知道,你可以写一个显示全屏红色,在传入颜色数据那加一个延时,你就可以看到红色按照何种扫描方式填满整个屏幕。通过更改绿色框内选项使示例跟自己的扫描方向相同。
配置完成后,点击批量转换,即可。注意,如果不确定自己是否配置正确,我们可以先只转换一张图片,看看自己屏幕能否正确显示出来,批量转换过程中,Image2Lcd可能会卡住,不用管它,但转换仍在进行中,可以观察转换文件夹文件数量依然在增加。
②得到大量bin文件,大家可以看到单个bin文件的大小为1024字节,怎么来的呢?很简单,128x64,每一个像素点占1位,那么就是
128X64/8=1024byte。
3.3合并bin文件
①将装有所有biin文件的batch文件夹剪切粘贴到C盘根目录
②按下键盘的WIN+R调出命令窗口,依次输入如下命令。
cd C:\batch
copy /b *.bin badapple.bin
③合并完成后在batch文件夹最下面找到badapple.bin文件剪切粘贴到内存卡。
然后将badapple.bin文件复制到SD卡中,插到单片机的SD卡座中即可。
四、编写播放函数
/************************************************
功能:从SD卡读取bin文件,并播放
参数:无
************************************************/
static void play_badapple(void)
{
uint32_t ls_move = 0; /* 存储文件指针移动 */
UINT br; /* 成功读取的字节个数 */
f_res = f_open(&file, "0:/badapple.bin", FA_READ);//打开bin文件
uint8_t badapple_Bin[1024]; /* BIN图形显存 */
if (f_res == FR_OK) //打开成功
{
while (1)
{
f_res = f_lseek(&file, ls_move); /* ls_move就是将读写指针定位到文件相应位置 */
f_res = f_read(&file, badapple_Bin, sizeof(badapple_Bin), &br); /* 读取Bin数据放入badapple_Bin数组中 */
//每次读取1024个字节正好一帧
if (br != 1024) /* 已经把数据读取完成*/// br表示成功读取的字节数,如果不是1024证明读取失败或者全部读取完了
{
ls_move = 0; /* 从头再来 */ //
break;
}
disp_image_64x128(50, 50, badapple_Bin);/* 显示帧数据 */
HAL_Delay(5); /* 加点延迟,看起来不会太鬼畜 */
ls_move += 1024; /* bin文件数据位置偏移 */ //偏移到下一帧位置
}
}
}
至此就大功告成了,相信你也可以,快去动手试试吧。
五、总结
没想到一个小小的badapple也融合了很多技术,设计到了屏幕显示,文件系统,SD卡操作等等。这次主要以128X64的尺寸显示,实际显示很流畅,就是有点小,哈哈。大家也可以更改更大尺寸尝试,但要注意的是, 更大尺寸的意味着刷新一帧画面需要更多时间,可能导致画面卡成PPT,具体的优化我就不展开了,快去实现自己的badapple吧,记得给我点点赞。
六、注
资源: 文章提到的资源整理