没有合适的资源?快使用搜索试试~ 我知道了~
嵌入式系统仿真实验第九讲1
资源详情
资源评论
资源推荐
嵌入式系统仿真实验第九讲
上一次我们在 LCD 上显示了 ASCII 字符,今天的实验,我们来看如何在 LCD
终端界面上显示汉字字符以及键盘驱动输入字符(上次的实验,不是键盘输入,
而是用串口终端模拟输入的)。
1
LCD
汉字字符显示
显示 ASCII 字符,我们用的 ASCII 字符点阵,这是在 bare metal programming(裸
机编程)阶段嵌入式系统工程师必备的技能,因为如果只是个简单的产品,我们
能节约一点硬件成本那都是很了不起的。如果我们能掌握一点汉字字符的显示原
理,不仅能帮助我们深入理解计算机的原理,还说不定在今后的工作中能发挥点
作用。
在使用汉字字符之前,我们简单介绍一下汉字的编码。早期的计算机是使用
英文的人发明的,所以刚开始是没有中文输入和显示的,后来有很多人研究中文
输入法和中文显示,包括联想的起底,也是靠倪光南院士他们当初做的汉卡发家。
要用汉字编码,先看看有哪些常见的汉字字符集编码:
GB2312 编码:1981 年 5 月 1 日发布的简体中文汉字编码国家标准。GB2312
对汉字采用双字节编码,收录 7445 个图形字符,其中包括 6763 个汉字。
BIG5 编码:台湾地区繁体中文标准字符集,采用双字节编码,共收录 13053
个中文字,1984 年实施。
GBK 编码:1995 年 12 月发布的汉字编码国家标准,是对 GB2312 编码的扩
充,对汉字采用双字节编码。GBK 字符集共收录 21003 个汉字,包含国家标准
GB13000-1 中的全部中日韩汉字,和 BIG5 编码中的所有汉字。
GB18030 编码:2000 年 3 月 17 日发布的汉字编码国家标准,是对 GBK 编码
的扩充,覆盖中文、日文、朝鲜语和中国少数民族文字,其中收录 27484 个汉字。
GB18030 字符集采用单字节、双字节和四字节三种方式对字符编码。兼容 GBK
和 GB2312 字符集。
Unicode 编码:国际标准字符集,它将世界各种语言的每个字符定义一个唯
一的编码,以满足跨语言、跨平台的文本信息转换。
目前的操作系统一般都支持 Unicode 编码,也就是再不会出现由于字符编码
格式造成的乱码问题出现,早期的时候汉字是双 8 位-两个字节的编码,而 ASCII
是 7 位编码,所以很多中文邮件之类的文档收发都会造成乱码出现,那时候出现
过很多的转码软件(我在九十年代做自由程序员的时候,就帮别人做过 BIG5 和
GB2312 码的互换程序),拿到现在这些软件就完全没有作用了,但在嵌入式系统
领域,低成本、高可靠性、高附加值都得靠软件来实现,即使后面我给大家讲到
bootloader 的移植,操作系统的移植,能否把系统裁剪得越小越高效可靠,是考
察一个嵌入式系统工程师基本功的关键,硬件的迭代有摩尔定律,但同等条件下,
嵌入式系统工程师的功底在产品竞争中往往取到了决定性的作用
。
早期,UCDOS 下使用的 HZK16 目前在嵌入式系统里面还有很多人在用。
HZK16 字库是一个符合 GB2312 标准的 16×16 点阵字库,HZK16 的 GB2312-80
支持的汉字有 6763 个,符 号 682 个。其中一级汉字有 3755 个,按声序排列,二
级汉字有 3008 个,按偏旁部首排列。这个字体文件大概 256K 字节大小。
HZK16 字库用 16×16 共 256 个点来显示一个汉字,也就是需要 32 个字节才
能显示一个汉字。在 GB2312 汉字编码表中,一个汉字由两个字节编码,其范围
为 A1A1~FEFE。比如 0xCEE4 这个编码,代表汉字“武”。高八位称为区码,从 A1-A9
为符号区,B0 到 F7 才是汉字区。每一个区有 94 个字符(注意:这只是编码的
许可范围,不一定都有字型对应,比如符号区就有很多编码空白区域)。低八位
为位码,表示该字在位区的位置。
区码:汉字的高字节,因为汉字编码是从 0xA0 区开始的,所以文件最前面
就是从 0xA0 区开始,要算出相对区码
位码:汉字的低字节,表示该字在位区的位置。
由此,我们可以算出一个汉字在 HZK16 中的绝对偏移位置:
offset=(94*(区码-1)+(位码-1))*32
注: 1、区码减 1 是因为数组是以 0 为开始而区码位码是以 1 为开始的;
2、(94*(区码-1)+位码-1)表示每个区 94 个字符排列,在该区内该字的位
码是处在第几个位置。
3、最后乘以 32,因为 hzk16 汉字库要用 16x16=256 位也就是 32 个字节
信息记录该字的字模信息,每一位二进制”0” 表示背景色,”1”表示显示色,
这样组成一个汉字的显示字模。
我们通过汉字的两字节编码(区码和位码),计算出它在字体文件 HZK16 中
存放的偏移地址就可以读取这 32 个字节的点阵信息,然后将它们画出来就可以
显示出中文字了。
比如“武”字,GB2312 的编码为 0x CEE4,那么“武”字在 hzk16 文件里面
存放的点阵信息的偏移地址就是(94*(0xCE-1)+0xE4-1)*32=0x098520,也就是从
0x098520 开始 32 个字节存放的是“武”的点阵信息。
明白了这个原理,我们就可以编程序了,字符文件我们目前还不能像大家在
有操作系统或者基础库的情况下对文件进行操作,我们只能选择两种方式,前面
我有介绍,一种用我前面编的二进制转 C 代码程序把 hzk16k(k 是楷体字模)文
件转成 C 语言字节数组,另一个方法就是 objcopy 命令生成.o 文件,然后在链接
文件数据段指明链接地址。
接着上次的程序,我们在 LCD 驱动文件 vid.c 里面加几个函数。
extern char _binary_hzk16s_start;
void lcd_put_pixel(int x, int y, int u_color)
{
int c;
c = get_color();
set_color(u_color);
set_pix(x,y);
set_color(c);
}
/* LCD 显示单个汉字
* x : 屏幕 x 轴的坐标
* y : 屏幕 y 轴的坐标
* word : 需要显示的汉字字符编码(两个字节)
* scale: 显示比例
*/
void lcd_show_single_chinese(int x, int y, unsigned char* word, int scale)
{
//汉字库 hzk16 的起初地址
volatile unsigned char *addr = &_binary_hzk16_start;
//一个汉字占 32 位数据
unsigned char buffer[32];
//一个汉字的点阵是 16*16
unsigned char val[256];
unsigned int offset,i,j,k,len;
/* 计算偏移地址 */
offset = (94*(unsigned int)(word[0]-0xa0-1)+(word[1]-0xa0-1))*32;
addr += offset;//首地址+偏移地址
//拷贝 32 个字节数据到 buffer 数组
for(i=0; i<32; i++,addr++)
{
buffer[i] = *addr;
}
/* 按顺序取出 32 个字节字模中的每一个二进制位,共 256 位,这个 0 或 1 放到 val 数
组 */
len = 0;
for(k=0; k<16; k++)
{
for(j=0; j<2; j++)
{
for(i=0; i<8; i++)
{
val[len++] = buffer[k*2+j]&(0x80 >> i);
}
}
}
/* 根据 val 数组里面的 0 或 1 点阵来设置对应坐标点象素的颜色 */
len = 0;
for (j = y; j < y+16; j++)
{
for (i = x; i < x+16; i++)
{
/* 根据点阵的某位决定是否描颜色 */
if (val[len++])
lcd_put_pixel(scale*i, scale*j, color);
剩余17页未读,继续阅读
Xhinking
- 粉丝: 25
- 资源: 320
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0