单片机

lcd显示汉字——取模加显示

2019-04-14  本文已影响0人  你的优先级最高

1、显示汉字,有专门的的字库,但是汉字很多,每一个汉字都需要专门的编码,需要更大的存储空间存放字库,因此需要外部 flash

2、无论是汉字还是英文,显示的原理都是一样的——都是像素点的亮灭,显示出我们想要的形状,不同lcd的分辨率会有不一样。

像素点展示

3、如同上面一个汉字“实”,编码如下(阴码——1为亮,0为灭;阳码——1为灭,0为亮)

{0x08,0x20,0x30,0x21,0x20,0x21,0x21,0x22,0x28,0xE2,0x26,0x24,0xA0,0x28,0x60,0x30,

 0x2F,0xE0,0x20,0x30,0x20,0x28,0x20,0x24,0x20,0x22,0x28,0x21,0x30,0x20,0x00,0x00},/*"实",4*/

那么我们在显示的时候,在为1 的地方一个点就好,为0的地方就

0x08:——0000 1000,再看看第一张图片,从上往下找,第五个像素点就点亮

相应的,16 x 16 的汉字就需要16 x 16个像素点才能显示一个汉字,一个16进制数为8位,还差8位,因此需要两个16进制数才能显示一列的像素点。

4、取模软件使用的是:PCtoLCD2002完美版,软件界面如下图所示。主要设置字的大小就好就好,注意:在字的大小上面还有一个对应的英文大小,这个是取英文字母字模大小,但是,谁会去取英文字母的模呢,除非尺寸不和要求。

[PCtoLCD2002完美版界面图]

之后点击界面1 的齿轮,进行设置。怎么选择的取模方式,那么在写显示函数的时候就得使用相同的方式进行对像素点进行处理。

设置界面

1、阴码——1为亮,0为灭;阳码——1为灭,0为亮;

2、取模方式:怎么取的就怎么进行显示就好,如逐列式,就是一列一列读;像oled比较特殊,需要列行式,显示的时候也是八行显示像素点为一个阵列。

3、方向是哪个方向得看 ——取模走向,顺向就从上往下取;

4、C51时使用C语言取模的固定操作;

5、点阵大小就是最后生成的数组是多少个一行,如24,那么就是24个数据一行,剩下的就在下一行,这个不影响数据内容,只是最后你复制的时候需不需要进行改一下格式,好看一点而已,至于前缀后缀那些也只是最后生成的数组是什么样的。如下数据:
{0x08,0x20,0x30,0x21,0x20,0x21,0x21,0x22,0x28,0xE2,0x26,0x24,0xA0,0x28,0x60,0x30,0x2F,0xE0,0x20,0x30,0x20,0x28,0x20,0x24}, {0x20,0x22,0x28,0x21,0x30,0x20,0x00,0x00},/*"实",0*/
最后在数组里面使用的时候肯定要改一下格式而已,要不然如何使用。

5、程序源码

const unsigned char Word[100] = "实践班";//将取模的汉字全部放在这
const unsigned char WordCode[10][32] = {//汉字的模,一 一对应,不能乱了顺序
{0x08,0x20,0x30,0x21,0x20,0x21,0x21,0x22,0x28,0xE2,0x26,0x24,0xA0,0x28,0x60,0x30,
0x2F,0xE0,0x20,0x30,0x20,0x28,0x20,0x24,0x20,0x22,0x28,0x21,0x30,0x20,0x00,0x00},/*实",0*/
 
{0x00,0x04,0x7C,0xFC,0x44,0x04,0x47,0xF8,0x44,0x88,0x7C,0x88,0x00,0x02,0x09,0x02,
0x09,0x04,0xFF,0xC8,0x09,0x30,0x92,0x28,0x52,0x44,0x12,0x82,0x02,0x1F,0x00,0x00},/*"践",1*/
 
{0x21,0x08,0x21,0x0C,0x3F,0xF8,0x21,0x10,0x21,0x11,0x00,0x42,0x1F,0x84,0x00,0x18,
0xFF,0xE0,0x00,0x00,0x21,0x04,0x21,0x04,0x3F,0xFC,0x21,0x04,0x21,0x04,0x00,0x00},/*"班",2*/
};
 //显示一个汉字,16*16
void DisplayWord(u8 x0,u8 y0,u8 *buf)     
{
    u8 temp = 0,t1 = 0,i = 0,j = 0,x = x0,y = y0,num = 0;
    for(i=0;i<strlen((char *)Word);i++)
    {
        if(buf[i]==Word[i]&&buf[i+1]==Word[i+1])num = i/2;      //一个汉字占两个字节
    }
    for(i = 0;i < 32;i++)//32 是由于一列16 个像素点,需要两个编码才能控制一列,因此需要在32个8位编码
    {
        temp = WordCode[num][i];
        for(t1 = 0;t1 < 8;t1++)
        {               
            if(temp&0x80)LCD_Fast_DrawPoint(x,y,POINT_COLOR);//点亮一个像素点
            temp <<= 1;//依次找完
            y++;
            if(y >= y0 + 16)
            {
                y = y0;
                x++;//换列
            }
        }
    }
}
//显示汉字字符串,16*16
void DisplayStringWord(u8 x,u8 y,u8 *buf,u16 color)
{    
    u8 i = 0,j = 0, x1 = x, y1 = y;
    POINT_COLOR = color;
    
    for(i=0;i<strlen((char *)buf);i+=2)
    {
        DisplayWord(x1,y1,&buf[i]);
        x1 = x1 + 16;
    }
}

最后

如果你不理解上面的叙述,那么你可以将某个英文的编码找出来,然后按照顺序一个一个按照二进制进行排列,
如:上面 “实” 的编码

{0x08,0x20,0x30,0x21,0x20,0x21,0x21,0x22,0x28,0xE2,0x26,0x24,0xA0,0x28,0x60,0x30,
0x2F,0xE0,0x20,0x30,0x20,0x28,0x20,0x24,0x20,0x22,0x28,0x21,0x30,0x20,0x00,0x00}
0x08——0000 1000
0x20——0010 0000
.......
依次写完,你会理解像素点显示的奥秘

就这样写下来,你会发现,怎么有点像,好像之后一半,然后再组合下,在倒一下......,真的比较神奇。
当然最好的对象是数字——0,不信你自己试试看,试了之后再来理解我说的话,再看下文章,你会豁然开朗。

这个方法是出自我们创新班的一位大佬,我看他这样搞,我也试着这样做。
当然了,不同的显示屏的驱动代码不同,自然显示方式也有差异,因此,必须的参考代码中是怎么显示英文的,然后试着改怎么显示中文。

上一篇 下一篇

猜你喜欢

热点阅读