显示图片
1.这是随便一张的图片,自己可以随便截图一张
2.单击图片,右边选择编辑
3.如下操作
4.然后,这个水平和垂直的值的设置要根据你所使用的屏幕有多少个像素点,我当前使用的是0.96寸OLED屏幕,也就是12864,像素点是128*64。根据我的设置,图片最后显示到屏幕上的大小是22*32
5.接下来进行图片的保存,保存的格式是单色位图
6.分辨率是22*32,是按照我设置的,没问题
7.使用取模软件PCtoLCD,模式选择图形模式
然后选择之前保存的bmp图片
菜单中选项这边进行设置
取模
8.复制到程序中
/*** 函 数:OLED显示图像(**Adam修改, Y轴可以是负数**)* 参 数:X 指定图像左上角的横坐标,范围:0~127* 参 数:Y 指定图像左上角的纵坐标,范围:int_8* 参 数:Width 指定图像的宽度,范围:0~128* 参 数:Height 指定图像的高度,范围:0~64* 参 数:Image 指定要显示的图像* 返 回 值:无* 说 明:调用此函数后,要想真正地呈现在屏幕上,还需调用更新函数*/
void OLED_ShowImage(uint8_t X, uint8_t Y0, uint8_t Width, uint8_t Height, const uint8_t *Image)
{int8_t Y = (int8_t)Y0; // XY值为负数时,只要图片还有部分在屏幕内显示,就还是有意义的;uint8_t i, j;/*参数检查,保证指定图像不会超出屏幕范围*/if (X > 127){return;} // 如果X大于127则打印无意义,故无需打印uint8_t k = 0, l = 0, temp_Height; //(创建Y为负数相关变量)if (Y < 0) // 如果Y小于0, 则需打印图片位于屏幕内的部分;{temp_Height = Height; // 记录图片高度Height += Y; // 图片的高 减去Y轴绝对值k = (-Y - 1) / 8 + 1; // 图片的Byte行的下标偏移量;l = (-Y - 1) % 8 + 1; // Byte位移基 //(8 + Y % 8)%8;// OLED_ShowNum(0, 56, l, 3, 6);Y = 0; // 图片仍然从屏幕Y0开始打印if ((int8_t)Height < 1){return;} // 需打印的图片高小于1时,说明不需要打印;}else if (Y > 63){return;} // 如果Y大于63则打印无意义,故无需打印/*将图像所在区域清空*/OLED_ClearArea(X, Y, Width, Height);/*遍历指定图像涉及的相关页*//*(Height - 1) / 8 + 1的目的是Height / 8并向上取整*/uint8_t Height_ceil = (Height - 1) / 8 + 1;for (j = 0; j < Height_ceil; j++) // 以OLED_DisplayBuf行下标遍历,(图像涉及的相关页){/*遍历指定图像涉及的相关列*/for (i = 0; i < Width; i++){/*超出边界,则跳过显示*/if (X + i > 127){break;}if (Y / 8 + j > 7){return;}if (k) // 以一行OLED_DisplayBuf行下标为基础, 取两行图像Byte, 根据位移基放置;{/*显示上一Byte图像在当前页的内容*/OLED_DisplayBuf[Y / 8 + j][X + i] |= Image[(j + k - 1) * Width + i] >> ((l));/*超出边界,则跳过显示*//*使用continue的目的是,当前Byte超出图片时,上一Byte的后续内容还需要继续显示*/if ((j + k) * 8 >= temp_Height){continue;} // 如果当前行Byte已经不属于图像,则不放置;/*显示当前Byte图像在当前页的内容*/OLED_DisplayBuf[Y / 8 + j][X + i] |= Image[(j + k) * Width + i] << (8 - (l));}else // 以一行图像Byte为基础, 放于两行OLED_DisplayBuf行之间;{/*显示图像在当前页的内容*/OLED_DisplayBuf[Y / 8 + j][X + i] |= Image[(j)*Width + i] << ((Y) % 8);/*超出边界,则跳过显示*//*使用continue的目的是,下一页超出边界时,上一页的后续内容还需要继续显示*/if (Y / 8 + j + 1 > 7){continue;}/*显示图像在下一页的内容*/OLED_DisplayBuf[Y / 8 + j + 1][X + i] |= Image[(j)*Width + i] >> (8 - (Y) % 8);}}}
}
9.实验结果
10.重复上述操作,再次取模得到一个分辨率一致数字,这样方便写入同一个数组进行调用。这个二维数组的一行就是对应一张图片的数据,一个文字的数据...
这个二维数组的每一行代表的是一个数字,或者文字,图片。程序上面看着一张图片对应好多行数据,但是你把一张图片对应的数据想象全放在一行。二维数组的列必须固定,分辨率确定了就知道有多少列。
int a[3][4];
a;//代表数组首行地址,一般用a[0][0]的地址表示
&a;//代表整个数组的地址,一般用a[0][0]地址表示
a[i];代表了第i行起始元素的地址(网上说是代表了第i行的地址,但我觉得不是,在讲数组与指针的关系时我会验证给大家看)
&a[i];代表了第i行的地址,一般用a[i][0]的地址表示
a[i]+j;//代表了第i行第j个元素地址,a[i]就是j==0的情况
a[i][j];//代表了第i行第j个元素
&a[i][j];//代表了第i行第j个元素的地址
二维数组讲解
二维数组与指针(详解)_二维数组指针-CSDN博客
实验结果
显示文字
1.取模软件的设置还是和刚刚一样
2.模式选择字符模式,分辨率还是设置跟刚刚的一样,22*32,放入同一数组,方便管理,然后输入文字“你好”,进行取模
3.放入数组
const uint8_t number[][88] = {
0x00,0x00,0x80,0x60,0xD0,0xE8,0xF8,0x74,0xB4,0xDC,0xDC,0xDC,0xB4,0x74,0xE8,0xD8,
0xB0,0x60,0x80,0x00,0x00,0x00,0x00,0x00,0x7F,0xC0,0x7F,0xFF,0xE0,0xDF,0xBF,0xE3,
0x41,0xC0,0xA1,0x77,0xED,0xFF,0xFF,0xFC,0x03,0xFF,0xF8,0x00,0x00,0x00,0x00,0x00,
0xC1,0xE6,0x45,0x8D,0x8D,0x8D,0x9D,0x4F,0xEE,0xDF,0xE1,0xFF,0x7F,0xCF,0xF8,0xFF,
0x3F,0x00,0x00,0x00,0x02,0x07,0x0C,0x1B,0x1B,0x3F,0x36,0x36,0x36,0x37,0x3B,0x3B,
0x3D,0x1E,0x0F,0x0F,0x03,0x01,0x00,0x00,/*"D:\Desktop\图片\数字bmp\test_bmp\9.bmp",0*/
0x00,0x00,0x00,0xC0,0x70,0xE8,0xF4,0x3A,0xDA,0xEA,0xEE,0xEA,0xDA,0xBA,0xF4,0xEC,
0x18,0xE0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x1C,0xAF,0xDF,0xB8,0xF7,0xEF,
0xF8,0xD0,0xF8,0xFF,0x5C,0x6F,0xF8,0x7F,0x3F,0x00,0x00,0x00,0x00,0x00,0x70,0xFE,
0xFB,0xFE,0x83,0x7D,0xFF,0x0F,0x06,0x05,0x8D,0xFB,0xAF,0xFE,0xFD,0x02,0xFC,0xF8,
0x00,0x00,0x00,0x00,0x00,0x03,0x04,0x1B,0x17,0x37,0x76,0x75,0x7D,0x75,0x77,0x77,
0x77,0x3B,0x3D,0x1E,0x0F,0x07,0x00,0x00,/*"D:\Desktop\图片\数字bmp\test_bmp\8.bmp",0*/
0x00,0x00,0x00,0x00,0x00,0xC0,0x7C,0x18,0x08,0x00,0x80,0xFC,0x18,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x70,0x0E,0xFB,0x00,0x00,0x60,0x1C,
0x87,0x02,0x02,0xFA,0xF2,0x02,0x02,0x12,0x0F,0x07,0x02,0x00,0x00,0x02,0x01,0x00,
0x00,0xFF,0x00,0x00,0xC0,0x38,0x0F,0x01,0x00,0xFF,0xFF,0x00,0x01,0x06,0x38,0xF0,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x02,0x01,0x00,0x00,0x10,0x30,0x3F,
0x1F,0x00,0x00,0x00,0x00,0x01,0x01,0x00,/*"你",0*/
0x00,0x00,0x00,0x00,0x00,0xFC,0x08,0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,
0x20,0xE0,0x70,0x00,0x00,0x00,0x00,0x02,0x02,0x82,0xFF,0x03,0x02,0x82,0xFE,0x00,
0x00,0x00,0x00,0x00,0xFC,0xFC,0x03,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x20,0x3F,
0x40,0x40,0xE0,0xBF,0x00,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x01,0x01,0x01,0x01,
0x01,0x00,0x00,0x40,0x20,0x10,0x0C,0x03,0x01,0x01,0x03,0x0E,0x00,0x10,0x10,0x70,
0x7F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,/*"好",1*/
};
4.实验结果
实验结果
代码链接:
通过网盘分享的文件:2024_1_21_多级菜单_v1.8_STM32C8T6_标准库.zip
链接: https://pan.baidu.com/s/1309T7Osy5y5L-8e9PlvLYg?pwd=h4sx 提取码: h4sx
--来自百度网盘超级会员v7的分享
代码视频:
单片机多级菜单v1.2_哔哩哔哩_bilibili
注意:OLED_ShowImage这个函数在OLED_Patch_byAdam.c下