0.96寸OLED(SSD1306)屏幕显示
文章目录
前言
最近,我突发奇想去翻阅了一些我本科期间所做的一些小项目,发现都挺有意思的!当年做这些项目的时候可走了很多弯路,所以想着可以将它们上传到网络上,并通过我的讲解文章可以帮助你们少走一些弯路!
今天,我要分享的是一个0.96寸OLED(SSD1306)屏幕显示的学习笔记,因为我想要讲的详细一点,所以打算做成一个系列,手把手地教你学习和认识屏幕显示。由于我知识有限,如果出现一些错误,希望大家可以帮助我指出来,我们一起学习进步!!!
一、垂直水平滚动方法
1)SSD1306驱动芯片
对于垂直滚动方法,SSD1306数据手册也有详细的介绍,接下来我带大家一起来看看,如下图所示:
(SSD1306代码讲解部分)
OLED_Write_Cmd(0x2E); // 先必须关闭滚动
OLED_Write_Cmd(0x29); // 0x29是垂直水平向右滚动,0x2A是垂直水平向左滚动
OLED_Write_Cmd(0x00); // 虚拟字节
OLED_Write_Cmd(0x00); // 起始页 0
OLED_Write_Cmd(0x07); // 滚动时间间隔
OLED_Write_Cmd(0x07); // 终止页 7
OLED_Write_Cmd(0x01); // 垂直滚动偏移量OLED_Write_Cmd(0x2F); //开启滚动
(程序效果图 )
2)SSD1315驱动芯片
但是有些小伙伴,可能用上面的代码无法让自己手中的显示屏滚动起来,这个问题曾经也困扰我很久,找寻了很多博客也没有对这个问题进行解释。于是,通过我查阅大量资料发现,淘宝上很多便宜的0.96寸OLED显示屏采用的都是SSD1315驱动芯片,并不是SSD1306驱动芯片,这是因为SSD1315驱动芯片更加便宜,虽然这两者大部分的驱动命令相同,但有些许命令是有差别的!
网络上关于SSD1315驱动芯片的描述不是很多,这也萌生了我这篇博客,接下来,让我们来瞧瞧SSD1315驱动芯片关于垂直水平滚动的描述:
(SSD1315代码讲解部分)
OLED_Write_Cmd(0x2E); // 先必须关闭滚动
OLED_Write_Cmd(0x29); // 0x29是垂直水平向右滚动,0x2A是垂直水平向左滚动
OLED_Write_Cmd(0x01); // 0x00 水平滚动关闭,0x01 水平滚动开启OLED_Write_Cmd(0x00); // 起始页 0
OLED_Write_Cmd(0x07); // 滚动时间间隔
OLED_Write_Cmd(0x07); // 终止页 7
OLED_Write_Cmd(0x01); // 垂直滚动偏移量
OLED_Write_Cmd(0x00); // 暂不进行说明(后面会说明)
OLED_Write_Cmd(0x7F); // 暂不进行说明(后面会说明)OLED_Write_Cmd(0x2F); // 开启滚动
(程序效果图 )
TIPS:文中图片中白色文字的是SSD1306驱动芯片,蓝黄文字的是SSD1315驱动芯片,大家注意区分!
二、垂直滚动方法
1)SSD1306驱动芯片
而关于垂直滚动方法,用户手册没有进行详细的说明,但是还是被我找到了方法!!!大家仔细看我下面的代码注释,就会明白了!!!
OLED_Write_Cmd(0x2E); // 先必须关闭滚动
OLED_Write_Cmd(0x29); // 0x29是垂直水平向右滚动,0x2A是垂直水平向左滚动
OLED_Write_Cmd(0x00); // 虚拟字节
// 选择要作用的页(0~7)【除去这个范围的页,其余全都是垂直移动--若开启】
OLED_Write_Cmd(0x00); // 起始页 0
OLED_Write_Cmd(0x07); // 滚动时间间隔
OLED_Write_Cmd(0x07); // 终止页 7
OLED_Write_Cmd(0x01); // 垂直滚动偏移量OLED_Write_Cmd(0x2F); //开启滚动
注意上文红色标注,只要将起始页和终止页都设为0x00,则除去(0~0)PAGE范围外都是垂直移动,则整个屏幕文字就会垂直移动,但目前没有办法使屏幕向下垂直运动!
2)SSD1315驱动芯片
同上所理,但不同的是SSD1315驱动芯片方法中,在开启滚动命令前的两个字节正好是对滚动列进行设置的,而SSD1315的垂直滚动比SSD1306控制更为细节,大家仔细看我的代码注释!!!
OLED_Write_Cmd(0x2E); // 先必须关闭滚动
OLED_Write_Cmd(0x29); // 0x29是垂直水平向右滚动,0x2A是垂直水平向左滚动
OLED_Write_Cmd(0x01); // 0x00 水平滚动关闭,0x01 水平滚动开启OLED_Write_Cmd(0x00); // 起始页 0
OLED_Write_Cmd(0x07); // 滚动时间间隔
OLED_Write_Cmd(0x07); // 终止页 7
OLED_Write_Cmd(0x01); // 垂直滚动偏移量
// 选择要作用的列【除去这个范围的列,其余全都是垂直移动--若开启】
OLED_Write_Cmd(0x00); // 第0列开始
OLED_Write_Cmd(0x7F); // 第127列结束OLED_Write_Cmd(0x2F); // 开启滚动
注意上文红色标注,只要将文中标紫的部分都换成发送0x00,则除去(0~0)列范围外都是垂直移动,则整个屏幕文字就会垂直移动,但目前没有办法使屏幕向下垂直运动!
三、局部区域垂直水平滚动方法
1)SSD1306驱动芯片
有了前面的铺垫,咱们要实现局部区域垂直水平滚动就很简单了,我们瞧瞧一下官方手册里的A3命令,这可以实现部分区域进行垂直水平滚动,并结合代码我们来详细看看:
OLED_Write_Cmd(0x2E); // 先必须关闭滚动
OLED_Write_Cmd(0x29); // 0x29是垂直水平向右滚动,0x2A是垂直水平向左滚动
OLED_Write_Cmd(0x00); // 虚拟字节// 水平滚动的区域将会发生在被选用的区域①
OLED_Write_Cmd(0x00); // 起始页 0
OLED_Write_Cmd(0x07); // 滚动时间间隔
OLED_Write_Cmd(0x05); // 终止页 5
OLED_Write_Cmd(0x01); // 垂直滚动偏移量// 选择要作用的行(0~15)【除去这个范围的行,其余全都是水平移动--若开启】
// 垂直滚动的区域将会发生在被选用的区域②
OLED_Write_Cmd(0xA3); //选择行区域命令
OLED_Write_Cmd(0x00); //第0行开始
OLED_Write_Cmd(0x0F); //第15行结束OLED_Write_Cmd(0x2F); //开启滚动
从上述代码可以看到,区域①中控制是水平滚动,区域②控制的是垂直滚动,所以两个区域重叠的部分就是垂直水平滚动,而其余部分不会发生任何滚动变化,为了便于理解,结合上述代码,我手绘一张图进行讲解:
2)SSD1315驱动芯片
相比于SSD1306驱动芯片而言,SSD1306驱动芯片对区域性的垂直滚动可以控制得更加灵活,也可以控制得更加精准,增加了对屏幕列区域的滚动控制,同样,我们来瞧瞧官方手册里的A3命令,并结合详细代码来详细看看:
OLED_Write_Cmd(0x2E); // 先必须关闭滚动
// 选择要作用的行(0~63)【除去这个范围的行,其余全都是水平移动--若开启】
// 垂直滚动的区域将会发生在被选用的区域②OLED_Write_Cmd(0xA3); //选择行区域命令
OLED_Write_Cmd(0x00); //第0行开始
OLED_Write_Cmd(0x0F); //第15行结束OLED_Write_Cmd(0x29); // 0x29是垂直水平向右滚动,0x2A是垂直水平向左滚动
OLED_Write_Cmd(0x01); // 0x00 水平滚动关闭,0x01 水平滚动开启// 水平滚动的区域将会发生在被选用的区域①
OLED_Write_Cmd(0x00); // 起始页 0
OLED_Write_Cmd(0x07); // 滚动时间间隔
OLED_Write_Cmd(0x05); // 终止页 5
OLED_Write_Cmd(0x01); // 垂直滚动偏移量
// 选择要作用的列【除去这个范围的列,其余全都是垂直移动--若开启】
// 水平滚动的区域将会发生在被选用的区域①
OLED_Write_Cmd(0x00); // 第0列开始
OLED_Write_Cmd(0x3F); // 第63列结束OLED_Write_Cmd(0x2F); // 开启滚动
从上述代码可以看到,区域①中控制是水平滚动,区域②控制的是垂直滚动,所以两个区域重叠的部分就是垂直水平滚动,而其余部分不会发生任何滚动变化,相比于SSD1306,SSD1315增加了区域①的列选取,所以相较而言复杂一点,同样,为了便于理解,结合上述代码,我手绘一张图进行讲解:
四、详细部分代码
// 0.96寸OLED内部驱动芯片是SSD1306(有些SSD1315)--- 在屏幕滚动指令上有区别
#define DRIVER_CHIP 1306
/**
* @brief OLED_Inside_ver_sroll,内部设置垂直水平滚动
* @param start_page,end_page :起始滚动页与终止滚动页(start_page:0~7, end_page:0~7);
* scroll_offset : 垂直偏移量
* frame : 每个滚动步骤之间的时间间隔,以帧为单位,越大越慢(FRAME_2 ~ FRAME_128)
* dir : 1 垂直并向右滚动, 0 垂直并向左滚动
* @retval 无
*/
void OLED_Inside_Ver_Hor_Sroll(uint8_t start_page,uint8_t end_page,uint8_t scroll_offset,Roll_Frame frame, uint8_t dir)
{
#if (DRIVER_CHIP == 1315)
// 先必须关闭滚动
OLED_Write_Cmd(0x2E);
// 选择要作用的行(0~63)【除去这个范围的行,其余全都是水平移动--若开启】
// 垂直滚动的区域将会发生在被选用的区域
OLED_Write_Cmd(0xA3); //选择行区域命令
OLED_Write_Cmd(0); //第0行开始
OLED_Write_Cmd(0x3F); //第63行结束
// 1是垂直水平向右滚动,0是垂直水平向左滚动
OLED_Write_Cmd(dir ? 0x29 : 0x2A);
//虚拟字节(最低为1,水平滚动开启)
OLED_Write_Cmd(0x01);
// 水平滚动的区域将会发生在被选用的区域
OLED_Write_Cmd(start_page & 0x07); //起始页 0
OLED_Write_Cmd(frame & 0x07); //滚动时间间隔
OLED_Write_Cmd(end_page & 0x07); //终止页 7
OLED_Write_Cmd(scroll_offset & 0x07); //垂直滚动偏移量
// 选择要作用的列【除去这个范围的列,其余全都是垂直移动--若开启】
// 水平滚动的区域将会发生在被选用的区域
OLED_Write_Cmd(0x00); //第0列开始
OLED_Write_Cmd(0x7F); //第127列结束
OLED_Write_Cmd(0x2F); //开启滚动
#else
// 先必须关闭滚动
OLED_Write_Cmd(0x2E);
// 1是垂直水平向右滚动,0是垂直水平向左滚动
OLED_Write_Cmd(dir ? 0x29 : 0x2A);
//虚拟字节
OLED_Write_Cmd(0x00);
// 选择要作用的页(0~7)【除去这个范围的页,其余全都是垂直移动--若开启】
// 水平滚动的区域将会发生在被选用的区域
OLED_Write_Cmd(start_page & 0x07); //起始页 0
OLED_Write_Cmd(frame & 0x07); //滚动时间间隔
OLED_Write_Cmd(end_page & 0x07); //终止页 7
OLED_Write_Cmd(scroll_offset & 0x07); //垂直滚动偏移量
// 选择要作用的行(0~63)【除去这个范围的行,其余全都是水平移动--若开启】
// 垂直滚动的区域将会发生在被选用的区域
OLED_Write_Cmd(0xA3); //选择行区域命令
OLED_Write_Cmd(0x00); //第0行开始
OLED_Write_Cmd(0x3F); //第63行开始
OLED_Write_Cmd(0x2F); //开启滚动
#endif
}
总结
本系列所用单片机型号为STM32F103VE,后续我会把本节所涉及的工程及相关资料放在评论区,大家自取!请大家多多点赞、多多收藏、感谢支持!!!我会继续输出优质内容的!!!加油!加油!🌸🌸🌸