切换到宽版
  • 12629阅读
  • 50回复

[C51]恭祝坛友们新春快乐!用STC15W4K48及W25Q16,采用土办法编写OLED用的显示字库。 [复制链接]

上一主题 下一主题
离线落叶风
 

发帖
1326
M币
7247
专家
205
粉丝
19518
— 本帖被 發騷友 设置为精华,作者+3000M币+5专家(2018-02-20) —
今天是年初一,恭祝坛友们新春快乐!狗年吉祥,万事如意,身体健康,财运旺旺,有更多的高科技成果出现。今年回乡下过年,无聊,把年前未完工的DIY的部份东西整理一下,把本人显示字库的制作方法整理好,并发出来。

这次编写字库的主要原因是打算升级VFD多功能闹种,


想增加电源控制音频控制等功能,由于单片机空间有限,程序超出了单片机空间,所以才想把显示的字库移到W25Q16中,由于网上没有找不到合适的字库,手头上也没有W25Q16的编程器,网上的字库生成软件找不到破解板,所以采用土办法编写,由于VFD显示不通用,所以在这又制作比较常用的OLED显示字库,把制作过程发出来供坛友参考。
本次制作是采用实验板及IIC总线的OLED显示器及W25Q16芯片进行制作,硬件如下图,




实验板电路图如下,OLED的时钟脚接P21,数据脚接P22,W25Q16的DO脚接 P0^3,DIO 脚接P0^5,CLK 脚接P0^4,CS脚接 P0^2,HOLD及WP接3.3V电源,注意W25Q16供电不能超3.6V。



以下为完成的效果图。
下图为9个区里取一个字或最后个字把它显示出来。在校验字库是否正确时,需显示的内容一样才对。


以下为ASII字库。


以下为唐诗一首。



以下为本人字库的制作方法,比较土,能用。
先在网上下载GB2312字库表,在压缩包文件夹里GB2312编码范围.txt文件就是,由于它是带说明的,字的顺序不连续,所以需把没用的字清空,如用手工清理太麻烦,而且容易出错,所以用易语言写一个小工具,把文字提取出来(如下图),



并进行整理,然后按照表的顺序,分成每1024个编码为一组(在每个32K区程序内的TXT文件就是整理好的文字,不要改动它。),主要是由于是采用STC15W4K48写入W25Q16,由于单片机内部程序空间只有48K,每个显示汉字是用16*16,即需32B,1024个字的编码占了32K,为了方便操作,所以1024个字为一组,汉字编码是有90多区,即9K多个字,所以需分9组,别加ASII编码(16*8,8*8两种显示)占用一组,所以共10组,即需写入单片机十次。

以下按第一区32K的编写过程作介绍,其它区是一样的,由于GB2312是从0100开始的,所为了简化计算,所以第一组补00-99空值。。第9区由于只有607个字,所以需补416个空位。

打开第一区32K的程序文件,里面有个文字编码表1.txt,这个文件是已排列好的字,只需在字模提取软件提取出来就行了。字模提取软件是PCtoLCD2002完美版,本显示字库是宋体16*16,OLED显示的字是列行式逆向,需在设置好相对应的参数,如下图,


点导入文本,导入文字编码表1.txt,然后生成,保存在编码表.txt中,然后打开它,检查一下是不是1024个字的编码,


如没错就全选,复制到第一区程序里面的unsigned char code DISPdat16X16[],


然后生成hex文件就行了,然后写入单片机,运行一下,通过串口输出检查一下对应的文字数据是否正确,如正确(3个连续的0XFF为引导码,用来区分每次传出的数据),就完成这区的写入。如些方法运行十次。就完成字库的编码,然后再运行一下字库显示测试,在开始位置演示的图片,看看是否一样,如正确,就完成本字库的制作。第一区到第九区是汉字宋体显示字库,第十区ASII由于只有8*8及16*8的显示字库。以上是制作字库的方法,可以扩展到制作其它字库。压缩包内的程序是已做好宋体OLED显示字库,如需制作其它的字库只需改动程序里的DISPdat16X16里的值就行了。

以下为字库的使用方法,本程序的字库是宋体汉字,尺寸16*16,以及ASII的8*8及16*8。输入汉字后,取出汉字2位编码,分别减去0XA0,前位*100,再加后位,就是这个汉字的GB2312的地址,由于每个汉字显示占用32B,所以当前汉字显示数据开始地址为GB2312编码地址*32。对于ASII的8*8显示数据开始地址为ASII*8+0x048000  ASII的8*8显示数据开始地址为ASII*16+0x048400。
本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
本帖最近打赏记录:共17条打赏M币+237专家+2
12
关键词: OLED字库
离线落叶风

发帖
1326
M币
7247
专家
205
粉丝
19518
只看该作者 1楼 发表于: 02-16
     在这对程序一些关键东西说明一下,主要是对驱动W25Q16。
      本次W25Q16是8脚的,各管脚的说明:5脚(DIO):在普通方式下,这个引脚是串行输入引脚(DI),数据、地址和命令通过此引脚送到芯片内部,在CLK引脚的上升沿捕获。当使用了“快读双输出指令”时,这个引脚就变成了DO引脚,这种情况下,芯片就有了2个DO引脚,所以叫做双输出,这时芯片的通信速度相当于翻了一倍,所以传输速度更快。
     7脚(/HOLD):保持引脚,当/CS片选为低电平,且HOLD为低电平时,DO引脚处于高阻态,而且会忽略DIO和CLK引脚上的信号,把HOLD拉高,器件恢复正常工作,当芯片与多个其它芯片共享单片机上的同一个SPI接口时,此引脚就显得非常有用,通常此引脚接高电平保证芯片正常工作。
   3脚(/WP):写保护,低电平保护状态寄存器不被改写
   1脚(/CS):片选,低电平工作,高电平时DO脚高阻
    2脚(DO):数据输出,下降沿输出
    w25的端口兼容5伏的。用个1117--3.3V的就能共用5V,或5V的用两个二级管降压后得3.6V也和3.3V很接近可以用。
    W25X16的最大地址值是1FFFFFH,24位地址高3位固定为0(W25X64才需用到最高3位)
   W25X16分为8192页,每页256字节,用“页编程指令”每次就可以编程256字节,用“扇区擦除指令”每次可擦除16页,用“块擦除指令”每次可擦除256页,  用“整片擦除指令”可一次擦除整个芯片,W25X16有512个可擦除扇区或32个可擦除块。
     对于W25X16,1页=256字节,归纳一下,1页=256字节   1扇区=16页=16*256字节=4096字节  (W25X16有512个扇区)。1块=256页=256*256字节=65536字节 (W25X16有32块)。
    W25X16内部状态寄存器(上电复位时,各位都被清零)    7  SPR    6 保留位(0) 5 TB   4 BP2   3 BP1  2 BP0    1 WEL   0 BUSY
    BUSY忙位:只读位,在芯片执行“页编程”,“扇区擦除” 、“块擦除”、 “芯片擦除”、 “写状态寄存器”指令时,该位自动置1,此时除了“读状态寄存器”指令,其它指令都无效,当编程、擦除和写状态寄存器指令执行完毕后,该为自动变0,表示芯片可以接收其它指令了。
    WEL写保护位:只读位,写操作允许标志位,当执行完写使能指令后,该位为1表示允许写操作,为0表示禁止写,当芯片掉电后或执行写禁止、页编程、扇区擦除、块擦除、芯片擦除和写状态寄存器命令后自动进入写保护状态。
    W25X16包括15个基本指令,通过这15个基本指令与SPI总线就完全可以控制芯片,指令在/CS拉低后开始传送,DIO引脚上数据的第一个字节就是指令码,在CLK引脚的上升沿采集DIO数据,高位在前。
    本次程序主要用到擦除4KB空间、写允许(将WEL置位)、读寄存器参数、写入页数据、读出数据。详细看程序,程序有说明。
以下为W25Q16的模拟SPI读写程序,这个比较简单,如下:
写子程序,就是在时钟上升沿把数据一位一位送到W25Q16。
void W25Qxxwritebyte(unsigned char temp)//写数据
{
    unsigned char i;
    for(i=0;i<8;i++)
      {
            W25Qxx_CLK=0;
            W25Qxx_DIO=temp&0x80;//先入第一位数据,后再时钟为高,延时一下再低,如此循环8次。
        W25Qxx_CLK=1;
      temp=temp<<1;
      }      
}    
读子程序
unsigned char W25QxxReadByte()
{
    unsigned char i,tempdat=0;
    for(i=0;i<8;i++)
      {
        tempdat=tempdat<<1;
          W25Qxx_CLK=0;
        if(W25Qxx_DO==1)tempdat=tempdat+1;//
        W25Qxx_CLK=1;
      }
    return (tempdat);
}

有了读写程序后,就按照W25Q16的芯片说明进行命令操作,在这只贴出写擦除4KB空间子程序,流程为先判断芯片是否忙,不忙的话就送写允许命令,拉低片选脚,再送整扇擦除命令,送3B的地址,再拉高片选脚,然后判断芯片是否忙等待完成。
void W25Qxx_SectorErase(unsigned long Addr24) //擦除4KB空间
{
    unsigned char Addr1;       // 最低地址字节
    unsigned char Addr2;       // 中间地址字节
    unsigned char Addr3;       // 最高地址字节  
    Addr1=Addr24;
    Addr24=Addr24>>8;
    Addr2=Addr24;
    Addr24=Addr24>>8;
    Addr3=Addr24;                      // 把地址拆开来  
    while(W25Qxx_ReadStatus()&0x01);   // 判断是否忙  
    W25QxxWriteEnable();                     // 写允许
    W25Qxx_CS=0;
    W25Qxxwritebyte(0x20);       // 整扇擦除命令
    W25Qxxwritebyte(Addr3);
    W25Qxxwritebyte(Addr2);
    W25Qxxwritebyte(Addr1);
    W25Qxx_CS=1;
    while(W25Qxx_ReadStatus()&0x01);   // 等待擦除完成
}
以上为主要程序的介绍,对于其它看程序。

字库的数据生成在上层已介绍,然后利用本层对芯片的驱动,就完成本字库的写入。
以下压缩包是个字库的程序及资料,程序的字库是宋体16*16,列行式逆向,在程序注释中有错,没记得改,由于水平有限,可能有BUG,仅供参考。



[ 此帖被落叶风在2018-02-16 22:52重新编辑 ]
本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
本帖最近打赏记录:共10条打赏M币+138
离线elecfunwb

发帖
691
M币
2755
专家
8
粉丝
7
只看该作者 2楼 发表于: 02-16
坐等直播
字数补丁
离线维民所止

发帖
1152
M币
524
专家
2
粉丝
2
只看该作者 3楼 发表于: 02-16
床上明月光,疑时地上霜。
明显醉了。
本帖最近打赏记录:共1条打赏M币+1
离线by64214

发帖
2552
M币
6311
专家
0
粉丝
17
只看该作者 4楼 发表于: 02-16
恭祝坛友们新春快乐!  在假期中学习  在学习中快乐   能学习一下程序吗
离线温力口

发帖
54812
M币
164620
专家
434
粉丝
805
只看该作者 5楼 发表于: 02-16
谢谢分享。狗年大吉!
离线widjrerpfnvd

发帖
906
M币
1447
专家
5
粉丝
24
只看该作者 6楼 发表于: 02-16
这首诗亮的很,估计要精华呢

内容来自Android手机客户端

离线落叶风

发帖
1326
M币
7247
专家
205
粉丝
19518
只看该作者 7楼 发表于: 02-16
回 by64214 的帖子
by64214:恭祝坛友们新春快乐!  在假期中学习  在学习中快乐   能学习一下程序吗 (2018-02-16 17:57) 回 by64214 的帖子

已编写完成,已贴程序。
离线xiaomage

发帖
734
M币
3625
专家
5
粉丝
32
只看该作者 8楼 发表于: 02-16
新春快乐!经验所得,谢谢分享!
离线2545889167

发帖
12139
M币
9535
专家
275
粉丝
4641
只看该作者 9楼 发表于: 02-16
新春快乐!狗年吉祥
快速回复
限80 字节
如果您提交过一次失败了,可以用”恢复数据”来恢复帖子内容
 
上一个 下一个