点阵汉字显示
- 格式:doc
- 大小:30.00 KB
- 文档页数:3
C语⾔是如何⽤16点阵⽅法输出汉字的C语⾔是如何⽤16点阵⽅法输出汉字的?到⽬前为⽌,我们编写的C 程序,其⽤于⼈机交互的提⽰或菜单都是英⽂的,那么如何在没有汉化的Turbo C 集成开发环境下编制显⽰汉字的程序呢?解决这⼀编程问题,我们⾸先必须了解有关汉字编码及字库的知识。
根据对汉字使⽤频率的研究,可把汉字分成⾼频字(约100 个),常⽤字(约3000 个),次常⽤字(约4000 个),罕见字(约8000 个)和死字(约45000 个),即正常使⽤的汉字达15000 个。
我国1981 年公布了《通讯⽤汉字字符集(基本集)及其交换码标准》GB2312-80 ⽅案,把⾼频字、常⽤字、和次常⽤字集合成汉字基本字符集(共6763 个),在该集中按汉字使⽤的频度,⼜将其分为⼀级汉字3755 个(按拼⾳排序)、⼆级汉字3008 个(按部⾸排序),再加上西⽂字母、数字、图形符号等700 个。
汉字编码:区位码国家标准的汉字字符集(GB2312—80)在汉字操作系统中是以汉字库的形式提供的。
汉字库结构作了统⼀规定,即将字库分成94 个区,每个区有94 个汉字(以位作区别)每⼀个汉字在汉字库中有确定的区和位编号(⽤两个字节),这就是所谓的区位码(区位码的第⼀个字节表⽰区号,第⼆个字节表⽰位号,因⽽只要知道了区位码,就可知道该汉字在字库中的地址,每个汉字在字库中是以点阵字模形式存储的,如⼀般采⽤16×16点阵形式,每个点⽤⼀个⼆进位表⽰,存1 的点,当显⽰时,可以在屏上显⽰⼀个亮点,存0 的点,则在屏上不显⽰,这样把存某字的16×16 点阵信息直接⽤来在显⽰器上按上述原则显⽰,则将出现对应的汉字。
内码汉字使⽤两字节表⽰,国家制定了统⼀标准,称为国标码。
国标码规定,每个字节使⽤后⾯7 位,第⼀位为0。
为了区别于英⽂的ASCII 码,国标码在计算机上使⽤的时候,规定汉字每个字节第⼀位设置为1,以表⽰该两字节为汉字,称为内码。
点阵式汉字显示的制作作者:何奕飞来源:《职业·中旬》2009年第11期单片机是一门技术性和实践性很强的专业课程,必须通过一系列软硬件实验理论联系实际才能学懂学好。
它对学生的应用能力和自学能力有着较高的要求。
现在职业学校的教学中主要以“51系列”8位单片机为基础展开教学。
单片机应用及技术开发阶段,教师给出设计要求,由学生自行设计、安装电路,并编写程序。
主要是针对学生技师阶段的学习,在有些职业学校还未开展。
下面笔者以《点阵式汉字显示的制作》这一课题为例,讲述一下学生在技师阶段单片机学习中所应具备的知识和能力。
一、课题内容设计一汉字显示器,要求能在16*16点阵LED显示块上显示一汉字(且有四种显示方式),显示块用4个8*8LED数码显示器显示。
二、课题分析1.本课题所选用的CPU为AT89C51AT89C51是一种带4K字节闪烁可编程可擦除只读存储器的低电压,高性能CMOS 8位微处理器。
2.本课题选用的LED点阵为共阳极TBA22088H,采用动态扫描方式显示基本连接方式如下:16*16点阵显示器显示1个汉字,一行有16列,共有16行,需要用8*8的点阵显示器4块74LS373驱动器2块,单片机用P1口,P3.0~P3.3口,P2.4~P2.7口控制行驱动,每根线控制一行,故每次传送一行(2个数据)。
LED显示器的汉字显示器是由单片机从存储器中预先存储的“字形库”中取出相应的数据来显示汉字,每次选取一行,用P1口,P3.0~P3.3口,P2.4~P2.7口控制三极管9012的饱和与截止来控制显示器,提供行驱动电源,当输出高电压时就点亮了矩阵显示上的一行。
当选通某一行时,并对这一行中需要发光的二极管进行激励,然后对下一行继续进行上述步骤,当按一定的次序对所有行都进行扫描以后,可显示出一幅图画,只要图画刷新的周期小于人眼视觉残留时间,则就能形成一幅稳定不闪烁的图画。
3.本课题电源的控制如图1方式连接4.本课题采用上电自动复位方式,用12MHZ的晶振如图2。
单片机的16X16LED点阵式汉字电子显示屏的武汉理工大学《单片机课程设计》实验报告学号:0121018700318课程设计题目4个8x8点阵LED电子显示屏的设计学院物流学院专业物流工程班级物流ZY1001姓名宋金龙指导教师朱宏辉2013 年 6 月25 日武汉理工大学《单片机课程设计》报告武汉理工大学《单片机课程设计》实验报告摘要本设计是基于MCS-51的16x16点阵LED电子显示屏的设计,16x16的点阵共有256个发光二极管,我们采用动态扫描的显示方法,更节省锁存器也就节省了成本。
扫描驱动电路就可以实现多行(比如16行)的同名列共用一套驱动器。
具体就16x16的点阵来说,把所有同1行的发光管的阳极连在一起,把所有同1列的发光管的阴极连在一起(即我们采用共阳极的接法)。
采用扫描方式进行显示时,每一行和每一列都有一个行驱动器和列驱动器,各行的同名列和各列的同名行共用一个驱动器。
我们采用四个74LS273锁存器。
显示数据通常存储在单片机的存储器中,按8位一个字节的形式顺序排放。
编写点阵显示程序,利用proteus画出电路原理图并装入程序仿真调试,仿真成功后完成电路焊接并装入程序完成实物设计。
整个设计过程让我们学到许多实践知识!LED显示屏作为一种新型的显示器件,是由多个发光二极管按矩阵形式排列封装而成,通常用来显示时间、图文等信息,由点阵LED组成的汉字显示屏在工工程所应用非常广泛。
LED显示屏显示画面色彩鲜艳,立体感强,静如油画,动如电影,广泛应用于车站、码头、机场、商场、医院、宾馆、银行、证券市场、建筑市场、拍卖行、工业企业管理和其它公共场所。
在实际应用中的显示屏由于成本和可靠性的因素常采用一种称为动态扫描的显示方法。
本文设计的是一个室内用16x16的点阵LED图文显示屏,图形或文字显示有静止、移入移出等显示方式。
本设计是基于MCS-51单片机的16x16显示屏,其中包含了硬件、软件、调试等方案的设计。
24点阵汉字库可显示宋体(文件名:hzk24s),楷体(hzk24k),黑体(hzk24h),仿宋体(hzk24f),24点阵中文符号字库(hzk24T)用这个程序输出中文符号,需要打开24点阵中文符号字库(hzk24T),最好别输,要不麻烦#include<graphics.h>#include<stdio.h>#include<fcntl.h>#include<io.h>#include<stdlib.h>#include<conio.h>FILE *fp;main(){ int gd=DETECT,gm;/*图形屏幕初始化*/initgraph(&gd,&gm,"c:\\turboc2 ");setbkcolor(WHITE);openhzk24();puthz24(20,400,RED,"还是妹子嘿嘿",3,3); /*(x,y,color,"汉字内容",xk,yk),位置x,y,颜色,color,放大倍数显卡,yk*/getch();closegraph();}puthz24(int x,int y,int COLOR,char *s,int xk,int yk){char buffer[24][3];/*buffer用来存储一个汉字*/register m,n,i,j,o,p;unsigned char qh,wh;unsigned long offset;while(*s){ qh=*(s)-0xa0;/*汉字区位码*/wh=*(s+1)-0xa0;offset=((qh-16)* 94+(wh-1))* 72L;/*计算该汉字在字库中偏移量*/fseek(fp,offset,SEEK_SET);fread(buffer,72,1,fp);/*取出汉字32字节的点阵字模存入buffer中(一个汉字)*/for (j=0;j<24;j++)/*将32位字节的点阵按位在屏幕上打印出来(1:打印,0:不打印),显示汉字*/for(o=0;o<xk;o++)for(i=0;i<24;i++)for(p=0;p<yk;p++)if((0x80>>i%8)&buffer[j][i/8])putpixel(x+j*yk+p,y+i*xk+o,COLOR);s+=2;/*因为一个汉字内码占用两个字节,所以s必须加2*/x+=25+xk*25;}}openhzk24(){if ((fp=fopen("c:\\turboc2\\HZK24K","rb"))==NULL)/*打开汉字库,c:\\turboc2\\HZK24K表明汉字库位置在Tc环境下,红色位置说明打开的是楷体汉字库,可修改为其他24点阵汉字库,对应不同的字体*/{ printf("Can't open HZK24K,Please add it");getch();closegraph();exit(0);}}。
点阵汉字显示
由于Turbo C应用于DOS操作系统下,在使用Turbo C进行程序设计时,一般情况下只好使用英文
进行人机交互。要是想直接用中文界面,就需要另想他法了。
如果使用中文DOS系统(如UCDOS),则可以解决在字符界面下的汉字显示问题。也就是说,可以用
printf或其他字符串函数来输出汉字。
但是,这样仍然有一些不方便。必须先启动中文DOS系统,再执行Turbo C或编译好的程序。并且
在中文版DOS下运行Tubor C时,还可能出现一些问题。而对于图形界面来说,这种办法也行不通了。
那么在图形界面下显示汉字的问题就迫切需要解决了。既然是图形界面,只要把汉字当成一幅画,画
在显示屏上不就可以了。关键在于如何取得汉字的图形,也就是汉字的点阵字模呢。其实那些中文版的DOS
显示汉字的方式也就是在图形界面下画出汉字的,它们已经提供了现成的点阵字库文件。例如常用的16×
16点阵HZK16文件,12×12点阵HZK12文件等等,这些文件包括了GB 2312字符集中的所有汉字。现
在只要弄清汉字点阵在字库文件中的格式,就可以按照自己的意愿去显示汉字了。
下面以HZK16文件为例,分析取得汉字字模的方法。
HZK16文件是按照GB 2312-80标准,也就是通常所说的国标码或区位码的标准排列的。国标码分为
94 个区(Section),每个区 94 个位(Position),所以也称为区位码。其中01~09 区为符号、数字区,
16~87 区为汉字区。而 10~15 区、88~94 区是空白区域。
如何取得汉字的区位码呢?在计算机处理汉字和ASCII字符时,使每个ASCII字符占用1个字节,而
一个汉字占用两个字节,其值称为汉字的内码。其中第一个字节的值为区号加上32(20H),第二个字节的
值为位号加上32(20H)。为了与ASCII字符区别开,表示汉字的两个字节的最高位都是1,也就是两个字
节的值都又加上了128(80H)。这样,通过汉字的内码,就可以计算出汉字的区位码。
具体算式如下:
qh=c1-32-128=c1-160 wh=c2-32-128=c2-160
或
qh=c1-0xa0 wh=c2-0xa0
qh,wh为汉字的区号和位号,c1,c2为汉字的第一字节和第二字节。
根据区号和位号可以得到汉字字模在文件中的位置:
location=(94*(qh-1)+(wh-1))*一个点阵字模的字节数。
那么一个点阵字模究竟占用多少字节数呢?我们来分析一下汉字字模的具体排列方式。
例如下图中显示的“汉”字,使用16×16点阵。字模中每一点使用一个二进制位(Bit)表示,如果是1,
则说明此处有点,若是0,则说明没有。这样,一个16×16点阵的汉字总共需要16*16/8=32个字节表示。
字模的表示顺序为:先从左到右,再从上到下,也就是先画左上方的8个点,再是右上方的8个点,然后
是第二行左边8个点,右边8个点,依此类推,画满16×16个点。
对于其它点阵字库文件,则也是使用类似的方法进行显示。例如HZK12,但是HZK12文件的格式有
些特别,如果你将它的字模当作12*12位计算的话,根本无法正常显示汉字。因为字库设计者为了使用的
方便,字模每行的位数均补齐为8的整数倍,于是实际该字库的位长度是16*12,每个字模大小为24字节,
虽然每行都多出了4位,但这4位都是0(不显示),并不影响显示效果。 还有UCDOS下的HZK24S
(宋体)、HZK24K(楷体)或HZK24H(黑体)这些打印字库文件,每个字模占用24*24/8=72字节,不
过这类大字模汉字库为了打印的方便,将字模都放倒了,所以在显示时要注意把横纵方向颠倒过来就可以
了。
这样我们就完全清楚了如何得到汉字的点阵字模,这样就可以在程序中随意的显示汉字了。
如果在程序中使用的汉字数目不多,也可以不必总是在程序里带上几百K的字库文件,也许你的程序
才只有几十K。这样可以事先将所需要显示的汉字字模提取出来,放在另一个文件里,按照自己的顺序读
取文件就可以了。
下面的程序说明了具体显示汉字的方法,以16×16汉字为例,使用HZK16文件。
#include
#include
/* x,y为显示坐标,s为显示字符串,colour为颜色 */
void hanzi16(int x,int y,char *s,int colour)
{
FILE *fp;
char buffer[32]; /* 32字节的字模缓冲区 */
register I,j,k;
unsigned char qh,wh;
unsigned long location;
if((fp=fopen("hzk16","rb"))==NULL)
{
printf("Can't open hzk16!");
getch();
exit(0);
}
while(*s)
{
qh=*s-0xa0;
wh=*(s+1)-0xa0;
location=(94*(qh-1)+(wh-1))*32L; /* 计算汉字字模在文件中的位置 */
fseek(fp,location,SEEK_SET);
fread(buffer,32,1,fp);
for(i=0;i<16;i++)
for(j=0;j<2;j++)
for(k=0;k<8;k++)
if(((buffer[i*2+j]>>(7-k))&0x1)!=NULL)
putpixel(x+8*j+k,y+I,colour);
s+=2;
x+=16; /* 汉字间距 */
}
fclose(fp);
}
main()
{
int gd=DETECT,gm;
initgraph(&gd,&gm,"");
hanzi16(246,200,"疯狂甲虫乐园!",BROWN);
getch();
closegraph();
}