打印
[技术讨论]

百问LCD Framebuffer应用开发 - 操作原理

[复制链接]
30|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
神棍地海棠|  楼主 | 2024-11-25 10:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1.4 在LCD上使用点阵写字[color=var(--c-text-accent)][size=0.85em]#1.4.1 在LCD上显示英文字母
①找出英文字母在点阵数组中的地址,c所代表的是一个英文字母(ASCII值)。
程序文件:show_ascii.c
[backcolor=var(--code-bg-color)]4693                unsigned char *dots = (unsigned char *)&fontdata_8x16[c*16;
[color=var(--code-ln-color)]


②根据获得的英文字母点阵,每一位依次判断,描点,‘1’表示白色,‘0’表示黑色。
​ 根据上图,我们分析下如何利用点阵在LCD上显示一个英文字母,因为有十六行,所以首先要有一个循环16次的大循环,然后每一行里有8位,那么在每一个大循环里也需要一个循环8次的小循环,小循环里的判断单行的描点情况,如果是1,就填充白色,如果是0就填充黑色,如此一来,就可以显示出黑色底,白色轮廓的英文字母。
程序文件:show_ascii.c
[backcolor=var(--code-bg-color)]4697                for (i = 0; i < 16; i++)4698                {4699                        byte = dots[i;4700                        for (b = 7; b >= 0; b--)4701                        {4702                                if (byte & (1<<b))4703                                {4704                                        /* show */4705                                        lcd_put_pixel(x+7-b, y+i, 0xffffff); /* 白 */4706                                }4707                                else4708                                {4709                                        /* hide */4710                                        lcd_put_pixel(x+7-b, y+i, 0); /* 黑 */4711                                }4712                        }4713        }
[color=var(--code-ln-color)]


















③调用我们编写的lcd_put_ascii函数
程序文件:show_ascii.c
[backcolor=var(--code-bg-color)]4743 lcd_put_ascii(var.xres/2, var.yres/2, 'A'); /*在屏幕中间显示8*16的字母A*/
[color=var(--code-ln-color)]


④编译c文件show_ascii.c
编译命令:arm-linux-gnueabihf-gcc -o show_ascii show_ascii.c
⑤将编译出来的show_ascii传输到开发板,并进入show_ascii的目录下
执行命令:./show_ascii
如果实验成功,我们将看到屏幕中间会显示出一个白色的字母‘A’。
[color=var(--c-text-accent)][size=0.85em]#1.4.2 在LCD上显示汉字
​ 与显示英文字母有点不同,因为汉字的点阵我们是需要通过汉字库提取出来,并没有直接提供点阵数组,因此我们程序开头需要打开汉字库文件(HZK16),然后再找到相应的位置,提取出汉字的点阵,最后再按显示英文字母一样显示它,不过这个汉字是16*16的。
① 打开汉字库文件
程序文件:show_font.c
[backcolor=var(--code-bg-color)]4760        fd_hzk16 = open("HZK16", O_RDONLY);
[color=var(--code-ln-color)]


② 获取汉字库文件的属性,存在hzk_stat结构体变量中
程序文件:show_font.c
[backcolor=var(--code-bg-color)]4793        if(fstat(fd_hzk16, &hzk_stat))
[color=var(--code-ln-color)]


此处主要是用知道该文件的大小,因为后面mmap时需要知道映射的文件大小。
③使用mmap系统调用
程序文件:show_font.c
[backcolor=var(--code-bg-color)]4798        hzkmem = (unsigned char *)mmap(NULL , hzk_stat.st_size,                                 PROT_READ, MAP_SHARED, fd_hzk16, 0);
[color=var(--code-ln-color)]


hzkmem与fbmem类似,也是一个指向映射内存的指针,但是它是指向汉字库,方便
后续计算汉字点阵偏移位置用。
④使用汉字库,调出点阵显示汉字
​ HZK16 字库是符合GB2312标准的16×16点阵字库HZK16的编码,每个字需要32个字节的点阵来表示,例如我们将要显示的‘中’字,编码是D6D0,难道就是2个字节表示吗?不是说32字节吗?D6D0编码是一个类似于索引码,D6是区码,D0是位码,先要找到D6-A1才是真正区,在D6-A1区里找到D0-A1的真正位置,这才是‘中’字点阵的起始位置(减去A1是为了兼容ascii),每一个区有94个汉字。
程序文件:show_font.c
[backcolor=var(--code-bg-color)]4734                unsigned int area  = str[0 - 0xA1;4735                unsigned int where = str[1 - 0xA1;4736                unsigned char *dots = hzkmem + (area * 94 + where)*32;
[color=var(--code-ln-color)]




​ 上图是汉字点阵排布的示意图,总共有十六行,因此需要一个循环16次的大循环,考虑到一行有两个字节,我们大循环中加入一个循环2次的循环用于区分是哪个字节,最后判断当前字节的每一位,如果为 ‘1’描白色,如果为‘0’描黑色
程序文件:show_font.c
[backcolor=var(--code-bg-color)]4740        for (i = 0; i < 16; i++)4741                        for (j = 0; j < 2; j++)4742                        {4743                                byte = dots[i*2 + j;4744                                for (b = 7; b >=0; b--)4745                                {4746                                        if (byte & (1<<b))4747                                        {4748                                                /* show */4749                                                lcd_put_pixel(x+j*8+7-b, y+i, 0xffffff); /* 白 */4750                                        }4751                                        else4752                                        {4753                                                /* hide */4754                                                lcd_put_pixel(x+j*8+7-b, y+i, 0); /* 黑 */4755                                        }        4756                                }4757                        }
[color=var(--code-ln-color)]



















⑤调用我们编写的lcd_put_chinese函数
程序文件:show_font.c
[backcolor=var(--code-bg-color)]4810        printf("chinese code: %02x %02x\n", str[0, str[1);4811        lcd_put_chinese(var.xres/2 + 8,  var.yres/2, str);
[color=var(--code-ln-color)]



⑥编译c文件show_font.c
编译命令:arm-linux-gnueabihf-gcc -o show_font show_font.c
注:使用此命令HZK16文件必须与show_font.C在同一目录下。
⑦将编译出来的show_font传输到开发板,并进入show_font的目录下
执行命令:./show_font
如果实验成功,我们将看到屏幕中间会显示出一个白色的字母‘A’与汉字‘中’,同时在串口打印信息中看到‘中’对应的编码。
chinese code: d6 d0
[color=var(--c-text-accent)][size=0.85em]#1.5 搭建freetype相关环

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

270

主题

278

帖子

0

粉丝