一、前言
本文仅作个人学习记录,非教程,内容不完整,仅供参考,请勿用于商业用途。
二、概述
实现OLED滚动显示多行字符串,效果如下,视频转gif不好看,实际没那么难看。OLED使用IIC通信。
三、原理
Note: 这里假定你们已经实现OLED显示
OLED的显存由8PAGE组成,把整块屏幕分成8份,写的时候也是一页一页地写。
OLED | 128bit | ||
64bit | PAGE0 | ||
PAGE1 | |||
PAGE2 | |||
PAGE3 | |||
PAGE4 | |||
PAGE5 | |||
PAGE6 | |||
PAGE7 |
流程图如下:
四、代码实现
uint16_t Page = 0; //OLED当前Page,默认从page0开始写
uint16_t *Page_Addr = &Page; //指针指向PAGE,用于传递Page的数值
uint8_t str0[21]; //保存8条字符串,,每行max 21pcs字符
uint8_t str1[21];
uint8_t str2[21];
uint8_t str3[21];
uint8_t str4[21];
uint8_t str5[21];
uint8_t str6[21];
uint8_t str7[21];
//连续写字符函数
//Page:当前要写的OLED Page str[]:写入的数据
void OLED_Printf(uint16_t *NowPage, uint8_t str[])
{
int n = 0;
switch(*NowPage)
{
case 0:
for(n=0;n<21;n++)
{
str0[n] = str[n]; //将数据转移进数组
}
OLED_ShowStr(1,*NowPage,str0,1); //OLED PAGE0显示字符串
break; //显示完退出switch循环
case 1:
for(n=0;n<21;n++)
{
str1[n] = str[n];
}
OLED_ShowStr(1,*NowPage,str1,1);
break;
case 2:
for(n=0;n<21;n++)
{
str2[n] = str[n];
}
OLED_ShowStr(1,*NowPage,str2,1);
break;
case 3:
for(n=0;n<21;n++)
{
str3[n] = str[n];
}
OLED_ShowStr(1,*NowPage,str3,1);
break;
case 4:
for(n=0;n<21;n++)
{
str4[n] = str[n];
}
OLED_ShowStr(1,*NowPage,str4,1);
break;
case 5:
for(n=0;n<21;n++)
{
str5[n] = str[n];
}
OLED_ShowStr(1,*NowPage,str5,1);
break;
case 6:
for(n=0;n<21;n++)
{
str6[n] = str[n];
}
OLED_ShowStr(1,*NowPage,str6,1);
break;
case 7:
for(n=0;n<21;n++)
{
str7[n] = str[n];
}
OLED_ShowStr(1,*NowPage,str7,1);
break;
//OLED写满7行后下面会将(*NowPage)置为8,便触发default
default:
for(n=0;n<21;n++)
{
str7[n] = str[n]; //新数组补到Page7
}
//要开始显示第9行时再刷新转移后的数组,当然没有9行,意思是满屏后还要显示
OLED_WR_CMD(0xb0); //选择Page0
OLED_WR_CMD(0x00); //选择列
OLED_WR_CMD(0x10);
for(n=0;n<128;n++) //清空Page0
{
OLED_WR_DATA(0x00);
}
OLED_ShowStr(1,0,str0,1); //显示Page0
OLED_WR_CMD(0xb1); //选择Page1
OLED_WR_CMD(0x00); //选择列
OLED_WR_CMD(0x10);
for(n=0;n<128;n++) //清空Page1
{
OLED_WR_DATA(0x00);
}
OLED_ShowStr(1,1,str1,1);
OLED_WR_CMD(0xb2); //选择Page2
OLED_WR_CMD(0x00); //选择列
OLED_WR_CMD(0x10);
for(n=0;n<128;n++) //清空Page2
{
OLED_WR_DATA(0x00);
}
OLED_ShowStr(1,2,str2,1);
OLED_WR_CMD(0xb3); //选择Page3
OLED_WR_CMD(0x00); //选择列
OLED_WR_CMD(0x10);
for(n=0;n<128;n++) //清空Page3
{
OLED_WR_DATA(0x00);
}
OLED_ShowStr(1,3,str3,1);
OLED_WR_CMD(0xb4); //选择Page4
OLED_WR_CMD(0x00); //选择列
OLED_WR_CMD(0x10);
for(n=0;n<128;n++) //清空Page4
{
OLED_WR_DATA(0x00);
}
OLED_ShowStr(1,4,str4,1);
OLED_WR_CMD(0xb5); //选择Page5
OLED_WR_CMD(0x00); //选择列
OLED_WR_CMD(0x10);
for(n=0;n<128;n++) //清空Page5
{
OLED_WR_DATA(0x00);
}
OLED_ShowStr(1,5,str5,1);
OLED_WR_CMD(0xb6); //选择Page6
OLED_WR_CMD(0x00); //选择列
OLED_WR_CMD(0x10);
for(n=0;n<128;n++) //清空Page6
{
OLED_WR_DATA(0x00);
}
OLED_ShowStr(1,6,str6,1);
OLED_WR_CMD(0xb7); //选择Page7
OLED_WR_CMD(0x00); //选择列
OLED_WR_CMD(0x10);
for(n=0;n<128;n++) //清空Page7
{
OLED_WR_DATA(0x00);
}
OLED_ShowStr(1,7,str7,1);
break;
}
(*NowPage)++; //PAGE值自加
//OLED写满8页,转移数组
if((*NowPage) > 7)
{
(*NowPage) = 8;
for(n=0;n<21;n++)
{
str0[n] = str1[n]; //PAGE1-->PAGE0
}
for(n=0;n<21;n++)
{
str1[n] = str2[n];
}
for(n=0;n<21;n++)
{
str2[n] = str3[n];
}
for(n=0;n<21;n++)
{
str3[n] = str4[n];
}
for(n=0;n<21;n++)
{
str4[n] = str5[n];
}
for(n=0;n<21;n++)
{
str5[n] = str6[n];
}
for(n=0;n<21;n++)
{
str6[n] = str7[n];
}
//至此,7PAGE数据转移完毕
}
}
五、后记
欸欸欸!!!你这哪是屏幕滚动啊?
噢,那种滚动是实时操作系统RTOS的范畴了吧,暂时不会。
嵌入式小白,有错请大佬指正,respect