⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 t9_dx51.c

📁 一个不错的T9输入法例程
💻 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 + -