完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
前言
要问什么是测试单片机控制单色屏幕的最佳办法,我想badapple应该当之无愧,经典程度如helloworld。 这次,我用stm32f103c8t6+arduino框架读取sd卡,并控制jlx12864g-086液晶屏(3.3v版本)播放20fps(理论上)badapple动画。sd(tf)卡模块就是arduino上常用的那种,上面有卡槽和电平转换ic,将arduino常用的5v转成3.3v。液晶屏在某宝有,用u8g2库控制,可以看我以前的博客。 经过测试,发现该cog lcd实际帧率并不高,相较于oled,是肉眼可见的慢。和b站上的5110屏幕相比也慢。目前暂未能有效提升动画流畅度,也不知道是卡在sd的io上(可能性最大)还是lcd上还是别的什么地方,读者有兴趣可以在本文基础上进一步研究。 注意,本文需要结合其他的badapple实现文章进行阅读。本文代码皆为在他人基础上加以改动。在此表达感谢。 引脚连接 [tr]SD模块(硬SPI控制)单片机引脚[/tr]VCC5V GNDGND MISOPA6 MOSIPA7 SCKPA5 CSPA4 [tr]12864(软SPI控制)单片机引脚[/tr]CSPA3 RSTPA2 RSPA1 SDAPA0 SCLKPC15 VDD3.3V VSSGND 代码示例 #include 《SD.h》 #include 《Arduino.h》 #include 《U8g2lib.h》 #ifdef U8X8_HAVE_HW_SPI #include 《SPI.h》 #endif #define LCD_WIDTH 128 #define LCD_HEIGHT 64 //注意是count,乘以8=80,才是真实width #define WIDTH_COUNT 10 #define HEIGHT 60 #define SIZE (WIDTH_COUNT*HEIGHT) #define top (LCD_HEIGHT - HEIGHT) / 2 #define left (LCD_WIDTH - WIDTH_COUNT * 8) / 2 //液晶屏驱动 U8G2_UC1701_MINI12864_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ PC15, /* data=*/ PA0, /* cs=*/ PA3, /* dc=*/ PA1, /* reset=*/ PA2); int sdCSPin=PA4; char buf[SIZE]; File root; File myFile; void draw() { u8g2.drawBitmap(left, top, WIDTH_COUNT, HEIGHT, (const uint8_t*)buf); } void setup(){ Serial.begin(9600); u8g2.begin(); if (!SD.begin(sdCSPin)) { Serial.println(“Initialization Failed”); return; } Serial.println(“Initialization OK”); myFile = SD.open(“BADAPP~2.BIN”); } void loop(){ u8g2.firstPage(); do { draw(); } while(u8g2.nextPage()); if (myFile && myFile.available()) { myFile.read(buf, SIZE); } else { myFile.close(); myFile = SD.open(“BADAPP~2.BIN”); Serial.println(“Replay.”); delay(5000); } } 下面是将视频转为图像数据的matlab代码。在安装matlab时需要装图像处理工具箱这个组件,否则报错。不想安装matlab的读者可以自己写。 %% Bad Apple 图像数据生成程序 % 需事先将视频文件放在代码所在文件夹内 % 本例最终生成图像尺寸为80*60,可按需修改 %该源码来源于网络,具体作者未知,棉花糖做了细微修改 %如果侵犯了你的权益,我会及时删除 %% 预处理 clc;clear; fileName = ‘badapple.mp4’; % 文件名可按实际修改 video = VideoReader(fileName); % matlab自带,读取视频文件 numOfFrames = video.Duration * video.frameRate; % 总帧数 = 总时长 * 帧率 guiWaitBar = waitbar(0,‘Please wait’); % 新建进度条GUI fid = fopen(‘badapple_20FPS.bin’,‘a’); % 新建二进制文件,以添加方式打开 %% 图像处理 tic; % 计时开始 k = 1; while hasFrame(video) % 只要视频还没读取完就循环 frame = readFrame(video); % 每执行一次readframe,帧数减少1 if rem(k,2)==0 % 每隔3帧处理一帧,即原视频30FPS,此处取15FPS D = im2bw(frame,0.5); % 对图像二值化,0.5代表阈值取中值 rawData = imresize(D,[60 80]); % 保持原比例调整尺寸到80*60 %fwrite(fid,imageData‘,’ubit1‘,’ieee-be‘); % 按位,以大端模式写入二进制文件 fwrite(fid,rawData’,‘ubit1’,‘ieee-be’); end k = k+1; waitbar(k/numOfFrames,guiWaitBar); % 设置进度条当前值 end close(guiWaitBar); % 关闭进度条 fclose(fid); toc; % 计时停止 问题排查 1. sd卡无法读取 这个问题非常复杂,可能的原因有很多。 如果用的是stlink或jlink,那么请换成u***-ttl串口下载工具。我在测试时发现stlink调试sd卡是一直失败的,card.init通过,但卡在volume.init。换了u***-ttl可以正常使用。原因未可知,如果有知道原因的大佬麻烦解答一下。 先烧一个串口输出例程看看是否正常,检查波特率对不对。 运行cardinfo(官方例程)。官方例程是用硬件SPI1引脚。默认CS引脚是4,其实就是stm32f103上的PA4。也就是说只需要切换板型即可。引脚按照上文表格连接,保持不变。接下来看串口输出,是否能正常初始化、读取卡型、获取文件名等。 如果能成功获取文件名,那么要注意读取出的文件名是否是badapp~1.bin这种。如果是,请尝试把该名称替换掉代码里的文件名,再进行测试。 如果不能成功获取到文件名,那么有以下方法: 用avr版的arduino(比如uno)测试模块及sd卡是否正常 换更短的杜邦线 降低SPI速度。比如cardinfo例程中,有if (!card.init(SPI_HALF_SPEED, chipSelect)) 这一句,可以把 SPI_HALF_SPEED换成SPI_QUARTER_SPEED,或者除以1个值再进行测试。这里补充一下,如果读者遇到stm32+arduino i2c无法正常工作,也可以降低速度。 如果sd卡信息能够成功读取,那么恭喜你节省了99%的精力,并距离成功仅一步之遥(确信)。 2. lcd无显示 可以用我之前发的代码测试一下是否可以正常输出。 检查引脚是否正确、排针是否虚焊。如果买了多个屏幕那么换一个看看。 |
|
|
|
只有小组成员才能发言,加入小组>>
2549 浏览 0 评论
1148浏览 2评论
747浏览 1评论
500浏览 0评论
266浏览 0评论
429浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 19:08 , Processed in 1.336047 second(s), Total 79, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号