搜索
bottom↓
回复: 36

汉字索引的问题

[复制链接]

出0入0汤圆

发表于 2012-5-8 09:15:31 | 显示全部楼层 |阅读模式
typedef struct typFNT_GB16                 // 汉字字模数据结构
{
       signed char Index[2];               // 汉字内码索引
       char Msk[32];                       // 点阵码数据
};

/////////////////////////////////////////////////////////////////////////
// 汉字字模表                                                          //
// 汉字库: 宋体16.dot,横向取模左高位,数据排列:从左到右从上到下         //
/////////////////////////////////////////////////////////////////////////
struct typFNT_GB16 code GB_16[] =          // 数据表
{
"爱", 0x00,0x78,0x3F,0x80,0x11,0x10,0x09,0x20,
      0x7F,0xFE,0x42,0x02,0x82,0x04,0x7F,0xF8,
      0x04,0x00,0x07,0xF0,0x0A,0x20,0x09,0x40,
      0x10,0x80,0x11,0x60,0x22,0x1C,0x0C,0x08,

"你", 0x11,0x00,0x11,0x00,0x11,0x00,0x23,0xFC,
      0x22,0x04,0x64,0x08,0xA8,0x40,0x20,0x40,
      0x21,0x50,0x21,0x48,0x22,0x4C,0x24,0x44,
      0x20,0x40,0x20,0x40,0x21,0x40,0x20,0x80
};


void dprintf(uchar col,uchar layer,uchar *ptr)//ASCII的汉字混合显示程序
{
        uchar c1,c2;
        uchar i,j,k;
        uchar ulen;
        uchar ucol,ulayer;
        ulen=0;
        ucol=col;
        ulayer=layer;
        i=0;
        while(ptr[ulen]!='\0') ulen++;//判断字符串的长度

        while(i<ulen)
        {
                c1=ptr[i];
                c2=ptr[i+1];



                if(c1<=128)//字符和汉字的分界线
                {
                        显示字符的没问题
                        i++;
                }
                else
                {
                        for(j=0;j<255;j++)
                        {
                                if((c1==GB_16[j].Index[0])&&(c2==GB_16[j].Index[1]))//索引汉字.....这里查找汉字什么就是找不到?
                              {这里显示汉字什}
                        }
                       
                        ucol+=16;
                        i+=2;
                        }
                }
        }



主函数调用dprintf(1,1,“爱你”)时查找不到汉字、还有索引用c1=ptr[i]和第个字,c2=ptr[i+1];算是第二个字了,我有点搞不明白,
一个汉字是有两个内码,但什么把它分出来啊、各位大虾懂的和小弟说说啊?

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2012-5-8 09:16:21 | 显示全部楼层
在线等我哦,搞了几天搞不下啊、帮帮忙啊

出0入0汤圆

发表于 2012-5-8 09:43:15 | 显示全部楼层
signed char Index[2];               // 汉字内码索引

===>

unsigned char Index[2];               // 汉字内码索引

出0入0汤圆

发表于 2012-5-8 09:46:18 | 显示全部楼层
本帖最后由 shangdawei 于 2012-5-8 09:47 编辑

>> 一个汉字是有两个内码,但什么把它分出来啊

不想分开, 可以试试这个

typedef struct _typFNT_GB16                 // 汉字字模数据结构
{
       unsigned short Index;               // 汉字内码索引
       char Msk[32];                       // 点阵码数据
} typFNT_GB16;

typFNT_GB16 GB_16[] =          // 数据表
{
'爱',  // 0xB0AE

      0x00,0x78,0x3F,0x80,0x11,0x10,0x09,0x20,
      0x7F,0xFE,0x42,0x02,0x82,0x04,0x7F,0xF8,
      0x04,0x00,0x07,0xF0,0x0A,0x20,0x09,0x40,
      0x10,0x80,0x11,0x60,0x22,0x1C,0x0C,0x08,

'你', // 0xC4E3

      0x11,0x00,0x11,0x00,0x11,0x00,0x23,0xFC,
      0x22,0x04,0x64,0x08,0xA8,0x40,0x20,0x40,
      0x21,0x50,0x21,0x48,0x22,0x4C,0x24,0x44,
      0x20,0x40,0x20,0x40,0x21,0x40,0x20,0x80
};


if( (c1*256+c2) ==GB_16[j].Index )
{

}

出0入0汤圆

 楼主| 发表于 2012-5-8 09:47:28 | 显示全部楼层
shangdawei 发表于 2012-5-8 09:46
>> 一个汉字是有两个内码,但什么把它分出来啊

不想分开, 可以试试这个

谢谢大哥啊、

出0入0汤圆

 楼主| 发表于 2012-5-8 09:52:54 | 显示全部楼层
还有啊,大虾,我在网上看到c1=ptr[i]和第个字,c2=ptr[i+1];这算是第二个字了,什么会是一个汉字内码啊。我有点搞不明白,
希望能解答一下哦

出0入0汤圆

发表于 2012-5-8 11:38:39 | 显示全部楼层
可以查询那个汉子码

出0入0汤圆

 楼主| 发表于 2012-5-8 11:45:34 | 显示全部楼层
hxlwb 发表于 2012-5-8 11:38
可以查询那个汉子码

c2=prt[i+1]这个不就是字符串的第二个字符了吗、什么会是第一个字的第二个内码啊????

出0入0汤圆

 楼主| 发表于 2012-5-9 17:21:52 | 显示全部楼层
什么都没有人回答了哦、。我又看到有的用  c1=ptr[0];c2=ptr[1];就是查两个字吗、
有可能是一句子,什么只查第一个和第二个就可以知道后面汉字的内码了吗?


出0入0汤圆

 楼主| 发表于 2012-5-9 17:22:32 | 显示全部楼层
没人能解答一下啊~~~

出0入0汤圆

发表于 2012-5-9 17:33:25 | 显示全部楼层
tanguicaicai 发表于 2012-5-9 17:22
没人能解答一下啊~~~

提示你你一下
char是8bit的,汉字索引是16位的

出0入0汤圆

发表于 2012-5-9 17:37:47 | 显示全部楼层
我和你在研究同一个问题,好几天了,也调不来显示 总是显示乱码

出0入0汤圆

发表于 2012-5-9 17:46:28 | 显示全部楼层
// ------------------  汉字字模的数据结构定义 ------------------------ //
flash struct  typFNT_GB16   // 汉字字模数据结构
{
       unsigned char  Index[3];               // 汉字内码索引       
       unsigned char   Msk[32];                        // 点阵码数据
};
/////////////////////////////////////////////////////////////////////////
// 汉字字模表                                                          //
// 汉字库: 宋体16.dot,横向取模左高位,数据排列:从左到右从上到下         //
/////////////////////////////////////////////////////////////////////////
struct  typFNT_GB16 flash codeGB_16[40] =          // 数据表
{//这个 可能是 传说中的 结构体 数组

/*--  文字:  一  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
"主",0xff,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,

出0入0汤圆

发表于 2012-5-9 17:48:23 | 显示全部楼层
主程序里调用的这一句:
OLED_PutString(0x1c,0,"科技");delay_ms(8000);
其中0x1c ,0 是要显示的字的座标,这座标没有问题。

出0入0汤圆

发表于 2012-5-9 17:49:31 | 显示全部楼层
void OLED_PutString(unsigned int x, unsigned int y,unsigned char flash *s)
{
         unsigned int l=0;
        while(*s) {
                if( *s < 0x80)
                    {
                        OLED_PutChar(x+l*2,y,*s);
                        s++;l++;
                    }
                else
                    {
                        PutGB1616(x+l*2,y,(unsigned char *)s);
                        s+=2;l+=2;
                    }
                }
}

出0入0汤圆

发表于 2012-5-9 17:53:24 | 显示全部楼层
void PutGB1616(unsigned int x, unsigned int y, unsigned char c[2])
{
        unsigned int i,j,k;

        OLED_SetPos(x,  x+4-1,y, y+16-1);

        for (k=0;k<64;k++)
        { //64标示自建汉字库中的个数,循环查询内码
          if ((codeGB_16[k].Index[0]==c[0])&&(codeGB_16[k].Index[1]==c[1]))
          {   
               //unsigned int m = codeGB_16[k].Msk[i];
                   for(i=0;i<32;i++)
                   {    //16*16=256点32*8=256
                    unsigned char m = codeGB_16[k].Msk[i];
                    unsigned char m2;
                        m2=m&0b11000000;
                       
                        send_2bit(m2);
                       
                        //send_2bit(0x00);
                        m2=m&0x30;
                        m2<<=2;
                       
                        send_2bit(m2);
                       
                        //send_2bit(0xff);
                        m2=m&0x0c;
                        m2<<=4;
                        send_2bit(m2);
                       
                        //send_2bit(0x00);
                        m2=m&0x03;
                        m2<<=6;
                        send_2bit(m2);
                       
                        //send_2bit(0xff);
                    
                }  
          }
        }       
}

出0入0汤圆

发表于 2012-5-9 18:05:50 | 显示全部楼层
一个汉字两个字节..如果是汉字,在计算机里面就是两个字节的内码...你可以KEIL软仿调试的。。可以看见汉字内码在内存的如何存放的。。。然后再用一个简单的汉字内码查看器,看看是不是对上了。。计算机都是一个一个字节的存放的。。不管是什么东西。。。所以汉字是是两个字节,那么ptr[0]就是汉字的第一个内码字节,ptr[1]就是以起始地址偏移1个字节,就是汉字的第二个内码字节。。如果是ASCII码,那么才是你说的第二个字符,因为ASCII是在内存中只占一个字节的。。。

出0入0汤圆

发表于 2012-5-9 18:12:16 | 显示全部楼层
http://www.ourdev.cn/thread-4099591-1-1.html  看我的回复。。。楼主。。。

出0入0汤圆

发表于 2012-5-9 18:52:52 | 显示全部楼层
myqiang1990 发表于 2012-5-9 18:12
http://www.ourdev.cn/thread-4099591-1-1.html  看我的回复。。。楼主。。。

为什么有些signed char Index[3]; 是3,有些是2呢?
我觉得应该是2,可是改成2 .编译不通过,报错

出0入0汤圆

发表于 2012-5-9 18:57:10 | 显示全部楼层
我觉得我的程序,就是在数组里面 寻找  汉字内码时,对应错误

我有两个问题搞不懂
1 是 为什么有些signed char Index[3]; 是3
2 是 if( *s < 0x80)
                    {
                        OLED_PutChar(x+l*2,y,*s);
                        s++;l++;
                    }
                else
                    {
                        PutGB1616(x+l*2,y,(unsigned char *)s);
                        s+=2;l+=2;
                    }
上面这句,里面有个(unsigned char *)s,搞不懂这是什么意思

出0入0汤圆

发表于 2012-5-9 19:49:09 | 显示全部楼层
zhwm3064 发表于 2012-5-9 18:57
我觉得我的程序,就是在数组里面 寻找  汉字内码时,对应错误

我有两个问题搞不懂

把报错的信息发来看看

出0入0汤圆

发表于 2012-5-9 21:26:07 | 显示全部楼层
myqiang1990 发表于 2012-5-9 19:49
把报错的信息发来看看

Error:H\shengju\手持机程序\初步显示\GB1616.h(16).included from:初步.c:too many inintializers

出0入0汤圆

发表于 2012-5-9 21:31:50 | 显示全部楼层
我的程序是引用了别人在Keil上的程序,他的程序是用于LCD显示的,
我把程序改了下,用在CVAVR上,另外是用在OLED显示上,现在显示是没问题,因为我在上面的程序上改了下试验,可以显示正常。(改成后面那句就可以显示了send_2bit(m2); //send_2bit(0xff);)
这正明,就是,汉字内码引用时没有 对上号

出0入0汤圆

发表于 2012-5-10 05:47:38 | 显示全部楼层
为什么有些signed char Index[3]; 是3,有些是2呢?
我自己回答:这是因这汉字内码 在后面自动加上一个0*/

出0入0汤圆

 楼主| 发表于 2012-5-10 08:58:37 | 显示全部楼层
zhwm3064 发表于 2012-5-9 17:46
// ------------------  汉字字模的数据结构定义 ------------------------ //
flash struct  typFNT_GB16  ...

你的汉字内码什么有3个啊,我的能显示了,还有你那前面用的
flash有什么不同啊

出0入0汤圆

 楼主| 发表于 2012-5-10 09:00:06 | 显示全部楼层
zhwm3064 发表于 2012-5-10 05:47
为什么有些signed char Index[3]; 是3,有些是2呢?
我自己回答:这是因这汉字内码 在后面自动加上一个0*/ ...

不是一个汉字只有两个码吗、什么有3个

出0入0汤圆

 楼主| 发表于 2012-5-10 09:05:32 | 显示全部楼层
myqiang1990 发表于 2012-5-9 18:05
一个汉字两个字节..如果是汉字,在计算机里面就是两个字节的内码...你可以KEIL软仿调试的。。可以看见汉字 ...

听君一言,胜读10年书啊。
谢谢··受教了。

出0入0汤圆

 楼主| 发表于 2012-5-10 09:13:29 | 显示全部楼层
myqiang1990 发表于 2012-5-9 18:12
http://www.ourdev.cn/thread-4099591-1-1.html  看我的回复。。。楼主。。。

大虾还有点不明白的地方就是以c1=dp[0];c2=dp[1];这只 能查输入一串汉字的第一个字的内码啊。后面的
又什么查·如果是这样uchar i;一个变量,c1=dp;c2=dp[i+1];当写完一个字时i++;这我能理解,

出0入0汤圆

发表于 2012-5-10 21:43:08 | 显示全部楼层
tanguicaicai 发表于 2012-5-10 08:58
你的汉字内码什么有3个啊,我的能显示了,还有你那前面用的
flash有什么不同啊 ...

可能是编译器不同造成的,在Keil中,可能是两字节
我用的是CVAVR,取两字节会报错,只好用三字节了。是因为在生成的两字节编码的后边。又自动添加了一个0.休止符

出0入0汤圆

发表于 2012-5-10 21:44:56 | 显示全部楼层
tanguicaicai 发表于 2012-5-10 08:58
你的汉字内码什么有3个啊,我的能显示了,还有你那前面用的
flash有什么不同啊 ...

我前面用的flash,我不是太清楚了,我想可能是定义 这些数字 存在flash存储器中吧

出0入0汤圆

 楼主| 发表于 2012-5-11 09:05:38 | 显示全部楼层
昨晚回去搞了一下,出现了一个很怪得现象哦,哪位大虾了解的说一下哦、
display_st1(x,y,*dp,uchar mode);这个函数 是可以写入汉字和字符的(也就调用上面的字模来)
写入一个变量时像uchar c1=4;display_st1(1,1,c1,0);时它显示出现乱码哦display_st1(1,1,“145”,0);它又可以哦

出0入0汤圆

 楼主| 发表于 2012-5-12 08:55:44 | 显示全部楼层
大家就没有遇到这种情况吗?
display_st1(uchar x,uchar y,uchar *dp,uchar mode);

出0入0汤圆

 楼主| 发表于 2012-5-12 08:59:49 | 显示全部楼层
大家就没有遇到这种情况吗?
display_st1(uchar x,uchar y,uchar *dp,uchar mode);
写入一个变量就不能正常的显示,固定显示又可以哦,我
搞不清为什么哦,display_st1(1,1,“145”,0);这样又可以,uchar c1=3;
display_st1(1,1,c1,0);当我在前面设定c1=3;时,它又不能
正常显示,郁闷啊

出0入0汤圆

 楼主| 发表于 2012-5-12 17:09:35 来自手机 | 显示全部楼层
是不是我问这个问题很菜没人回哦

出0入0汤圆

 楼主| 发表于 2012-5-14 14:18:27 | 显示全部楼层
木有人回咱了,我改个一个法子让它显示0~9,
void display_shuzi(uchar x, uchar y,uchar a,uchar inverse) 这个是显示数字和变量的
{ uchar k,j;
       for(k=0;k<255;k++)
              { if((a+0x30)>0x39)break;
                            if((a+0x30)== ASC_12[k].Index[0] )
                               { lcd_address(x,y);
                        for(j=0;j<6;j++)
                      { if(inverse)lcd_data(~ASC_12[k].Msk[j]);
                       else lcd_data(ASC_12[k].Msk[j]);}
                    
                            lcd_address(++x,y);
                             for(j=6;j<12;j++)
                                { if(inverse)lcd_data(~ASC_12[k].Msk[j]);
                         else lcd_data(ASC_12[k].Msk[j]);}
                                                 break;}}
                                                                                                                                                                                                                                        }



void display_st1(uchar x,uchar y,uchar *dp,uchar inverse)
{ uchar c1,c2;
// uint c;
  uchar i,j,k,ulen,upage,ucol;
  upage=x;
  ucol=y;
  while ( (uchar)dp[ulen] != '\0' ){ulen++;};
  i=0;
  while(i<ulen)
  {  c1=dp[i];
     c2=dp[i+1];

    if(c1<128)
             {for(k=0;k<255;k++)
              { if(c1== ASC_12[k].Index[0] ) break;}
                             // if(ucol>128){ucol=1,upage++;}
                  lcd_address(upage,ucol);
                    for(j=0;j<6;j++)
                    { if(inverse)lcd_data(~ASC_12[k].Msk[j]);
                       else lcd_data(ASC_12[k].Msk[j]);}
                    
                    lcd_address(++upage,ucol);
                        for(j=6;j<12;j++)
                            { if(inverse)lcd_data(~ASC_12[k].Msk[j]);
                      else lcd_data(ASC_12[k].Msk[j]);}
                      upage--;
                                          ucol=ucol+7;
                                          i++;          }

        else       { for(k=0;k<40;k++)
                     {if((c1 == GB_12[k].Index[0])&&(c2 == GB_12[k].Index[1]))
                                            break;}
                     lcd_address(upage,ucol);
                         for(j=0;j<12;j++)
                          { if(inverse)lcd_data(~GB_12[k].Msk[j]);
                                 else lcd_data(GB_12[k].Msk[j]);}
                     
                        lcd_address(++upage,ucol);
                            for(j=12;j<24;j++)
                                 { if(inverse)lcd_data(~GB_12[k].Msk[j]);
                             else lcd_data(GB_12[k].Msk[j]);}  
                                        upage--;
                            ucol=ucol+12;i=i+2;}
                                                                        
                                           }}

出0入0汤圆

发表于 2014-9-24 10:13:07 | 显示全部楼层
路过,学习了

出0入8汤圆

发表于 2014-10-17 09:27:24 | 显示全部楼层
路过,看一下~
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-4 02:20

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表