在与硬件的蓝牙通讯过程中,硬件需要手机端发送1616的汉字点阵过去,用于硬件直接显示汉字。这里采用的是通用的HZK16(宋体)汉字
1HZK16字库是符合GB2312国家标准的16×16点阵字库,HZK16的GB2312-80支持的汉字有6763个,符号682个。其中一级汉字有 3755个,按声序排列,二级汉字有3008个,按偏旁部首排列。
我们在一些应用场合根本用不到这么多汉字字模,所以在应用时就可以只提取部分字体作为己用。 HZK16字库里的16×16汉字一共需要256个点来显示,也就是说需要32个字节才能达到显示一个普通汉字的目的。
我们知道一个GB2312汉字是由两个字节编码的,范围为0xA1A1~0xFEFE。A1-A9为符号区,B0-F7为汉字区。每一个区有94个字符(注意:这只是编码的许可范围,不一定都有字型对应,比如符号区就有很多编码空白区域)。
下面以汉字「我」为例,介绍如何在HZK16文件中找到它对应的32个字节的字模数据。
前面说到一个汉字占两个字节,这两个中前一个字节为该汉字的区号,后一个字节为该字的位号。其中,每个区记录94个汉字,位号为该字在该区中的位置。所以要找到「我」在hzk16库中的位置就必须得到它的区码和位码。
区码:汉字的第一个字节-0xA0,因为汉字编码是从0xA0区开始的,所以文件最前面就是从0xA0区开始,要算出相对区码
位码:汉字的第二个字节-0xA0
这样我们就可以得到汉字在HZK16中的绝对偏移位置:offset = (94(区码-1)+(位码-1))32。
注解:
区码减1是因为数组是以0为开始而区号位号是以1为开始的
(94(区号-1)+位号-1)是一个汉字字模占用的字节数
最后乘以32是因为汉字库文应从该位置起的32字节信息记录该字的字模信息(前面提到一个汉字要有32个字节显示)
以上是摘抄自 HZK16汉字1616点阵字库的使用及示例程序 - 陪她去流浪
首先需要先将UTF-8编码转换成 cp936 编码,然后才能正确地索引字库中的汉字。
下面的方法执行完之后 会打印出来二进制 横向扫描的0,1的点阵
更多 关于手机端发送1616汉字点阵取模相关问题(二) -
void rwe ()
{
temp = num[z][i2];
io_595();
temp = num[z][i2+1];
io_595();
i = i%16;
}
在这里,temp是16位的,num虽然定义是16位的,但实际有效数据是8位的,
改成一下试试:
void rwe ()
{
temp = num[z][i2];
temp<<=8;
temp += num[z][i2+1];
io_595();
i = i%16;
}
#include <REG51H>
#include <intrinsh>
#define NOP() _nop_() // 定义空指令 ,这个函数在库 <intrinsh> 中
//--重定义函数变量--//
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
//--定义SPI要使用的 IO--//
sbit MOSIO = P3^4;
sbit R_CLK = P3^5;
sbit S_CLK = P3^6;
//---全局变量声明--//
ulong column; //点阵列
ulong row; //点阵行
ulong dt;
//点阵显示数组
uchar code tab0[] = {0x00, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80,
0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80, 0x00};
//你的字,这个只是举例
//uchar code tab1[] = {
//0X0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF,
//0X0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF};
//函数声明
void HC595SendData( uchar BT3, uchar BT2,uchar BT1,uchar BT0);
void delay(unsigned short s)
{
for(s;s>0;s--);
}
/主函数/
void main(void)
{
int k, i, ms;
i = 80; //显示时间
while(1)
{
delay(1000);
HC595SendData(0xff,0xff,0,0);
for(ms = i; ms > 0; ms--)
{
for(k = 0; k < 16; k++)
{
//输出字
HC595SendData(~tab1[2k +1],~tab1[2k],tab0[2k],tab0[2k + 1]);
}
}
}
}
/
函 数 名 : HC595SendData
函数功能 : 通过595发送四个字节的数据
输 入 : BT3:第四个595输出数值
BT2: 第三个595输出数值
BT1:第二个595输出数值
BT0:第一个595输出数值
输 出 : 无
/
void HC595SendData( uchar BT3, uchar BT2,uchar BT1,uchar BT0)
{
uchar i;
//--发送第一个字节--//
for(i=0;i<8;i++)
{
MOSIO = BT3 >> 7 ; //从高位到低位
BT3 <<= 1;
S_CLK = 0;
S_CLK = 1;
}
//--发送第一个字节--//
for(i=0;i<8;i++)
{
MOSIO = BT2 >>7; //从高位到低位
BT2 <<= 1;
S_CLK = 0;
S_CLK = 1;
}
//--发送第一个字节--//
for(i=0;i<8;i++)
{
MOSIO = BT1 >> 7; //从高位到低位
BT1 <<= 1;
S_CLK = 0;
S_CLK = 1;
}
//--发送第一个字节--//
for(i=0;i<8;i++)
{
MOSIO = BT0 >> 7; //从高位到低位
BT0 <<= 1;
S_CLK = 0;
S_CLK = 1;
}
//--输出--//
R_CLK = 0; //set dataline low
R_CLK = 1; //片选
}
这不仅仅是简单的移位,我也做过,你生成字型码的时候是横着扫描吗?如果是,移位也会横向,如果不是,移位的话会乱码。存放字型码的最好是Uchar code,这样占用数据空间会减小。你移位的时候用中间变量和指针进行 *** 作。
还有,你扫码方式,我做的是1/4行扫。你的如果是逐行扫描就不太一样 了。
#include <reg52h>
#define uchar unsigned char
#define uint unsigned int
#define outdat P2
sbit ld=P3^0;
sbit lw=P3^1;
//数码管显示代码
unsigned char code tab[]={
0x01,0x02,0x03,0x04,0xFF,0xFF,0xFF,0xFF};
void delay1ms(unsigned int count) //延时1ms
{
unsigned char j;
for(;count>0;count--)
for(j=0;j<120;j++);
}
void display(unsigned char num)
{
outdat=tab[num];
ld=0;ld=1;ld=0;
outdat=0x01<<num;
lw=0;lw=1;lw=0;
delay1ms(2);
}
void main()
{
unsigned char i;
while(1)
{
for(i=0;i<8;i++)
{
display(i);
}
}
}
这先要知道HC595是怎么接的,与点阵是怎么接的,就是点阵的行/列是怎么与HC595接的。
其次是要知道4个HC595是全部串联起来吗,那哪片在前,哪片在后,这关系到输入串行数据时,怎么写数据,即先写什么,后写什么。
第三,根据点阵的行/列排列来确定汉字取模的方式,汉字取模分为按行取,还是按列取,再就是先取高位,还是先取低位。
这样才能确定那个汉字取模软件的取模方式,然后再根据你写程序的语言,是汇编的还是C语的,来确定字模的形式。
这些问题,你都搞明白了吗?
我也不怎么会,还在学习中
下面有一个1616的C程序
参考一下。。。
字模软件你要的话我可以给你
共同学习。。。
#include<reg51h>
sbit P20=P2^0;
sbit P22=P2^2;
unsigned char code text[]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x80,0x00,0x80,0xFC,0x80,0x05,0xFE,0x85,0x04,0x4A,0x48,0x28,0x40,0x10,0x40,
0x18,0x40,0x18,0x60,0x24,0xA0,0x24,0x90,0x41,0x18,0x86,0x0E,0x38,0x04,0x00,0x00,/"欢",0/
0x40,0x00,0x21,0x80,0x36,0x7C,0x24,0x44,0x04,0x44,0x04,0x44,0xE4,0x44,0x24,0x44,
0x25,0x44,0x26,0x54,0x24,0x48,0x20,0x40,0x20,0x40,0x50,0x00,0x8F,0xFE,0x00,0x00,/"迎",1/
0x01,0x00,0x21,0x10,0x19,0x18,0x0D,0x10,0x09,0x20,0x01,0x04,0x7F,0xFE,0x04,0x40,
0x04,0x40,0x04,0x40,0x04,0x40,0x08,0x42,0x08,0x42,0x10,0x42,0x20,0x3E,0x40,0x00,/"光",2/
0x01,0x00,0x09,0x80,0x09,0x00,0x49,0xFE,0x4A,0x20,0x4A,0x10,0x4C,0x10,0x49,0x04,
0x49,0xFE,0x49,0x24,0x49,0x24,0x49,0x24,0x49,0x24,0x09,0xFC,0x09,0x04,0x00,0x00,/"临",3/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
void Delay(unsigned char i)
{
unsigned char j;
for(;i>0;i--)
for(j=0;j<80;j++)
{;}
}
void main()
{
unsigned int a,e;
unsigned char b,c,d=0;
SCON=0;
while(1)
{
for(e=0;e<160;e=e+32)
{
for(a=0;a<8;a++)
{
for(b=0;b<8;b++)
{
for(c=0;c<32;c++)
{
SBUF=~(text[e+c+32]>>(8-a)|text[e+c+1]<<a);
while(TI==0);
TI=0;
SBUF=~(text[e+c+1]>>(8-a)|text[e+c]<<a);
while(TI==0);
TI=0;
c++;
P20=1;
P1=d;
P22=0;
Delay(3);
P20=0;
P22=1;
d++;
if(d==16)d=0;
}
}
}
for(a=0;a<8;a++)
{
for(b=0;b<8;b++)
{
for(c=0;c<32;c++)
{
SBUF=~(text[e+c+1+32]>>(8-a)|text[e+c+32]<<a);
while(TI==0);
TI=0;
SBUF=~(text[e+c+32]>>(8-a)|text[e+c+1]<<a);
while(TI==0);
TI=0;
c++;
P20=1;
P1=d;
P22=0;
Delay(3);
P20=0;
P22=1;
d++;
if(d==16)d=0;
}
}
}
}
for(a=0;a<160;a=a+2)
{
for(b=0;b<8;b++)
{
for(c=1;c<32;c++)
{
if(a+c<160){
SBUF=~text[a+c];
while(TI==0);
TI=0;
SBUF=~text[a+c-1];
while(TI==0);
TI=0;}
else {
SBUF=~text[a+c-160];
while(TI==0);
TI=0;
SBUF=~text[a+c-1-160];
while(TI==0);
TI=0;}
P1=c/2;
c++;
P20=1;
P22=0;
Delay(3);
P22=1;
P20=0;
}
}
}
}
}
以上就是关于关于iOS 蓝牙 字库 发送16*16汉字点阵取模相关问题(一)全部的内容,包括:关于iOS 蓝牙 字库 发送16*16汉字点阵取模相关问题(一)、51单片机 16X16点阵 代码程序出问题了,请求帮助、谢谢!!!、急急急。。。跪求16x16点阵模块显示汉字的C语言程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)