banyai的笔记 https://bbs.21ic.com/?88351 [收藏] [复制] [RSS]

日志

利用STM32的USART、DMA和SPI编写汉字库

已有 2805 次阅读2011-3-19 02:30 |系统分类:单片机| STM32, USART, DMA, SPI, W25X80

     在嵌入式系统中,我们经常会用到汉字,用来液晶显示或打印机打印。那么我们就需要一个汉字库来保存汉字的信息。我用STM32来实现了通过STM32的串口从PC机上传送到STM32,并通过STM32的DMA通道及SPI接口向W25X80写入汉字库,通过这个方法,可以在没有支持W25X80的编程器情况下,写入汉字库。也可向它编写一些其它的信息。分享一下:
      一、汉字显示原理:
            要在点阵式液晶上显示一个汉字,其实就是显示一小块图形,跟据字体的大小,可以分为12X12,16X16,24X24等,例如下图:
                                  
       显示这个汉字时,用了横向16X纵向16个点阵,把和字相应的点显示,其它的点不显示,就能把这个字展现出来了。
       在这里,我们还有一个非常关键的问题,就是取模方式,就是怎么来保存这个字的数据。在常用的单色点阵液晶上,显示数据都是以8位字节方式的,所以我们在保存字的数据时,也采用8位方式,但这样也有很多种方法,比如:横向8点右高位;横向8点左高位;纵向8点上高位;纵向8点下高位。而字节排列一般是从左到右,从上到下。因为一个汉字是16X16,所以有256个点,用字节存储的话,就需要32个字节。在这里,我们按其中一种方法取模,例如,采用横向8点右高位,就是指从左向右取点,左边是低位(D0),右边是高位(D7)。这时,取到的字节分别是:0x00,0x00,0xfc,0x1f,0x00,0x10,.....;采用纵向8点下高位时,就是指从上到下取点,上面是低位,下面是高位,这时,取到的字节分别是:0x00,0x00,0x82,0x92,...;
       那么我们应该选择哪种取模方式呢?这取决于你所选的液晶或打印机。例如:在一块以ST7565P的控制芯片为主的128X64的液晶上,它的显示RAM的排列方式为纵向8点下高位,那么汉字取模时,也采用同样的方式就可以,如果采用的方式不一样,那就需要在显示时,通过处理器进行转换。
      二、什么时候采用汉字库及存放读取方式
            汉字库是存放了所有常用汉字点阵的库,按GB2312标准的库,共有大概87(区)X94(位)个汉字及符号(88~94区没有汉字),那么它需要87X94X32/1024 = 255.56KB,通常我们用256KB来保存这个字库。
            当需要显示的汉字会发生变化或要显示的汉字很多时,需要用到汉字库,比如:可以通过用户设定一些信息(通信录之类的操作)。如果显示是固定的,不可更改,那么就不需要用到汉字库,只需要将要显示的汉字通过一些软件(比如HZDotReader)提取出来, 并改成源代码的形式(结构体数据之类),编译后,固化在FLASH中即可。 
            现在的微处理器的FLASH越来越大,有些超过1MB,用它来保存字库也是一种选择,但FLASH越大,价格也会越高,而且很多微处理器并没有那么大的FLASH,所以一般,我们把字库放在外扩的数据FLASH中。W25X80是一种具有1MB大空间,且价格便宜的SPI接口FLASH,前面256KB保存字库后,后面的空间还可以用来保存数据。并且它有DIP8封装,当产品发生故障时,可以很方便的取下来,放在新的产品上,按原先保存的数据继续工作。 
             有了汉字库,我们就需要确定需要显示的汉字点阵的位置,并把它们读出来。在程序中,我们通常位采用汉字内码或区位码来表示一个汉字,比如unsigned char *p = "灵",这时指针p指向了一个存放"灵"这个字的FLASH空间的起始地址,共3个字节组成:0xc1,0xe9,0x00。前两个是灵这个汉字的汉字内码:0xc1e9的高8位和低8位,最后一个0x0是字符串的结束字符。汉字内码-0xa0a0=区位码,如灵字的区位码是0x2149,区码0x21(十进制:33),位码0x49(十进制:73)。汉字点阵的起始地址=((区码-1)X 94 + (位码-1)) X 32。 从这个地址开始,读取32个字节,就是字的点阵。   


                                                                        (未完待续)
       


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)