ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

k210 C语言开发-4 从sd卡读取播放烟花视频

2022-01-28 00:04:10  阅读:299  来源: 互联网

标签:bin 视频 k210 ret C语言 320 图片 buf sd


k210 C语言开发-4

先上成果图吧,祝大伙新年快乐!
请添加图片描述
B站原视频
前天无意中看到CSDN有个活动,我一看只要是和烟花相关的都可以,然后我就准备用k210播放个烟花视频。结果我哼哧哼哧整完了之后,发现这个活动是要用代码来实现放烟花,文不对题了属于是。。。唉,记录一下过程吧。

大体思路就是把视频文件转换成二进制文件放到SD卡中,然后单片机读取用LCD播放。
在之前已经实现了k210使用LCD以及sd卡
老样子,先把需要的文件整合一下:
在这里插入图片描述
发现原先的LCD和SD卡都用的spi0接口.所以要在代码里改下接口。
K210是具有FPIOA(现场可编程IO阵列),我们可以将 255 个内部功能映射到芯片外围的 48 个自由 IO 上。所以说我们可以把一些引脚的功能改了,比如原本接SD卡的是spi0,现在可以改成spi1。

void io_mux_init(void) {
  fpioa_set_function(27, FUNC_SPI1_SCLK);
  fpioa_set_function(26, FUNC_SPI1_D1);
  fpioa_set_function(28, FUNC_SPI1_D0);
  fpioa_set_function(29, FUNC_SPI1_SS3);
}

还有原本这些都调用的spi0也要都改成1.
在这里插入图片描述
这些都在一个sdcard.c文件里,把SPI_DEVICE_0全部替换为SPI_DEVICE_1就行了。
然后测试一下,可以正常输出就行。
那现在就是先实现一个把一张图片转换成bin文件放到sd卡里,然后读bin文件用LCD显示。
我测试时用的这个图片,我觉得清晰的颜色可以比较容易看到一些问题
请添加图片描述
取模软件用的是Image2Lcd,这个软件功能很全。
打开图片,输出数据类型选二进制,,输出灰度选择16位真彩色,然后根据屏幕大小选择输出的形状,在软件的下方就显示了输入输出图像的形状。
扫描的方式很重要,我在这里反复弄了几次。
首先我先确定了我的屏幕在DIR_XY_LRDU方向下输入扫描方向是这样的:
在这里插入图片描述
所以我的图片取模的方向也要是这个顺序,Image2Lcd这个软件在左上方显示了当前设置下的扫描方式
在这里插入图片描述
注意不要包含图像头数据,这样方便我们读取。
用读卡器把转换后的bin文件放到SD卡里。
用f_read()来读取,十六位真彩色下,每个像素用2个字节来表示,所以总的字节数是3202402=153,600。

ret = f_read(&file, (void *)v_buf, 320 * 240 * 2, &v_ret_len);

然后我去看了下库里的LCD显示图片函数,发现它居然要我放个uint32_t类型的数组

void lcd_draw_picture(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height,
                      uint32_t *ptr) {
  lcd_set_area(x1, y1, x1 + width - 1, y1 + height - 1);
  tft_write_word(ptr, width * height / 2, lcd_ctl.mode ? 2 : 0);
}

可是这个小屏幕一个像素点只需要uint16_t就够了啊。
后来我发现它用一个uint32_t来显示两个像素,我也不明白为啥要这样设计,不过反正我直接读取的是uint8_t都要转换一下,也就无所谓了。
那么现在就是把4个字节拼成一个uint32_t来显示两个像素。

      for (int n = 0; n < 320 * 240 / 2; n++) {
        img_buf[n] = (v_buf[4 * n] << 24) | (v_buf[4 * n + 1] << 16) |
                     (v_buf[4 * n + 2] << 8) | v_buf[4 * n + 3];
      }

然后

lcd_draw_picture(0, 0, 240, 320, img_buf);

在这里插入图片描述
这个图片是错的,因为当时没调整扫描方向。
现在基本成功一大半了,理论上来说循环播放图片就是视频了。
把视频从B站上下载下来,up在评论区给了百度网盘的链接,嫌下载速度慢的话,油猴插件和IDM了解一下。
然后就是视频转换与裁切,这些在线转换工具百度一搜就有。
整完之后就是这样的:
在这里插入图片描述
把这个放到PotPlayer里获得每一帧的图片。
先设置为无边框尺寸
在这里插入图片描述
然后选择连续截图:
在这里插入图片描述
选择截图的方式,帧率

在这里插入图片描述
注意,由于是用截图的方式获得图片的所以要用无边框以及在点击开始时视频是要处于播放状态的。
然后就得到了一个有很多帧图像的文件夹了
在这里插入图片描述
拿一张图片出来显示显示试试:
在这里插入图片描述
不错不错,接着在用Image2Lcd来批量取模,取模后的文件就放在帧图像的文件夹里。
点开后是很多个bin文件,我们需要将它们合并成一个bin文件。
方法很多,我用的是linux的cat指令。
在WSL下,cd到那个bin文件夹
在这里插入图片描述
用 bat指令合成就行
在这里插入图片描述
现在这个vedio.bin文件就是这个视频的所有数据了。
前面已经实现了一张图片的显示,现在就是一个for循环的事了

for (uint32_t i = v_fileinfo.fsize / (320 * 240 * 2); i > 0; i--) {
      ret = f_read(&file, (void *)v_buf, 320 * 240 * 2, &v_ret_len);
      if (ret != FR_OK) {
        printf("Read %s err[%d]\n", path, ret);
      } else {
        // printf("Read :> %d %d bytes lenth\n", v_buf, v_ret_len);
      }

      for (int n = 0; n < 320 * 120; n++) {
        img_buf[n] = (v_buf[4 * n] << 24) | (v_buf[4 * n + 1] << 16) |
                     (v_buf[4 * n + 2] << 8) | v_buf[4 * n + 3];
      }

      lcd_draw_picture(0, 0, 240, 320, img_buf);
      // 加地址偏移
      img_offset += 320 * 240 * 2;
      ret = f_lseek(&file, img_offset);

      if (ret != FR_OK) return -3;
      // printf("%d\n", v_buf[0]);
      // printf("%d\n", v_buf[1]);
      // printf("%d\n", img_buf[0]);
      // printf("%d\n", img_buf[70100]);
    }

大功告成

标签:bin,视频,k210,ret,C语言,320,图片,buf,sd
来源: https://blog.csdn.net/m0_66478571/article/details/122722648

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有