打印

设计时**

[复制链接]
11914|66
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
古道热肠|  楼主 | 2008-8-23 17:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
汉字点阵显示程序是常用的模块,很多应用都要用到,为了便于给广大网友一个参考,贴上自己用的,如果大家有更好的,也欢迎贴上来.
//下需是结构体定义

/*汉字X方向宽度*/
#define HZ_SIZE_X                2
/*汉字Y方向宽度*/
#define HZ_SIZE_Y                16

#define HZ_NUM                    128

typedef struct _HzModel
{
    /* 汉字内码 */
    uint uiHZcode;

    /* 点阵字模 向下为x,向右为y*/
    uchar model[HZ_SIZE_X][HZ_SIZE_Y];

}HZ_MODEL

//定义结束

//下面是字库文件

#include "ZKFunc.h"

code HZ_MODEL ZK_Data[]=
{
    {    0xD2F4,  //音
        0x02,0x00,0x01,0x10,0x3F,0xF8,0x08,0x20,0x04,0x20,0x04,0x44,0xFF,0xFE,0x00,0x10,
        0x1F,0xF8,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10},

    {    0xC0D6,  //乐
        0x00,0x20,0x00,0xF0,0x1F,0x00,0x10,0x00,0x11,0x00,0x11,0x00,0x21,0x04,0x7F,0xFE,
        0x01,0x00,0x01,0x00,0x09,0x20,0x09,0x10,0x11,0x08,0x21,0x0C,0x45,0x04,0x02,0x00},

    {    0xD0C0,  //欣
        0x02,0x40,0x07,0x40,0x38,0x40,0x20,0x40,0x20,0x7E,0x20,0x82,0x3F,0x24,0x24,0x20,
        0x24,0x20,0x24,0x20,0x24,0x50,0x24,0x50,0x44,0x88,0x44,0x88,0x85,0x06,0x02,0x04},

    {    0xC9CD,  //赏
        0x01,0x00,0x11,0x10,0x09,0x20,0x7F,0xFE,0x40,0x02,0x8F,0xE4,0x08,0x20,0x0F,0xE0,
        0x00,0x10,0x1F,0xF8,0x10,0x10,0x11,0x10,0x11,0x10,0x02,0xC0,0x0C,0x30,0x30,0x08},

    {    0xCAB1,  //时
        0x00,0x08,0x04,0x08,0x7E,0x08,0x44,0x08,0x47,0xFE,0x44,0x08,0x44,0x08,0x7C,0x88,
        0x44,0x48,0x44,0x48,0x44,0x08,0x44,0x08,0x7C,0x08,0x44,0x48,0x00,0x28,0x00,0x10},

    {    0xD6D3,  //钟
        0x10,0x20,0x10,0x20,0x10,0x20,0x1C,0x24,0x21,0xFE,0x21,0x24,0x7D,0x24,0x91,0x24,
        0x11,0x24,0xFD,0xFC,0x11,0x24,0x10,0x20,0x14,0x20,0x18,0x20,0x10,0x20,0x00,0x20},

    {    0xB9DC,  //管
        0x10,0x40,0x1F,0x7C,0x28,0x90,0x45,0x08,0x01,0x00,0x7F,0xFE,0x40,0x02,0x9F,0xF4,
        0x10,0x10,0x1F,0xF0,0x10,0x00,0x1F,0xF0,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x00},

    {    0xC0ED,  //理
        0x00,0x08,0x13,0xFC,0xFA,0x48,0x22,0x48,0x23,0xF8,0x22,0x48,0xFA,0x48,0x23,0xF8,
        0x20,0x40,0x20,0x50,0x23,0xF8,0x3C,0x40,0xE0,0x40,0x40,0x44,0x0F,0xFE,0x00,0x00},

    {    0xD3CE,  //游
        0x02,0x10,0x41,0x14,0x20,0x1E,0x2F,0xE0,0x82,0x40,0x62,0x3E,0x23,0x84,0x02,0x88,
        0x12,0x88,0x22,0xFE,0xE2,0x88,0x24,0x88,0x24,0x88,0x28,0x88,0x31,0xA8,0x20,0x10},

    {    0xCFB7,  //戏
        0x00,0x40,0x00,0x50,0x7E,0x48,0x02,0x40,0x43,0xFE,0x24,0x40,0x14,0x44,0x14,0x44,
        0x08,0x48,0x14,0x48,0x12,0x50,0x22,0x20,0x40,0x60,0x80,0x92,0x01,0x0A,0x02,0x06},

    {    0xB9A6,  //功
        0x00,0x80,0x00,0x80,0x08,0x80,0xFC,0x80,0x10,0x84,0x17,0xFE,0x10,0x84,0x10,0x84,
        0x10,0x84,0x10,0x84,0x1D,0x04,0xF1,0x04,0x41,0x04,0x02,0x44,0x04,0x28,0x08,0x10},

    {    0xC4DC,  //能
        0x10,0x80,0x10,0x88,0x24,0x98,0x44,0xA0,0xFE,0xC0,0x02,0x84,0x7C,0x84,0x44,0x7C,
        0x7C,0x00,0x44,0x88,0x44,0x98,0x7C,0xA0,0x44,0xC0,0x44,0x82,0x54,0x82,0x48,0x7E},

    {    0xCEB4,  //未
        0x01,0x00,0x01,0x00,0x01,0x08,0x7F,0xFC,0x01,0x00,0x01,0x00,0x01,0x04,0xFF,0xFE,
        0x03,0x80,0x05,0x40,0x09,0x20,0x11,0x10,0x21,0x0E,0x41,0x04,0x01,0x00,0x01,0x00},

    {    0xBFAA,  //开
        0x00,0x08,0x7F,0xFC,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x24,0xFF,0xFE,
        0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x10,0x20,0x10,0x20,0x20,0x20,0x40,0x20},

    {    0xCDA8,  //通
        0x03,0xF8,0x40,0x10,0x30,0xA0,0x10,0x48,0x03,0xFC,0x02,0x48,0xF2,0x48,0x13,0xF8,
        0x12,0x48,0x12,0x48,0x13,0xF8,0x12,0x48,0x12,0x68,0x2A,0x50,0x44,0x06,0x03,0xFC},

    {    0xC9E8,  //设
        0x01,0xF0,0x21,0x10,0x11,0x10,0x11,0x10,0x01,0x10,0x02,0x0E,0xF4,0x00,0x13,0xF8,
        0x11,0x08,0x11,0x10,0x10,0x90,0x10,0xA0,0x14,0x40,0x18,0xB0,0x13,0x0E,0x0C,0x04},

    {    0xB6A8,  //定
        0x02,0x00,0x01,0x00,0x7F,0xFE,0x40,0x02,0x80,0x24,0x1F,0xF0,0x01,0x00,0x01,0x00,
        0x11,0x20,0x11,0xF0,0x11,0x00,0x11,0x00,0x11,0x00,0x29,0x06,0x47,0xFC,0x80,0x00},

    {    0xCDCB,  //退
        0x03,0xF8,0x42,0x08,0x32,0x08,0x13,0xF8,0x02,0x08,0x02,0x08,0xF3,0xFC,0x12,0x08,
        0x12,0xD0,0x12,0x20,0x12,0x90,0x13,0x0C,0x12,0x04,0x28,0x00,0x44,0x06,0x03,0xFC},

    {    0xB3F6,  //出
        0x01,0x00,0x01,0x00,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x3F,0xF8,0x21,0x08,
        0x01,0x00,0x41,0x04,0x41,0x04,0x41,0x04,0x41,0x04,0x41,0x04,0x7F,0xFC,0x40,0x04},

    {    0xC4EA,  //年
        0x08,0x00,0x08,0x08,0x1F,0xFC,0x11,0x00,0x21,0x00,0x41,0x10,0x1F,0xF8,0x11,0x00,
        0x11,0x00,0x11,0x04,0xFF,0xFE,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00},

    {    0xD4C2,  //月
        0x00,0x10,0x0F,0xF8,0x08,0x10,0x08,0x10,0x08,0x10,0x0F,0xF0,0x08,0x10,0x08,0x10,
        0x08,0x10,0x0F,0xF0,0x08,0x10,0x08,0x10,0x10,0x10,0x10,0x10,0x20,0x50,0x40,0x20},

    {    0xC8D5,  //日
        0x00,0x10,0x1F,0xF8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0xF0,
        0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10,0x00,0x00},

    {    0xB7D6,  //分
        0x00,0x80,0x04,0x80,0x04,0x40,0x08,0x40,0x08,0x20,0x10,0x10,0x20,0x08,0x4F,0xEE,
        0x84,0x24,0x04,0x20,0x04,0x20,0x04,0x20,0x04,0x20,0x08,0x20,0x11,0x40,0x20,0x80},

    {    0xC3EB,  //秒
        0x04,0x20,0x0E,0x20,0x78,0x20,0x08,0x20,0x08,0xA8,0xFE,0xA6,0x08,0xA2,0x1D,0x20,
        0x1A,0x24,0x28,0x24,0x28,0x28,0x48,0x10,0x88,0x20,0x08,0x40,0x08,0x80,0x0B,0x00},

    {    0xC8B7,  //确
        0x00,0x40,0x04,0x40,0xFE,0x78,0x10,0x90,0x11,0x24,0x23,0xFE,0x25,0x24,0x7D,0x24,
        0xA5,0xFC,0x25,0x24,0x25,0x24,0x25,0xFC,0x25,0x24,0x3D,0x24,0x22,0x24,0x04,0x0C},

    {    0xCEC2,  //温
        0x00,0x08,0x43,0xFC,0x32,0x08,0x12,0x08,0x83,0xF8,0x62,0x08,0x22,0x08,0x0B,0xF8,
        0x10,0x00,0x27,0xFC,0xE4,0xA4,0x24,0xA4,0x24,0xA4,0x24,0xA4,0x2F,0xFE,0x20,0x00},

    {    0xB6C8,  //度
        0x01,0x00,0x00,0x84,0x3F,0xFE,0x22,0x20,0x22,0x28,0x3F,0xFC,0x22,0x20,0x23,0xE0,
        0x20,0x00,0x2F,0xF0,0x22,0x20,0x21,0x40,0x20,0x80,0x43,0x60,0x8C,0x1E,0x30,0x04},

    {    0xFFFF,  //字库结尾标志符
        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},

};   //end
//总的有效字符数为27
//字库生成日期为:2008年7月16日
//字库生成时间为:22时36分17秒
//程序开发者:古道热肠,感谢您的使用!
//作者联系邮箱:xg_2004_sy@126.com
//---------------------------字库文件结束

//--------------------下面是字库查找的函数-------------------
extern code HZ_MODEL ZK_Data[];



/*-在内存中根据汉字内码取16点阵字模-*/
/* 返回:true  成功取到字模  */
/* 返回:false 取字模失败    */
bool GetHzModelInMem(uint uiHZCode,HZ_MODEL  ** pHzModel)
{
    //顺序查找法

    uint uiIndex;
    bool bResultFlag;

    uiIndex = 0;
    while(1)
    {
        if(ZK_Data[uiIndex].uiHZcode == 0xFFFF)
        {
            *pHzModel = (HZ_MODEL *)&(ZK_Data[uiIndex]);
            bResultFlag = false;
            break;
        }

        if(ZK_Data[uiIndex].uiHZcode == uiHZCode)
        {
            //-找到
            *pHzModel = (HZ_MODEL *)&(ZK_Data[uiIndex]);
            bResultFlag = true;
            break;
        }
        else
        {
            uiIndex++;
        }
    }

    return bResultFlag;
}

void GetHZDot(uint uiHZCode,uchar *ucHZDotData)
{
    HZ_MODEL *pHzModel;
    bool bReturnValue;

    bReturnValue =  GetHzModelInMem(uiHZCode,&pHzModel);
    memcpy(ucHZDotData,&pHzModel->model,32);
}

/*
void TestGetHZDot(void)
{
    uchar xdata ucDataBuff[32];
    uchar *ucDispString;
    code uchar ucCodeString[] ="古道热肠"; 
    uint uiHZCode;
    
    ucDispString = ucCodeString;
    while(*ucDispString != '\0')
    {
        uiHZCode = *ucDispString++;
        uiHZCode <<=8;
        uiHZCode += *ucDispString++;

        GetHZDot(uiHZCode,ucDataBuff);
    }

}
*/

//-----------------------------------------------------------

//备注:用二分法查找会提高查找速度,但字库文件要先排序.

相关帖子

沙发
古道热肠|  楼主 | 2008-8-23 17:11 | 只看该作者

程序运行后的效果图

//下面的这段代码产生的效果图,够方便吧.

//熄灭指示灯
        LedOff(LED1);    
        LedOff(LED2);            
        LedOff(LED3);            
//LCD开始接管显示
        LCD_ClearScreen();
        LcdShowString_Reverse(0,0,"音乐欣赏");
        LcdShowString(1,0,"时钟管理");
        LcdShowString(2,0,"  游戏  ");
        ulDelayCount = 0;
        while(1)
        {
            uchar ucKeyValue;

            if(KbHit())
            {
                ucKeyValue = KbGet();
                BeepShort();
                switch(ucKeyValue)    
                {
                    case c_Key_Up:
                    case c_Key_Left:
                        if(ucMenuFuncIndex == 0)
                        {
                            ucMenuFuncIndex = 2;
                        }
                        else
                        {
                            ucMenuFuncIndex--;
                        }
                        break;
                    case c_Key_Down:
                    case c_Key_Right:
                        if(ucMenuFuncIndex == 2)
                        {
                            ucMenuFuncIndex = 0;
                        }
                        else
                        {
                            ucMenuFuncIndex++;
                        }
                        break;
                    case c_Key_Ok:        //按下确认键执行与菜单索引号对应的功能
                        BootMenu_FunctionEnter(ucMenuFuncIndex);
                        LCD_ClearScreen();        //清除屏幕残留背景。
                        break;
                     default:
                        BeepShort();
                        break;
                }
                //刷新显示屏
                switch(ucMenuFuncIndex)
                {
                    case 0:
                        LcdShowString_Reverse(0,0,"音乐欣赏");
                        LcdShowString(1,0,"时钟管理");
                        LcdShowString(2,0,"  游戏  ");
                        break;
                     case 1:
                        LcdShowString(0,0,"音乐欣赏");
                        LcdShowString_Reverse(1,0,"时钟管理");
                        LcdShowString(2,0,"  游戏  ");
                        break;
                     case 2:
                        LcdShowString(0,0,"音乐欣赏");
                        LcdShowString(1,0,"时钟管理");
                        LcdShowString_Reverse(2,0,"  游戏  ");
                        break;
                      default:
                        LcdShowString_Reverse(0,0,"音乐欣赏");
                        LcdShowString(1,0,"时钟管理");
                        LcdShowString(2,0,"  游戏  ");
                        break;
                }
                ulDelayCount=0;
            }
            else
            {
                ulDelayCount++;    
                if(ulDelayCount >0x7FF00)
                {
                    //启动待机画面
                    WaitForKeyPress();
                    //清延时计数器
                    ulDelayCount=0;

                    //刷新显示屏
                    LCD_ClearScreen();
                    switch(ucMenuFuncIndex)
                    {
                        case 0:
                            LcdShowString_Reverse(0,0,"音乐欣赏");
                            LcdShowString(1,0,"时钟管理");
                            LcdShowString(2,0,"  游戏  ");
                            break;
                         case 1:
                            LcdShowString(0,0,"音乐欣赏");
                            LcdShowString_Reverse(1,0,"时钟管理");
                            LcdShowString(2,0,"  游戏  ");
                            break;
                         case 2:
                            LcdShowString(0,0,"音乐欣赏");
                            LcdShowString(1,0,"时钟管理");
                            LcdShowString_Reverse(2,0,"  游戏  ");
                            break;
                          default:
                            LcdShowString_Reverse(0,0,"音乐欣赏");
                            LcdShowString(1,0,"时钟管理");
                            LcdShowString(2,0,"  游戏  ");
                            break;
                    }

                }
            }
        }
      }
}

使用特权

评论回复
板凳
电子尘埃| | 2008-8-23 18:52 | 只看该作者

好,顶了再看.论坛就需要这样的热心人与高手.

使用特权

评论回复
地板
xwj| | 2008-8-23 20:07 | 只看该作者

结尾判断应该用sizeof,可以快很多

而且,结尾判断应该放在else加指针里

并且,多次读数组的地方应该用缓存,可以避免反复的执行繁杂的读数组操作,以加快速度


使用索引方式的最大优势就是编程方便,可以直接用LcdShowString(0,0,"音乐欣赏");这样的方式来些程序,甚至能使用格式化字符串printf()、sprintf()来输出。


索引字库显示用结构体是很久以前的方法,当时还没有晓奇的、HzPrj.exe等软件,批量取模最方便的是HZDotReader,偶是用UltraEdit修改他的执行文件来增加索引的

但后来,大量方便的字模软件陆续出现,都有了生成索引的功能,
这时,软件生成索引的方式就有比较了,有的用结构数组,有的生成两个对应的数组分别放索引和字模

我个人觉得:使用独立的索引要比用结构体更方便快捷,毕竟间址指针加2、乘2比加34、乘34更容易获得优化,而且书写也更方便,更易理解阅读



PS:
3楼看懂了的话就说一声哦

使用特权

评论回复
5
icmap| | 2008-8-23 20:21 | 只看该作者

方法很好

 

使用特权

评论回复
6
huangqi412| | 2008-8-23 20:53 | 只看该作者

学习

使用特权

评论回复
7
电子尘埃| | 2008-8-23 21:39 | 只看该作者

还没有仔细看呢.应该可以看的懂.


比处理Ascii麻烦多了,

xwj大侠

我用你说的方法.我再试一下,然后把他写出来,你帮我指点指点好吗?

/*-----------------------------------------------------------------

功能:    显示一个 Ascii码Asc8X16E
说明:    *ptr指向待显示字编码的首地址
        z 为显示方向 TRUE 为正向显示
                x为要显示的横坐标
                y为要显示的纵坐标
                x,y最大值为14,0为起始值
        x大于7时为右屏否则为左屏
-----------------------------------------------------------------*/
void Display_Asc(INT8U n,BOOL z,INT8U x,INT8U y)
{
        INT8U i,j;
        INT8U *ptr_Asc;
        INT16U k;

        if ( n != 0 ) n -= 32;
        k = (INT16U)n;
        k <<= 4;
        ptr_Asc = nAsciiDot;
        ptr_Asc +=k;
        if ( z == TRUE ) {
                if ( x>7 ) {
                        x -= 8;
                        LCDR;
                }
                else LCDL;
                x = ( 0x40 + (x<<3) );
                y = ( 0xb8 + (y<<1) );
                for ( j=0;j<2;j++ ) {
                        CLR_RS;//LCD_RS=0;
                        WritesLCD(y + j);               //页面地址设置(每页分8行,共8页)
                        WritesLCD(x);           //列地址设为0
                        SET_RS;//LCD_RS=1;        //写数据
                        for ( i=8;i>0;i-- ) WritesLCD(pgm_read_byte(ptr_Asc++));
                }
        }
        else {
                if ( x>7 ) {
                        x -= 8;
                        LCDL;
                }
                else LCDR;
                x = 7 - x;      
                y = 3 - y;
                x = ( 0x40 + x*8);
                y = ( 0xb8 + y*2 );
                ptr_Asc += 15;
                for ( j=0;j<2;j++ ) {
                        CLR_RS;//LCD_RS=0;
                        WritesLCD(y + j);               //页面地址设置(每页分8行,共8页)
                        WritesLCD(x);           //列地址设为0
                        SET_RS;//LCD_RS=1;        //写数据
                        for ( i=8;i>0;i-- )    WritesLCD( ReversalFun(pgm_read_byte(ptr_Asc--)) );
                }
        }
}

使用特权

评论回复
8
电子尘埃| | 2008-8-23 22:42 | 只看该作者

起码看懂了还是要用子函数去找的.并且还很麻烦

使用特权

评论回复
9
电子尘埃| | 2008-8-23 23:34 | 只看该作者

接xwj高人的前半部份重弄一下.让菜菜鸟也看懂

我理解错了天经地义.哈哈,理解错了,就有人更正.这也不失两位高人的好意.
bool GetHzModelInMem(uint uiHZCode,HZ_MODEL  ** pHzModel)
{
        //顺序查找法

        uint uiIndex = 0;

        while ( 1 ) {
                if ( ZK_Data[uiIndex].uiHZcode == uiHZCode ) {
                        //-找到地址
                        *pHzModel = (HZ_MODEL *)&(ZK_Data[uiIndex]);
                        return(true);
                }
                else {
                        uiIndex++;
                        if ( uiIndex > 字个数 )
                                //不要每次都比较,,可以提速
                                return(false);
                }
        }
}

使用特权

评论回复
10
电子尘埃| | 2008-8-23 23:38 | 只看该作者

使用独立的索引要比用结构体更方便快捷

独立的索引怎么弄还是不明白噢,
把这个好贴顶臭了,没人骂我吧.

使用特权

评论回复
11
xwj| | 2008-8-23 23:43 | 只看该作者

顺便提一下:相当讨厌while(1)这样的写法

严格限制一个入口对应一个出口,限制循环的次数,这对减少程序的BUG绝对有好处

使用特权

评论回复
12
电子尘埃| | 2008-8-23 23:56 | 只看该作者

bool GetHzModelInMem(uint uiHZCode,HZ_MODEL  ** pHzModel)
{
        //顺序查找法

        uint uiIndex;
        bool bResultFlag = 0;

       for( uiIndex = 0;uiIndex<  字个数 ;uiIndex++) {
                if ( ZK_Data[uiIndex].uiHZcode == uiHZCode ) {
                        //-找到地址
                        *pHzModel = (HZ_MODEL *)&(ZK_Data[uiIndex]);
                        ResultFlag = true;
                        break;
                }
       }
       returnb(ResultFlag);
}
//越来越简洁了.可这样比上面多判断了几次.
你还没有跟我说如何独立用索引呀?

使用特权

评论回复
13
xwj| | 2008-8-23 23:59 | 只看该作者

唉,第几次说了?

去下个HZDotReader

使用特权

评论回复
14
电子尘埃| | 2008-8-24 00:22 | 只看该作者

下了嘛.

就是不知道如何把索引与码表联系在一起呀

使用特权

评论回复
15
bob.xue| | 2008-8-24 08:43 | 只看该作者

签名mark

日后再详看

使用特权

评论回复
16
jack.king| | 2008-8-24 10:54 | 只看该作者

能不能说具体点!

大侠们能不能清楚点啊!
  近来我也在用这个东西看了大侠发的东西,觉得我的方法太笨了!
  可是你们说的方法我又有点不能理解!太蠢了 不好意思!
  

使用特权

评论回复
17
wayner| | 2008-8-24 13:41 | 只看该作者

好东西

使用特权

评论回复
18
古道热肠|  楼主 | 2008-8-24 17:09 | 只看该作者

回电子尘埃

您的那个ASC_Disp没有分层驱动,与硬件关联得太紧,这样扩充起来很不方便.

使用特权

评论回复
19
古道热肠|  楼主 | 2008-8-24 17:12 | 只看该作者

xwj提出的优化方法很有道理,俺抽空试试

结尾补充0xFFFF可以在查找汉字没找到时,在液晶屏上显示一实心方块,很快就知道该补充哪些汉字到字库中去了.

使用特权

评论回复
20
古道热肠|  楼主 | 2008-8-24 17:15 | 只看该作者

<原创>再来一个生成汉字库的工具软件源代码.

//用于将16*16点阵汉字字符对应的点阵数据转存到数组.
//功能说明:将需转换的所有字符存入特定文件中,启动本软件,完成转换
//转换完成后,提示保存数据的文件名,输入目标文件名即可
//最后修订日期:2007年7月8日
//修订者:古道热肠
//修订日期:2008年2月11日
//增加了生成的C文件的头文件包含定义内容,便于直接给Keil项目使用

#include<dos.h>
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
#include<process.h>


#define  NUL         0x00
#define  TO_NOT_EOF     0
#define  TO_EOF        -1

#define bool unsigned char
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long

#define  TRUE           1
#define  FALSE          0
#define true 1
#define false 0

static  char  ToLine[300];
static  char  ToLineRd[300];
int stat;
#define c_MaxCharNumber   6000;

uchar ZKDataBuff[6000];
uint  uiTotalChar;

FILE *Src;                //文件指针

static int ToRdLine(void)
{
     char *ptr;

     if (fgets(ToLine, 200, Src) != NULL)
     {
            //Remove the newline character
            ptr = strchr(ToLine, '\n');
            if (ptr != NULL)
            {
            //*(ptr--) = NUL;
                ToLine[ptr-ToLine] = NUL;
            }
            strcpy(ToLineRd, ToLine);

            return (TO_NOT_EOF);
    }
    else
    {
        return (TO_EOF);
    }
}


void AddCharToBuff(uchar *num)
{
    uint uiCount;

    for(uiCount=0; uiCount<uiTotalChar;)
    {
        if((ZKDataBuff[uiCount] == num[0]) && (ZKDataBuff[uiCount+1] == num[1]))
        {
            return;
        }
        else
        {
            uiCount += 2;
        }
    }

    if(uiCount == uiTotalChar)
    {
        ZKDataBuff[uiTotalChar] = num[0];
        ZKDataBuff[uiTotalChar+1] = num[1];
        uiTotalChar += 2;
    }
    else
    {

    }
}

//将输入文件的字符进行过滤,去除重复字符后
//汇总字符内容到内部临时数组
bool FilterChar(char *fInFile)
{
    unsigned char now[2];
    char *str;
    unsigned int i;

    if((Src = fopen(fInFile,"r")) == NULL)
    {
        printf("Open File %s error!\n",fInFile);
        return false;
    }

    uiTotalChar  =0;

    //读一行
    stat = ToRdLine();

    while(stat != TO_EOF)
    {
        i = 0;
        str = ToLineRd;
        while(str!='\x0')
        {
            now[0]=str;
            now[1]=str[i+1];

            AddCharToBuff(now);
            i += 2;
        }
        stat = ToRdLine();
    }
    return TRUE;
}

void Hzks_File2(char *fInFile,char *fOutFile)
{
    FILE *in;
    FILE *out;
    FILE *ZKCodeFile;


    char ch0,ch1;
    long fpos;
    unsigned char bitdata[32];
    unsigned char now[2];
    int i=0;
    char *str;
    unsigned char uci;
    char ucDataBuff[16];
    unsigned int uiHZInsideCode;

    if((in=fopen("hzk16","rb"))==NULL)
    {
        printf("Open File hzk16 error!\n");
        exit(0);
    }

    //生成二进制数据文件,用于将字库保存到存储器中时使用
    if((out=fopen(fOutFile,"wb"))==NULL)
    {
        printf("Open file %s error!\n",fOutFile);
        exit(0);
    }

    strcpy(ucDataBuff,fOutFile);
    strcat(ucDataBuff,".c");

    //生成字库代码文件,用于将字库的内容编译成Code
    if((ZKCodeFile = fopen(ucDataBuff,"wb"))== NULL)
    {
        printf("Open file %s error!\n",ucDataBuff);
        exit(0);
    }
    //数据从输入文件注入内存,并清除重复字符
    FilterChar(fInFile);


    //启动输出过程
    fprintf(ZKCodeFile,"#include \"ZKFunc.h\" \r\n\r\n");

    fprintf(ZKCodeFile,"code HZ_MODEL ZK_Data[]=\r\n{\r\n");


    i = 0;
     while(i< uiTotalChar)
    {
    //    int offset=0,;
        char str1[2];
        unsigned char ucCount;
        unsigned char ucDebugDataBuff[32];

        now[0]=ZKDataBuff;
        now[1]=ZKDataBuff[i+1];
        ch0=ZKDataBuff;
        ch1=ZKDataBuff[i+1];


        fpos=32L*(((unsigned char)ch0-161)*94+((unsigned char)ch1-161));

        fseek(in, fpos, SEEK_SET);
        fread( bitdata, 32, 1, in);
        //
        fwrite(now,2,1,out);
        fwrite(bitdata,32,1,out);

        uiHZInsideCode = now[0]*0x100 + now[1];
        fprintf(ZKCodeFile,"\t{\t0x%04X,  //%c%c\r\n",uiHZInsideCode,now[0],now[1]);
        fprintf(ZKCodeFile,"\t\t0x%02X,",bitdata[0]);

        for(ucCount=1; ucCount<15;ucCount++)
        {
            fprintf(ZKCodeFile,"0x%02X,",bitdata[ucCount]);
            sprintf(ucDebugDataBuff,"0x%02X,",bitdata[ucCount]);
        }
        fprintf(ZKCodeFile,"0x%02X,\r\n",bitdata[15]);

        fprintf(ZKCodeFile,"\t\t0x%02X,",bitdata[16]);
        for(ucCount=17; ucCount<31;ucCount++)
        {
            fprintf(ZKCodeFile,"0x%02X,",bitdata[ucCount]);
            sprintf(ucDebugDataBuff,"0x%02X,",bitdata[ucCount]);
        }
        fprintf(ZKCodeFile,"0x%02X},\r\n\r\n",bitdata[31]);

        i=i+2;
    }
    //最后一个字符的处理,用于程序找不到对应的点阵时获取的数据
    {
        unsigned char ucCount;

        fprintf(ZKCodeFile,"\t{\t0x%04X,  //字库结尾标志符\r\n",0xFFFF);
        fprintf(ZKCodeFile,"\t\t0x%02X,",0xff);

        for(ucCount=1; ucCount<15;ucCount++)
        {
            fprintf(ZKCodeFile,"0x%02X,",0xff);
        }
        fprintf(ZKCodeFile,"0x%02X,\r\n",0xff);

        fprintf(ZKCodeFile,"\t\t0x%02X,",0xff);
        for(ucCount=17; ucCount<31;ucCount++)
        {
            fprintf(ZKCodeFile,"0x%02X,",0xff);
        }
        fprintf(ZKCodeFile,"0x%02X},\r\n\r\n",0xff);
    }

    fprintf(ZKCodeFile,"};   //end\r\n");

    {
        struct date CurrentDate;
        struct  time CurrentTime;

        fprintf(ZKCodeFile,"//总的有效字符数为%d\r\n",uiTotalChar/2);
        getdate(&CurrentDate);
        gettime(&CurrentTime);

        fprintf(ZKCodeFile,"//字库生成日期为:%d年%d月%d日\r\n",CurrentDate.da_year,CurrentDate.da_mon,CurrentDate.da_day);
        fprintf(ZKCodeFile,"//字库生成时间为:%02d时%02d分%02d秒\r\n",CurrentTime.ti_hour,CurrentTime.ti_min,CurrentTime.ti_sec);
        fprintf(ZKCodeFile,"//程序开发者:古道热肠,感谢您的使用!\n");
        fprintf(ZKCodeFile,"//作者联系邮箱:xg_2004_sy@126.com");
     }

    now[0] = 0xff;
    now[1] = 0xff;
    memset(bitdata,'\xff',32);
    fwrite(now,2,1,out);
    fwrite(bitdata,32,1,out);

    fclose(in);
    fclose(Src);
    fclose(out);
    fclose(ZKCodeFile);

    printf("change success,Total HZ char is:%d \n",(uiTotalChar/2));
    printf("Press any key to end!");
    for(uci=0; uci<100;uci++)       //Max delay time is 10 second;
    {
        if(kbhit())
        {
            break;
        }
        delay(100);
    }
    clrscr();
}


void main(void)
{
//    char *str="游戏";
    unsigned char fNameInPut[20] ="sstring.txt";
    unsigned char fNameOutPut[20];

    //printf("\nPlease Input Source file to Input:");
     //scanf("%s\h",fNameInPut);

    printf("\nPlease Input Destination file to output:");
     scanf("%s\h",fNameOutPut);


    Hzks_File2(fNameInPut,fNameOutPut);
}

使用特权

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

本版积分规则

284

主题

6411

帖子

16

粉丝