📄 t9_dx51.c
字号:
//**********************************************************************************
//本函数模块作者:喜用火 yangj@xwtech.com xyh_mcu@sina.com
//版本v1.0
//本程序专为"DX-51多功能试验板"设计
//**********************************************************************************
//"DX-51多功能试验板"的"T9拼音输入法"函数模块
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#include <reg52.h>
#include "study.h"
//**********************************************************************************
#include <string.h>
uchar xdata KeyBuf[8]; //按健数码缓冲区
uchar xdata PYBuf[12][8]; //拼音组合缓冲区
uchar xdata HZBuf[12]; //汉字待选缓冲区
uchar xdata HZOut[32]; //汉字选中缓冲区(2行合计16字空间)
uchar xdata HZSave[160]; //汉字保存缓冲区(5页合计80字空间)
//键盘分配组合表在FLASH中,从0x3b500开始...[8][5]={{"abc"},{"def"},{"ghi"},{"jkl"},{"mno"},{"pqrs"},{"tuv"},{"wxyz"}};
#define KeyPY 0x3b500
//拼音输入法首字母索引表
ulong code PY_index_headletter[26+1]={ 0x3A840,0x3A868,0x3A8E8, 0x3A9F8,0x3AAA8,0x3AAC8,
0x3AB10,0x3ABA8,0x3AC40, 0x3AC40,0x3ACB0,0x3AD40, 0x3AE10,0x3AEA8,0x3AF68,
0x3AF78,0x3B000,0x3B070,0x3B0E0, 0x3B1F8,0x3B298,0x3B298, 0x3B298,0x3B2E0,0x3B350,0x3B3C8,
0x3B4F0 };
//拼音输入法二级字母索引表(index)在FLASH中,从0x3a840+1开始...
//拼音输入法汉字排列码表(mb)在FLASH中,从0x3b528开始...
#define MBStart 0x3b528
//**********************************************************************************
void KeyBuf_clear() //按健缓冲区清零(有效值:2~9)
{
uchar i;
for(i=0;i<8;i++)
{
KeyBuf[i]=0;
}
}
//**********************************************************************************
void PYBuf_clear() //拼音组合缓冲区清零
{
uchar i,j;
for(i=0;i<12;i++)
{
for(j=0;j<8;j++)
PYBuf[i][j]=0;
}
}
//**********************************************************************************
void HZBuf_clear() //汉字待选缓冲区清零(6字空间)
{
uchar i;
for(i=0;i<12;i++)
{
HZBuf[i]=0x2e; //'.'
}
}
//**********************************************************************************
void HZOut_clear() //汉字选中缓冲区清零(16字空间)
{
uchar i;
for(i=0;i<32;i++)
{
HZOut[i]=0;
}
}
//**********************************************************************************
void HZSave_clear() //汉字保存缓冲区清零(80字空间)
{
uchar i;
for(i=0;i<160;i++)
{
HZSave[i]=0;
}
}
//**********************************************************************************
ulong GetChnStr(uchar *Input_py_str,uchar *PYCount)
{ //返回值:最终汉字的码表地址或指向第一个相符合的拼音的index地址
//PYCount:通过这个值来指示共有几个拼音组合符合要求
ulong xdata cpHZ,cpHZedge,address,pHZ=0;
uchar xdata py_qw[2]; //用来存放拼音的一个韵母或一个汉字的区位码
uchar i,InputStrLength;
if(Input_py_str[0]==0)return(0);
InputStrLength=strlen(Input_py_str); //输入拼音串长度
cpHZ=PY_index_headletter[Input_py_str[0]-'a']; //查首字母(声母)索引
cpHZedge=PY_index_headletter[Input_py_str[0]-'a'+1]; //设置拼音声母界限
cpHZ++; //指向字母索引表中第二个字母
Input_py_str++; //指向键入的拼音的第二个字母
while(cpHZ<cpHZedge) //索引表不超界
{
for(i=0;i<InputStrLength;i++)
{
if(*(Input_py_str+i)==0)//if((*(Input_py_str+i)==0)&&(py_qw[1]==0x20))
{
if(PYCount==0)
{
address=cpHZ+5;
readeprom(address,py_qw,2);
address=py_qw[0]+py_qw[1]*256+MBStart;
return (address); //返回最终汉字的码表地址
}
if(pHZ==0)
pHZ=cpHZ-1;
(*PYCount)++; //指示共有几个拼音组合符合要求
}
readeprom(cpHZ+i,py_qw,2);
if(*(Input_py_str+i)!=py_qw[0])
break; //发现字母串不配,退出
}
cpHZ+=0x08;
}
return(pHZ); //返回指向第一个相符合的拼音的index地址
}
//**********************************************************************************
void T9Key(uchar *KeyBuf) //按键对应的字母经检索组合成有效的拼音
{ //输入:已键入的按键数码KeyBuf[8]
//返回:指向PYBuf[12][8]的二维数组,PYBuf[i][7]=1代表该拼音组合有效
uchar i,j,k;
ulong xdata pPY; //键盘--字母对应表地址
uchar xdata c0,c1,c2,c3,c4,c5;
uchar xdata ABC[6][5]; //存放按键对应的字母
PYBuf_clear(); //拼音组合缓冲区清零
for(i=0;i<6;i++) //键盘分配缓冲清零
{
for(j=0;j<5;j++)
ABC[i][j]=0;
}
for(k=0;KeyBuf[k]!=0;k++)//取出键盘分配表给ABC[6][5]
{
pPY=KeyPY+(KeyBuf[k]-2)*5;
readeprom(pPY,ABC[k],5);
}
if(k==0)return;
i=0;k--;
for(c0=0;ABC[0][c0]!=0;c0++)
{
if(ABC[0][c0]=='i'||ABC[0][c0]=='u'||ABC[0][c0]=='v') //第一个拼音上不可能的字母
continue;
PYBuf[i][0]=ABC[0][c0]; //第一位拼音字母
if(k>=1) //有2个拼音时
{
for(c1=0;ABC[1][c1]!=0;c1++)
{
PYBuf[i][1]=ABC[1][c1]; //第二位拼音字母
if(k>=2) //有3个拼音时
{
for(c2=0;ABC[2][c2]!=0;c2++)
{
PYBuf[i][2]=ABC[2][c2];
if(k>=3) //有4个拼音时
{
for(c3=0;ABC[3][c3]!=0;c3++)
{
PYBuf[i][3]=ABC[3][c3];
if(k>=4) //有5个拼音时
{
for(c4=0;ABC[4][c4]!=0;c4++)
{
PYBuf[i][4]=ABC[4][c4];
if(k==5) //有6个拼音时
{
for(c5=0;ABC[5][c5]!=0;c5++)
{
PYBuf[i][5]=ABC[5][c5];
if(GetChnStr(PYBuf[i],0))
{for(j=0;j<8;j++)PYBuf[i+1][j]=PYBuf[i][j];PYBuf[i][7]=1;i++;}
}
}
else if(GetChnStr(PYBuf[i],0)) //有5个拼音时
{for(j=0;j<8;j++)PYBuf[i+1][j]=PYBuf[i][j];PYBuf[i][7]=1;i++;}
}
}
else if(GetChnStr(PYBuf[i],0)) //有4个拼音时
{for(j=0;j<8;j++)PYBuf[i+1][j]=PYBuf[i][j];PYBuf[i][7]=1;i++;}
}
}
else if(GetChnStr(PYBuf[i],0)) //有3个拼音时
{for(j=0;j<8;j++)PYBuf[i+1][j]=PYBuf[i][j];PYBuf[i][7]=1;i++;}
}
}
else if(GetChnStr(PYBuf[i],0)) //有2个拼音时
{for(j=0;j<8;j++)PYBuf[i+1][j]=PYBuf[i][j];PYBuf[i][7]=1;i++;}
}
}
else if(GetChnStr(PYBuf[i],0)) //有1个拼音时
{for(j=0;j<8;j++)PYBuf[i+1][j]=PYBuf[i][j];PYBuf[i][7]=1;i++;}
}
for(j=0;j<8;j++)PYBuf[i][j]=0;
}
//**********************************************************************************
void T9Demo(void) //T9拼音演示例程
{
ulong xdata HZaddress,v1,v2;
uchar i,j,k,m,p,q,s,t,ch,PYCt,py_qw1[2],py_qw2[2];
bit bj1,bj2,bj3,bj4,py;
bj1=bj2=bj3=bj4=py=0;
i=k=m=p=s=t=0;
cls(8);
setcursor(0,0);
lcdstring("T9拼音输入法例程\r\n ----喜用火\r\nxyh_mcu@sina.com\r\n 按任意键继续!");
while((ch=getkey(1000))==0);//等待按键
cls(8);
setcursor(0,4); lcdstring("T9拼音:");
setcursor(15,4);lcdchar('@');
setcursor(0,6); lcdstring("[..............]");
KeyBuf_clear();PYBuf_clear();HZBuf_clear();HZOut_clear();HZSave_clear();//大清除
while (1)
{
while((ch=getkey(1000))==0);//等待按键
if((ch-0x30)>=1&&(ch-0x30)<=q/2&&bj1==1)
{
bj1=0; bj2=1; bj3=1;//按键(1~6)选中汉字开始处理...
}
else if(((ch>='2')&&(ch<='9'))&&(bj1==0))//拼音键有效值(2~9)
{
KeyBuf[k]=ch-0x30; k++; bj3=0; bj4=0; py=1;
if(m!=s/32){m=s/32;for(j=0;j<32;j++)HZOut[j]=HZSave[32*m+j];}
}
else if(ch=='D')
{
if(bj4==1){beep(3);continue;}//无效按键操作
else if(bj3==1)
{
if(m<s/32){m++;for(j=0;j<32;j++)HZOut[j]=HZSave[32*m+j];}//向下翻阅已经输入的汉字
else {beep(3);continue;}
}
else if(bj1==1){if(p<(PYCt-1)/12)p++;else {beep(3);continue;}}//向下查阅待选的汉字,页数计算
else if(PYBuf[i+1][7]){i++;}//向下查阅待选的拼音组合
else {beep(3);continue;}//无效按键操作
}
else if(ch=='U')
{
if(bj4==1){beep(3);continue;}//无效按键操作
else if(bj3==1)
{
if(m>0){m--;for(j=0;j<32;j++)HZOut[j]=HZSave[32*m+j];}//向上翻阅已经输入的汉字
else {beep(3);continue;}
}
else if(bj1==1){if(p>0)p--;else {beep(3);continue;}}//向上查阅待选的汉字
else if(i>0){i--;}//向上查阅待选的拼音组合
else {beep(3);continue;}//无效按键操作
}
else if(ch=='C')
{
if(bj4==1){bj4=0;}//取消退出
else if(bj3==1)
{
if(m==s/32)
{
if(t>=2)//删除一个汉字
{
t=t-2;s=s-2;HZSave[s]=0;HZSave[s+1]=0;
}
else {bj3=0;bj4=1;cls(8);setcursor(0,0);lcdstring("退出编辑?\r\n\r\nCancel--取消\r\nEnter --确定");continue;}//是否退出?
}
else m=s/32;//返回当前页
for(j=0;j<32;j++)HZOut[j]=HZSave[32*m+j];
}
else if(bj1==1){i=0;k=0;p=0;}//预选汉字无效
else if(k>0){k--;KeyBuf[k]=0;py=1;}//删除一个拼音字母
if(k==0){KeyBuf_clear();PYBuf_clear();HZBuf_clear();bj1=0;bj3=1;py=0;}//无拼音字母可删
}
else if(ch=='Y')
{
if(bj4==1){bj4=0;return;}//退出
else if(bj3==1){bj3=0;bj4=1;cls(8);setcursor(0,0);lcdstring("存盘(虚拟)退出?\r\n\r\nCancel--返回编辑\r\nEnter --存盘退出");continue;}//存盘退出?
else if((k==0)||(bj1==1)){beep(3);continue;}//没有按键或无效按键操作
else bj1=1;//预选汉字标志
}
else {beep(3);continue;}//无效按键操作
if(py==1)
{
T9Key(KeyBuf);py=0;i=0;//由按键得出可能的拼音组合
if(PYBuf[0][7]==0)//没有有效的拼音组合
{beep(3);k--;KeyBuf[k]=0;T9Key(KeyBuf);continue;}
}
if((k>0)&&(bj2==0))
{
v1=GetChnStr((PYBuf[i]),1)+6; v2=v1+8;
readeprom(v1,py_qw1,2); readeprom(v2,py_qw2,2);
PYCt=py_qw2[0]-py_qw1[0]+256*(py_qw2[1]-py_qw1[1]);//符合要求拼音组合数计算
if(p==(PYCt-1)/12&&PYCt%12!=0)q=PYCt%12; else q=12;
HZBuf_clear();
HZaddress=GetChnStr(PYBuf[i],0)+12*p;//拼音选择中...汉字选择中...
readeprom(HZaddress,HZBuf,q);//取出汉字区位码
}
if(bj2==1)//汉字选中后处理
{
if(s==160){;}//达到80字了,自己处理吧...
if(t==32){t=0; HZOut_clear();}//满一页处理...
HZOut[t]=HZBuf[2*(ch-0x30-1)]; HZSave[s]=HZOut[t];//取出按键(1~6)对应的汉字的区码
HZOut[t+1]=HZBuf[2*(ch-0x30-1)+1]; HZSave[s+1]=HZOut[t+1];//取出按键(1~6)对应的汉字的位码
bj2=0; t=t+2; s=s+2; m=s/32;
KeyBuf_clear(); PYBuf_clear(); HZBuf_clear();//选中汉字后清键值
i=0; k=0; p=0;
}
cls(8);
setcursor(0,0); lcdstring(HZOut); //显示选中的汉字
setcursor(0,4); lcdstring("T9拼音:");//输入法状态显示
setcursor(16-k,4);lcdstring(PYBuf[i]); //显示拼音组合
setcursor(2,6); lcdstring(HZBuf); //显示待选的汉字
setcursor(15-k,4); if(bj1==0)lcdchar('@'); else lcdchar('#');//拼音处提示符
setcursor(0,6); if(bj1==0)lcdstring("[."); else lcdstring(">>");//汉字待选处提示符
setcursor(14,6); if(bj1==0)lcdstring(".]"); else lcdstring(">>");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -