stm32汉字字库显示实验与OLED的使用
1.字库的使用
2.OLED的使用:
1)OLED通用的初始化流程:
不论是使用I2C协议还是SPI协议,或者是6800和8080的并口协议进行通讯,OLED初始化的通用流程都如下图所示:
2)原子OLED屏芯片SSD1306的部分指令集
-
注意:当我们发送列地址时,列地址会被拆分成两个字节发送,注意列地址(1个字节)的高四位发送时需要在其前面加上0X10,以便让OLED芯片能识别到我们发送的这个命令是列地址的高四位 ,实际上第四位发送时也加上了0x00,不过,这个0x00加上去没有显示出来而已。 -
有些驱动芯片是在列地址开始是有偏移量的,如洋桃使用SH1106具有0X02的起始偏移(列地址加上即可)。 -
OLED驱动芯片中,将0.96寸的OLED上的点阵对应成内部的SRAM上的每个位,(纵向下高位的模式)安排字节,即,0.96寸的OLED上是 64*128个像素点,将其8个像素点一行,分成8个大行,对应内部SRAM的8页(B0-B7)一页有128个字节,这128个字节是”竖着放的“,即每个字节对应一列,每个字节中的每个位(bit)对应每个大行中中的1个像素点 。 OLED驱动芯片的显示SRAM对应如下:(分页,及下高位取模) 将每个页放大的下高位取模如下: -
因此对于这样的芯片,就有以下两种不同的显示方式:
-
洋桃的方法: 显示时,为了方便,不用在不同页之间来回切换,取模方式使用: **从左往右,再从上到下 ** (因为从左往右在同一页) 纵向取模下高位 。(这样取模得到得点阵可以直接显示,较方便) -
原子的方法: 现在单片机内部定义一个二维数组BUFFER,大小于SRAM相同;每次画点时都是往这个SRAM上置位,最后将这个SRAM一次性更新到OLED内部的SRAM上(更新方式于第一种方法相同)。(好处时,取模方式没有限制,可以兼容多种取模方式,画点时也比较快,不用每次画点都需要重新与OLED发起通讯,坏处是对单片机的SRAM要求比较高,容量要足够大。而且需要记得在每次画点结束后都要调用SRAM的更新函数。)
3.小项目练习
这次没有过于探究底层的程序,关于i2c,和6800,8080协议,以及字库的生成,读取和查找,以后再做总结吧,(毕竟现在学的还很浅)。
主要是利用原子的图库和洋桃的OLED——i2c驱动显示函数(因为手头只有一个i2c驱动的OLED),将不同取模方式的进行转换会比较麻烦些,显示函数还比较好处理。(如果有涉及侵权问题,联系我删除)
主要自己写的三个函数如下:
OLED0561.里的三个函数:
主要是实现了字库功能,这样就不用每个想要的汉字都去取模了。
void OLED_Show_str(u8 row,u16 colon,u8* str,u8 mode)
{
u8 is_Hz=0;
u8 size =16;
while(*str!=0)
{
if(colon>=128)
{
row+=2*(colon/128);colon%=128;
if(row>=8)row%=8;
}
if(!is_Hz)
{
if(*str>0x80)is_Hz=1;
else
{
OLED_DISPLAY_8x16(row,colon,*str);
str++;
colon+=size/2;
}
}else
{
is_Hz=0;
OLED_Show_HZ(row,colon,str,mode);
str+=2;
colon+=size;
}
}
}
void OLED_Show_HZ(u8 x,u8 y,u8*ZH,u8 mode)
{
u8 i=0;
u8 j,t,c=0;
u8 dzk[32];
Get_HzMat(ZH,dzk,16);
for(i=0;i<32;i++)
{
if(mode)dzk[i] =~( char_revolve(dzk[i]) ) ;
else dzk[i] = char_revolve(dzk[i]);
}
for(t=0;t<2;t++)
{
I2C_SAND_BYTE(OLED0561_ADD,COM,0xb0+x);
I2C_SAND_BYTE(OLED0561_ADD,COM,y/16+0x10);
I2C_SAND_BYTE(OLED0561_ADD,COM,y%16);
for(j=0;j<16;j++)
{
if(t==0){c=2*j;}
else {c=2*j+1;}
I2C_SAND_BYTE(OLED0561_ADD,DAT,dzk[c]);
}x++;
}
I2C_SAND_BYTE(OLED0561_ADD,COM,0xAF);
}
static u8 char_revolve(u8 temp_char)
{
u8 result=0;
u8 i=0;
u8 Mask_bit=0x01;
for(i=0;i<8;i++)
{
if(temp_char&0x80)result|=Mask_bit;
temp_char<<=1;
Mask_bit<<=1;
}
return result;
}
主函数中实现了个小弹幕:原理不难。同时也将OLED_Show_str()函数置于USMART中,供串口调用,有兴趣的同学可以试试看:
代码仓库的连接如下:(仓库中的Project4,之前忘了用分支把练习项目分开了)使用正点原子精英板,插SD卡(提供字库,FLASH内有的则不需要),I2C驱动的0.96寸OLED屏。
ZET6小项目: 是学习stm32zet6时做的一些小项目练习。 (gitee.com)
效果如下:
|