打印

晕~~~参与了就要**到底啊,怎么能因为他人的一句话就轻

[复制链接]
22175|107
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
芯行天下|  楼主 | 2009-3-5 08:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这是我在一个项目中用到的T9拼音输入法,基本实现在GB2132的全部输入,多音字的输入处理,标点,拼音,数字等。
本输入法检索快,效率高,字库全,是在一般嵌入式系统中有很好的应用。
字库编码部分较长,没有贴出来,可以下载源码包。请大家下载使用,但要保持magicchip原创。

T9拼音输入法源码下载:https://bbs.21ic.com/upfiles/img/20093/200932711246603.rar
贪吃蛇源码下载:https://bbs.21ic.com/upfiles/img/20093/2009327112542318.rar
俄罗斯方块源码包(有BUG):https://bbs.21ic.com/upfiles/img/20093/2009331105428542.rar

大家如果觉得这些东西对自已有用,就顶一下本贴,也算是对我的支持!!!!!!!

/*******************************************************************************
**功能:输入法索引程序
**创建:magicchip
**日期:20080509
*******************************************************************************/
void py_index_sub(void)
{
    uint8 i;
    uint8 flag = 0x55;
    uint32 temp;
    uint8 mblentemp;
    mblentemp = t9pyfun.mblen;

    t9pyfun.mblen = 0x00;
    if ((t9pyfun.pysrf == T9PY) && (t9pyfun.firstno != ' '))           //拼音输入法
    {
       for (i=0;i<t9PY_indexlen[t9pyfun.firstno];i++)
       {
              if (t9pyfun.t9py == (*(t9PY_index_headno[t9pyfun.firstno]+i)).t9PY)
           {
                  t9pyfun.mblen++;
               flag = 0xaa;
               t9pyfun.t9PY_addr = (t9PY_index_headno[t9pyfun.firstno]+i);
               for (i++;i<t9PY_indexlen[t9pyfun.firstno];i++)
               {
                     if (t9pyfun.t9py == (*(t9PY_index_headno[t9pyfun.firstno]+i)).t9PY)
                      t9pyfun.mblen++;
                  else 
                      break;
               }
               break;
           }
       }
       if (flag == 0x55)           //没有查找完全对应的拼音组合,
       {
             for (i=0;i<t9PY_indexlen[t9pyfun.firstno];i++)
             {
                 temp = (*(t9PY_index_headno[t9pyfun.firstno]+i)).t9PY;
              while (temp > t9pyfun.t9py)
              {
                 temp >>= 4;
                 if (temp == t9pyfun.t9py)
                 {
                     t9pyfun.t9PY_addr = t9PY_index_headno[t9pyfun.firstno]+i;
                    t9pyfun.mblen++;
                    i = t9PY_indexlen[t9pyfun.firstno];
                    flag = 0xaa;
                    break;
                 }
              }             
          }
          if (flag == 0x55)
          {
                 t9pyfun.t9py >>= 4;
                 t9pyfun.mblen = mblentemp;
           }
       }
       
    }
    else if(t9pyfun.pysrf == T9SZ)             //数字输入
    {
        t9pyfun.mblen++;
        t9pyfun.t9PY_addr = &t9PY_sz[t9pyfun.firstno];
    }
    else if(t9pyfun.pysrf == T9BD)            //标点输入
    {
        t9pyfun.mblen++;
        t9pyfun.t9PY_addr = t9PY_index0;
    } 
    else if(t9pyfun.pysrf == T9DX)            //大写英文字母输入
    {
        if ((t9pyfun.firstno>1)&&(t9pyfun.firstno<10))
        {
            t9pyfun.mblen++;
            t9pyfun.t9PY_addr = &t9PY_ABC[t9pyfun.firstno];
        }
    } 
    else if(t9pyfun.pysrf == T9XX)            //小写英文字母输入
    {
        if ((t9pyfun.firstno>1)&&(t9pyfun.firstno<10))
        {
            t9pyfun.mblen++;
            t9pyfun.t9PY_addr = &t9PY_abc[t9pyfun.firstno];
        }
    }
}


uint16   straddrx;        //字符显示位置
uint16     straddry;
uint16   t9pyaddrx;        //拼音显示位置
uint16   t9pyaddry;
uint16   indexaddrx;    //索引显示位置
uint16   indexaddry;
uint8    indexdata;     //索引值,也即选出的字在索引表中的位置.

uint8    hzbuff[512];   //输入256个汉字
uint16   hzlen;         //输放汉字的个数
uint16   hzin;          //往缓冲区输入汉字的位置
uint16   hzout;         //从缓冲区取出汉字的位置

#define  indextablen    15  //每次显示索引处的长度,最大值为15个汉字。


/*********************************************************************************************************
** create by :           magicchip
** create data:          2008-06-04
** 输入数数: 
** 功能:    显示输入法
** 入口参数:
** 出口参数:      
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void dispsrf(void)
{
    const uint8 *strsrf[] = {"标点","大写","小写","拼音","数字"};
    const uint8 disp_srf[] = "输入法:";    
    
    SetFgColor(RED);
    SetBgColor(TIANLANSE);
    SetCharCoord(SRF_X,SRF_Y);    

    PrintGB((uint8*)disp_srf,4);
    PrintGB((uint8*)strsrf[t9pyfun.pysrf],2);
}

/*********************************************************************************************************
** create by :           magicchip
** create data:          2008-06-04
** 输入数数: 
** 功能:    显示字符处光标和拼音处光标
** 入口参数:
** 出口参数:      
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void dispgb(uint16 gbchar)
{
    SetFgColor(RED);
    SetBgColor(TIANLANSE);
    SetCharCoord(straddrx,straddry);
    PrintoneASCII(gbchar);
    SetCharCoord(t9pyaddrx,t9pyaddry);
    PrintoneASCII(gbchar);
}

/*********************************************************************************************************
** create by :           magicchip
** create data:          2008-06-11
** 输入数数: 
** 功能:    显示输入的内容
** 入口参数:
** 出口参数:      
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void dispsf(void)
{
    uint8 i=0,j=0;
    SetFgColor(RED);
    SetBgColor(TIANLANSE);
    
    if (hzlen > 0)               //缓冲区内有显示的内容
    {
        SetCharCoord(straddrx,straddry);
        while(1)
        {
            if (hzbuff[hzout] > 0x80)   //显示汉字
            {
                PrintoneGB(&hzbuff[hzout]);                
                hzout += 2;
                straddrx += 16;
                if (straddrx > 304)
                {
                    straddrx = 0;
                    straddry += 16;
                    if (straddry > 223)
                    {
                        straddry = 16;
                        SetFgColor(TIANLANSE);
                        Draw_Rect(0x27,0,16,319,223);        //清除显示区域
                        SetFgColor(TIANLANSE);
                    }
                    SetCharCoord(straddrx,straddry);                    
                }
            }
            else if (hzbuff[hzout] > 0)  // 显示ASC
            {
                PrintoneASCII(hzbuff[hzout]);                
                hzout ++;
                straddrx += 8;
                if (straddrx > 312)
                {
                    straddrx = 0;
                    straddry += 16;
                    if (straddry > 223)
                    {
                        straddry = 16;
                        SetFgColor(TIANLANSE);
                        Draw_Rect(0x27,0,16,319,223);         //清除显示区域
                        SetFgColor(TIANLANSE);
                    }
                    SetCharCoord(straddrx,straddry);                    
                }
            }
            else
                break;
        }
                
    }

    t9pyaddrx = 0;    
    SetCharCoord(t9pyaddrx,t9pyaddry);
    PrintASCII("                                        ");
    if (t9pyfun.mblen > 0)            //索引内容
    {
        t9pyaddrx = 0;
        SetCharCoord(t9pyaddrx,t9pyaddry);
        while(t9pyfun.t9py >> (4*i))                  //显示索引拼音
        {
            PrintoneASCII(*((*t9pyfun.t9PY_addr).PY+i));
            i++;
            t9pyaddrx += 8;            
        }

        if (*(*t9pyfun.t9PY_addr).PY_mb > 0x80)                   //显示汉字索引列表
        {
            if (!(*((*t9pyfun.t9PY_addr).PY_mb+indexdata*2)))    //设置开始显示索引汉字的位置.
            {
                indexdata = 0;
                i = 0;
            }
            else
                i = 2*indextablen*(indexdata/indextablen);
            SetCharCoord(indexaddrx,indexaddry);           //设置汉字索引表显示的位置.
            while(*((*t9pyfun.t9PY_addr).PY_mb+i))           //显示索引汉字
            {
            
                if (i/2 == indexdata)
                {
                     SetFgColor(WHITE);
                     SetBgColor(BLACK);
                     PrintoneGB((uint8*)(((*t9pyfun.t9PY_addr).PY_mb+i)));    
                     i += 2;
                     SetFgColor(RED);
                     SetBgColor(TIANLANSE);
                }
                else
                {
                    PrintoneGB((uint8*)(((*t9pyfun.t9PY_addr).PY_mb+i)));    
                    i += 2;
                }            
            
                j++;           //保证索引列表不溢出
                if (j >= indextablen)
                    break;            
            }
        }
        else        //标点或大小写字母索引显示
        {
            if (!(*((*t9pyfun.t9PY_addr).PY_mb+indexdata)))    //设置开始显示索引的位置.
            {
                indexdata = 0;
                i = 0;
            }
            else
                i = 2*indextablen*(indexdata/(2*indextablen));
            SetCharCoord(indexaddrx,indexaddry);           //设置索引表显示的位置.
            while(*((*t9pyfun.t9PY_addr).PY_mb+i))           //显示索引字符
            {
                if (i == indexdata)
                {
                     SetFgColor(WHITE);
                     SetBgColor(BLACK);
                    PrintoneASCII(*((*t9pyfun.t9PY_addr).PY_mb+i));    
                     i ++;
                     SetFgColor(RED);
                     SetBgColor(TIANLANSE);
                }
                else
                {
                    PrintoneASCII(*((*t9pyfun.t9PY_addr).PY_mb+i));
                    i ++;
                }            
            
                j++;           //保证索引列表不溢出
                if (j >= (2*indextablen))
                    break;
            }
        }            
    }
}

/*********************************************************************************************************
** create by :           magicchip
** create data:          2008-06-11
** 输入数数: 
** 功能:    初始化索引量,使之清0。
** 入口参数:
** 出口参数:      
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void clrindex(void)
{
    t9pyfun.firstno = ' ';       //初始输入数字按键为空
    t9pyfun.mblen = 0;           //初始码表长度为0
    t9pyfun.mbtimes = 0;       //索引切换次数为0
    t9pyfun.t9py = 0;           //初始按键组合为0
    indexdata = 0;
}

/*********************************************************************************************************
** create by :           magicchip
** create data:          2008-06-04
** 输入数数: 
** 功能:    汉字输入法任务
** 入口参数:
** 出口参数:      
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void T9pyTask(void *pdata)
{
    uint8 err;
    uint16 i;
    uint8 gbflag;
    void *key;
    pdata = pdata;

suspendt9pytask:
    OSTaskSuspend(T9pyTaskPrio); 
    ClearScreen(TIANLANSE);
    SetBgColor(TIANLANSE);

    hzlen = 0;
    hzin = 0;
    hzout = 0;
    for (i=0;i<512;i++)
        hzbuff = 0x00;

    clrindex();
    t9pyfun.pysrf = T9PY;       //初始输入法为拼音
    straddrx = 0;
    straddry = 16;
    t9pyaddrx = 0;
    t9pyaddry = 224;
    indexaddrx = 80;    //索引显示位置
    indexaddry = 224;
    dispsrf();
    
    OSMboxAccept(KeyMbox);                //清除按键
    while(1)
    {
        key = OSMboxPend(KeyMbox,50,&err);
        if (err == OS_NO_ERR)
        {
            if ((uint32)key == KEY_JH)           // 输入法切换
            {
                if ((++t9pyfun.pysrf) > T9SZ)
                    t9pyfun.pysrf = T9DX; 
                dispsrf();
            }
            else if ((uint32)key == KEY_XH)       // 输入标点符号,
            {
                 t9pyfun.mblen++;
                 t9pyfun.t9PY_addr = t9PY_index0;
                 dispsf();
            }
            else if (((uint32)key>=0x30) &&((uint32)key<=0x39))      //输入内容
            {
                if (t9pyfun.pysrf == T9PY)
                {
                    if (((uint32)key>=0x32) &&((uint32)key<=0x39))      //输入内容
                    {
                        t9pyfun.mbtimes = 0;
                        indexdata = 0;
                        if (t9pyfun.firstno == ' ')
                            t9pyfun.firstno = (uint32)key-0x30;
                        t9pyfun.t9py = ((t9pyfun.t9py<<4) | ((uint32)key - 0x30));
                        py_index_sub();
                        dispsf();
                        
                    }
                    else if ((uint32)key == T9N00)                      //索引切换.
                    {
                        t9pyfun.t9PY_addr++;
                        t9pyfun.mbtimes++;
                        indexdata = 0;
                        if (t9pyfun.mbtimes >= t9pyfun.mblen)
                        {
                            t9pyfun.mbtimes = 0;
                            t9pyfun.t9PY_addr -= t9pyfun.mblen;
                        }
                        dispsf();
                    }
                    else if ((uint32)key == T9N01)              //输入空格
                    {
                        if (hzlen < 255)
                        {
                            hzlen ++;
                            hzbuff[hzin++] = ' ';
                            hzbuff[hzin++] = ' ';
                            clrindex();
                            dispsf();
                        }
                    }
                }
                else if (t9pyfun.pysrf == T9SZ)                //输入数字
                {
                    if (hzlen < 255)
                    {
                        hzlen ++;
                        hzbuff[hzin++] = (uint32)key;
                        hzbuff[hzin++] = ' ';
                        clrindex();
                        dispsf();
                    }        
                }
                else if ((t9pyfun.pysrf == T9DX) || (t9pyfun.pysrf == T9XX)) //输入字母
                {
                    if (((uint32)key>=0x32) &&((uint32)key<=0x39))      //输入内容
                    {
                        if (t9pyfun.firstno == ' ')
                        {
                            t9pyfun.mbtimes = 0;
                            indexdata = 0;                        
                            t9pyfun.firstno = (uint32)key-0x30;
                            t9pyfun.t9py = ((t9pyfun.t9py<<4) | ((uint32)key - 0x30));
                            py_index_sub();
                            dispsf();
                        }                         
                    }
                    else if ((uint32)key == T9N01)              //输入空格
                    {
                        if (hzlen < 255)
                        {
                            hzlen ++;
                            hzbuff[hzin++] = ' ';
                            hzbuff[hzin++] = ' ';
                            clrindex();
                            dispsf();
                        }
                    }
                }                                            
            }
            else if ((uint32)key == KEY_LEFT)
            {
                if (t9pyfun.mblen > 0)
                {                                         
                    if (indexdata == 0)            //删除索引拼音    
                    {
                        if ((t9pyfun.t9py > 0) && (t9pyfun.pysrf == T9PY))
                        {
                            t9pyfun.t9py >>= 4;
                            if (t9pyfun.t9py == 0)
                                clrindex();
                            else
                                py_index_sub();
                            dispsf();
                        }
                        else 
                        {
                            clrindex();
                            dispsf();
                        }                    
                    }
                    else
                    {                        //索引汉字表左移
                        indexdata--;
                        dispsf();
                    }            
                }
                else if (hzlen > 0)           //删除输入的汉字.
                {
                    if (straddrx == 0)
                    {
                        straddrx = 304;
                        straddry -= 16;
                    }
                    else
                        straddrx -= 16;                        
                    hzlen--;
                    hzbuff[--hzin] = 0;
                    hzbuff[--hzin] = 0;
                    hzout -= 2;
                    SetCharCoord(straddrx,straddry);
                    PrintASCII("   ");
                }                
            }
            else if ((uint32)key == KEY_RIGHT)
            {
                if (t9pyfun.mblen>0)
                {
                    indexdata++;
                    dispsf();
                }    
            }
            else if ((uint32)key == KEY_ENTER)
            {
                if (t9pyfun.mblen>0)
                {
                    if (hzlen < 255)
                    {
                        if (*(*t9pyfun.t9PY_addr).PY_mb > 0x80)          //输入汉字
                        {
                            hzlen ++;
                            hzbuff[hzin++] = *((*t9pyfun.t9PY_addr).PY_mb+indexdata*2);
                            hzbuff[hzin++] = *((*t9pyfun.t9PY_addr).PY_mb+indexdata*2+1);
                            clrindex();
                            dispsf();
                        }
                        else               //输入字符
                        {
                            hzlen ++;
                            hzbuff[hzin++] = *((*t9pyfun.t9PY_addr).PY_mb+indexdata);
                            hzbuff[hzin++] = ' ';
                            clrindex();
                            dispsf();
                        }
                    }
                    else 
                    {
                        clrindex();
                        dispsf();
                    }                    
                }
    
            }
            else if ((uint32)key == KEY_MENU)
            {
                OSTaskResume(GuiTaskPrio);       //恢复GUI任务
                    goto suspendt9pytask;
            }
          &nb

相关帖子

沙发
jhanmeng| | 2009-3-5 09:19 | 只看该作者

顶顶顶!

有见地,水平就是高,厉害,佩服!佩服!顶!

使用特权

评论回复
板凳
飞090305| | 2009-3-5 09:26 | 只看该作者

顶一个

大家多顶!!

使用特权

评论回复
地板
芯行天下|  楼主 | 2009-3-5 09:31 | 只看该作者

大家不要光顶呀,要谈一下各自已的心得体会呀

大家不要只顶呀,要多谈谈自已呀。

使用特权

评论回复
5
飞090305| | 2009-3-5 09:34 | 只看该作者

个人调试小技巧

1. 中断服务程序要尽可能的简单

   同时考虑到性能和维护,中断服务程序必须要尽可能的简单。与生俱来的异步特性使得中断服务程序的调试要比通常的程序难了许多。让其做的事情尽可能少对于维护程序来说就尤为重要。把ISR中的数据处理移到主程序中,这样ISR可以解放出来去仅仅抓取数据(例如从硬件设备)并把数据放到临时buffer中以备用。可以用一个标志来通知主程序数据待处理。

2.将所有定义放在一个地方

  这个简单;如果有大量的常量定义或者条件定义,把他们集中放置。可以是一个单独文件或者源代码路径。如果你把定义深深隐藏在代码中,它会让你吃苦头的。

3.把调式代码从源文件中移除

  在开发过程中,你可能会加入大量的调式代码,例如冗长的文本输出,断言,LED闪烁等等。当项目结束,就应当把这些代码清除掉,尤其是那些随意加入的调式代码。

清扫代码是一个高尚的工作,但去掉调试信息也可能带来的问题。维护代码的兄弟将可能会加入产生这些代码,如果代码已经有了,就会使得维护变得容易。如果这些代码需要在产品构建的时候去掉,使用条件编译或者把调试代码放进中介模块或者库中,并保证不会链接到产品中去。最初的开发应当考虑到编写文档和清理调式代码的时间;这些额外的时间将会物有所值。





使用特权

评论回复
6
芯行天下|  楼主 | 2009-3-5 09:43 | 只看该作者

回5楼

回5楼,关于5楼的关点,我来说几句。

1:中断尽量短,这个我同意。

2:编程时要考虑程序的可移植性,一个类型的文件放在一起,单独建立一个文件夹,用于保存,定义两个文件,一个源文件,.C,一个头文件.H。这样便于移植。

3:调试代码在编写时可以加入预编译,这样当生成最终程序时,只需把预编译去掉就行了。如果将来还想调试,只需加上预编译就行了。

使用特权

评论回复
7
lost1421| | 2009-3-5 10:01 | 只看该作者

路过

大家继续!

使用特权

评论回复
8
救火车| | 2009-3-5 10:17 | 只看该作者

路过,顶一个!!

使用特权

评论回复
9
zizzfish| | 2009-3-5 14:23 | 只看该作者

对于第二个问题

2:函数指针在查表跳转中的应用。
直接调用(*funaddr[no])();而不用在声明一个指针函数,省了几个RAM。
另外,指针函数可以有参数的。

使用特权

评论回复
10
芯行天下|  楼主 | 2009-3-5 14:59 | 只看该作者

传递参数

楼上很细致,是可以省掉几个RAM,但是如果传递参数的话,给所有调用函数传递的参数数量,类型要一至才行。不然还是没有办法传递的。

使用特权

评论回复
11
古道热肠| | 2009-3-5 15:26 | 只看该作者

不一致的参数怎么没办法传递呢,用指针强制转换

入口统一定义为,短参数+长参数+数据字符指针,看GUI代码时经常这么做的.

使用特权

评论回复
12
bjc125| | 2009-3-5 16:21 | 只看该作者

路过 学习中

谢谢

使用特权

评论回复
13
llh_kf1100| | 2009-3-5 22:34 | 只看该作者

路过

学习中。。。

使用特权

评论回复
14
McuPlayer| | 2009-3-5 22:47 | 只看该作者

看到这句话我真欣慰,欧耶

“清扫代码是一个高尚的工作”

我现在就在清扫调试期间留下的一个大堆的调试代码。
到了这个阶段,一般案子快结束了,离收款也近了一大步。

使用特权

评论回复
15
HotC51| | 2009-3-5 22:58 | 只看该作者

去掉“技巧”二字~~~

使用特权

评论回复
16
原野之狼| | 2009-3-5 23:42 | 只看该作者

帮顶~

第一种方法,只有
While(1);
调试内容往哪写呢?
楼主一般如何做。。。

使用特权

评论回复
17
Airwill| | 2009-3-6 00:35 | 只看该作者

就这也算得技巧和优化?


抄来这么一点点吧, 还这么多人奉承! 

估计象 hotpower 等大虾们见了, 鼻子气歪了. 
我们的论坛谈了这么久的这类话题, 居然众人还是没有多少进步!

使用特权

评论回复
18
芯行天下|  楼主 | 2009-3-6 08:22 | 只看该作者

回16楼

#ifdef  SOFT_DEBUG_EN
void assert_failed(uint8* file, uint32 _line,uint32 data)
{
  while(1); 
  {
    
  }
}
#endif  // end of SOFT_DEBUG_EN

调试内容写在  
while(1); 
  {
    
  }
内部,你可以写你需要的程序,比如通过串口把错误信息输出,或者能过LCD把错误信息显示出来。

使用特权

评论回复
19
程序匠人| | 2009-3-6 08:49 | 只看该作者

关于“将所有定义放在一个地方”

2.将所有定义放在一个地方

  这个简单;如果有大量的常量定义或者条件定义,把他们集中放置。可以是一个单独文件或者源代码路径。如果你把定义深深隐藏在代码中,它会让你吃苦头的。
------------------------------------------

匠人以往也是这个习惯。最近在重新思考这个问题。

把所有定义放在一起的好处(匠人称之为“公共头文件”——具体理解,可以参考“公共厕所”),上文已经说了。但是这种方式也有缺点,就是不利于各个模块文件的移植。比如说你要把以前另一个项目的LCD程序拿过来用,不但要把对应的lcd.C 和lcd.h 文件复制过来,还要到“公共头文件”另外去复制那些与lcd有关的定义。

但是如果不把所有定义放在一起,查找起来又不方便。

使用特权

评论回复
20
程序匠人| | 2009-3-6 09:19 | 只看该作者

关于调试(测试)代码,匠人的习惯做法

1、测试代码顶格写;
2、如果是汇编程序,则正常代码统一用大写,测试代码用小写;
3、测试代码后面加注释“test”字样

等到程序竣工时,用UE搜索所有程序中的关键字“test”,然后根据实际需要决定删除或保留

使用特权

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

本版积分规则

87

主题

660

帖子

0

粉丝