本帖最后由 CHRRR 于 2024-5-16 07:27 编辑
本帖最后由 CHRRR 于 2024-5-15 22:58 编辑
本帖最后由 CHRRR 于 2024-5-15 22:57 编辑
本帖最后由 CHRRR 于 2024-5-15 22:51 编辑
本帖最后由 CHRRR 于 2024-5-14 17:24 编辑
本帖最后由 CHRRR 于 2024-5-14 17:23 编辑
本帖最后由 CHRRR 于 2024-5-14 07:29 编辑
本帖最后由 CHRRR 于 2024-5-14 07:06 编辑
前言
五月初收到了Ai-M61-32S开发板,又白嫖朋友一个I2C OLED,就想用OLED显示点灯动画完成点灯作业
开发环境搭建
参考站内零基础搭建小安派Windows 开发环境
通过Git拉取SDK和工具链
在文件资源管理器可以看到拉取结果
接下来打开系统属性-环境变量添加Path,将M61SDK下toolchain中的gcc、make、ninja添加进环境变量,接下来保存并重启电脑,环境就配置完成了
I2C OLED
0.96寸上下的小尺寸OLED大多由SSD1306驱动。这颗驱动芯片缓存共有8页,每页128个字节,最多能够对应128*64像素(刚好是0.96寸OLED常用分辨率),支持I2C和SPI。这块屏幕是I2C协议(引脚用的少适合懒狗),作为一个常用元件网上有很多资料例程,这里贴一下中景园资料的百度云链接:中景园OLED资料 提取码8888
通过查询Ai-M61-32S规格书,IO0和IO1可作为I2C SCL和SDA使用,这里把OLED屏幕的引脚和开发板依次接好,如图所示:
Aseprite像素画编辑器
做像素游戏开发和像素画的坛友应该挺熟悉这个工具。正如其名,Aseprite是一个方便使用的精灵图形编辑器。精灵图形在游戏开发中是将多个图像(更多是一个动画序列)按照坐标拼合成一个图像,使用时通过坐标变化取图,能够避免多次图像载入,是一种空间换时间的策略。
Aseprite售价20刀,但是在Github是有开源版本的,可以自己编译,将白嫖进行到底。Github链接:Aseprite Github
OK,编译完成打开应用,首先左上角 文件-新建 新建一个图形序列。这里尺寸选择和OLED屏幕分辨率相同的128x64像素,方便图形绘制和取模,颜色选择灰度(其实用到的只有黑白两色),背景选透明,点击确定就完成了设置,进入画布。
Aseprite界面类似画图,上手还是相对简单的。贴一个简单入门教程,对于OLED这种每个像素只有亮灭两种状态的屏幕来说,几分钟就能学会并制作出自己的动画序列:
关于aseprite画像素画你需要知道的一切
第一步,用工具栏里的椭圆、直线工具简单画一个灯泡的形状作为第一帧
第二步,多画两笔,得到一个动画序列
第三步,导出动画序列中的图片并依次取模,或者就像精灵图形的定义一样,将动画序列导出到一张图中,一次取模十分方便:
点灯程序
因为工作不在家,再摸到开发板已经是14号晚上了,于是在社区找到了个大佬搬运的OLED驱动程序Ai-M61-32S i2c点亮oled详细教程及踩坑记录 - 小安派S1&M61教程合集 - 物联网开发者社区-安信可论坛 - Powered by Discuz! (ai-thinker.com),在基础上照葫芦画瓢写了个播放动画帧图像的函数:
/**
* 函 数:OLED显示GIF帧序列
* 参 数:X 指定图像左上角的横坐标,范围:0~127
* 参 数:Y 指定图像左上角的纵坐标,范围:0~63
* 参 数:Width 指定图像的宽度,范围:0~128
* 参 数:Height 指定图像的高度,范围:0~64
* 参 数:GIF 需要显示的GIF图像名
* 参 数:frame GIF动画帧数
* 返 回 值:无
* 说 明:调用此函数后,要想真正地呈现在屏幕上,还需调用更新函数
*/
void OLED_ShowGIFFrame(uint8_t X, uint8_t Y, uint8_t Width, uint8_t Height, uint8_t *GIF, const uint8_t frame)
{
uint8_t i, j;
/*参数检查,保证指定图像不会超出屏幕范围*/
// if (X > 127) {return;}
if (Y > 63) {return;}
/*将图像所在区域清空*/
OLED_ClearArea(X, Y, Width, Height);
/*遍历指定图像涉及的相关页*/
/*(Height - 1) / 8 + 1的目的是Height / 8并向上取整*/
for (j = 0; j < (Height - 1) / 8 + 1; j ++)
{
/*遍历指定图像涉及的相关列*/
for (i = 0; i < Width; i ++)
{
/*超出边界,则跳过显示*/
// if (X + i > 127) {break;}
if (Y / 8 + j > 7) {return;}
/*显示图像在当前页的内容*/
OLED_DisplayBuf[Y / 8 + j][X + i] |= GIF[frame* ((Height - 1) / 8 + 1) * Width + j * Width + i] << (Y % 8);
/*超出边界,则跳过显示*/
/*使用continue的目的是,下一页超出边界时,上一页的后续内容还需要继续显示*/
if (Y / 8 + j + 1 > 7) {continue;}
/*显示图像在下一页的内容*/
OLED_DisplayBuf[Y / 8 + j + 1][X + i] |= GIF[frame* ((Height - 1) / 8 + 1) * Width + j * Width + i] >> (8 - Y % 8);
}
}
}
接下来make一下,按住开发板IO2不放的同时点按EN后松开进入烧录模式,烧录完成后再按一下EN复位,这时就能看到点灯结果啦: