{
temp=str_match(strin,(u8*)py_index3.py_input);
if(temp)
{
if(temp==0XFF)matchlist[mcnt++]=(py_index*)&py_index3;
else if(temp>bmcnt)//找最佳匹配
{
bmcnt=temp;
bestmatch=(py_index*)&py_index3;//最好的匹配.
}
}
}
if(mcnt==0&&bmcnt)//没有完全匹配的结果,但是有部分匹配的结果
{
matchlist[0]=bestmatch;
mcnt=bmcnt|0X80; //返回部分匹配的有效位数
}
return mcnt;//返回匹配的个数
}
//得到拼音码表.
//str:输入字符串
//返回值:匹配个数.
u8 get_pymb(u8* str)
{
return get_matched_pymb(str,t9.pymb);
}
//串口测试用
void test_py(u8 *inputstr)
{
……代码省略
}
这里总共就4个函数,其中get_matched_pymb,是核心,该函数实现将用户输入拼音数字串同拼音索引表里面的各个项对比,找出匹配结果,并将完全匹配的项目存放在matchlist里面,同时记录匹配数。对于那些没有完全匹配的输入串,则查找与其最佳匹配的项目,并将匹配的长度返回。函数test_py(代码省略)用于给usmart调用,实现串口测试,该函数可有可无,只是在串口测试的时候才用到,如果不使用的话,可以去掉,本章,我们将其加入usmart控制,大家可以通过该函数实现串口调试拼音输入法。
其他两个函数,也比较简单了,我们这里就不细说了,保存pyinput.c,打开pyinput.h,输入如下代码:
#ifndef __PYINPUT_H
#define __PYINPUT_H
#include "sys.h"
//拼音码表与拼音的对应表
typedef struct
{
u8 *py_input;//输入的字符串
u8 *py; //对应的拼音
u8 *pymb; //码表
}py_index;
#define MAX_MATCH_PYMB 10 //最大匹配数
//拼音输入法
typedef struct
{
u8(*getpymb)(u8 *instr); //字符串到码表获取函数
py_index *pymb[MAX_MATCH_PYMB]; //码表存放位置
}pyinput;
extern pyinput t9;
u8 str_match(u8*str1,u8*str2);
u8 get_matched_pymb(u8 *strin,py_index **matchlist);
u8 get_pymb(u8* str);
void test_py(u8 *inputstr);
#endif
保存pyinput.h。pymb.h里面完全就是我们前面介绍的拼音码表,该文件很大,里面存储了所有我们可以输入的汉字,此部分代码就不贴出来了,请大家参考光盘本例程的源码。
最后,我们打开test.c,输入代码如下:
const u8* kbd_tbl[9]={"←","2","3","4","5","6","7","8","9",};//数字表
const u8* kbs_tbl[9]={"DEL","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz",};//字符表
//加载键盘界面
//x,y:界面起始坐标
void py_load_ui(u16 x,u16 y)
{
u16 i;
POINT_COLOR=RED;
LCD_DrawRectangle(x,y,x+180,y+120);
LCD_DrawRectangle(x+60,y,x+120,y+120);
LCD_DrawRectangle(x,y+40,x+180,y+80);
POINT_COLOR=BLUE;
for(i=0;i<9;i++)
{
Show_Str_Mid(x+(i%3)*60,y+4+40*(i/3),(u8*)kbd_tbl,16,60);
Show_Str_Mid(x+(i%3)*60,y+20+40*(i/3),(u8*)kbs_tbl,16,60);
}
}
//按键状态设置
//x,y:键盘坐标
//key:键值(0~8)
//sta:状态,0,松开;1,按下;
void py_key_staset(u16 x,u16 y,u8 keyx,u8 sta)
{
u16 i=keyx/3,j=keyx%3;
if(keyx>8)return;
if(sta)LCD_Fill(x+j*60+1,y+i*40+1,x+j*60+59,y+i*40+39,GREEN);
else LCD_Fill(x+j*60+1,y+i*40+1,x+j*60+59,y+i*40+39,WHITE);
Show_Str_Mid(x+j*60,y+4+40*i,(u8*)kbd_tbl[keyx],16,60);
Show_Str_Mid(x+j*60,y+20+40*i,(u8*)kbs_tbl[keyx],16,60);
}
//得到触摸屏的输入
//x,y:键盘坐标
//返回值:按键键值(1~9有效;0,无效)
u8 py_get_keynum(u16 x,u16 y)
{
u16 i,j; u8 key=0;
static u8 key_x=0;//0,没有任何按键按下;1~9,1~9号按键按下
tp_dev.scan(0);
if(tp_dev.sta&TP_PRES_DOWN) //触摸屏被按下
{
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
if(tp_dev.x<(x+j*60+60)&&tp_dev.x>(x+j*60)&&tp_dev.y<(y+i*40+40)
&&tp_dev.y>(y+i*40)) { key=i*3+j+1; break; }
}
if(key)
{
if(key_x==key)key=0;
else
{
py_key_staset(x,y,key_x-1,0);
key_x=key;
py_key_staset(x,y,key_x-1,1);
}
break;
}
}
}else if(key_x) {py_key_staset(x,y,key_x-1,0); key_x=0; }
return key;
}
//显示结果.
//index:0,表示没有一个匹配的结果.清空之前的显示
// 其他,索引号
void py_show_result(u8 index)
{
LCD_ShowNum(30+144,125,index,1,16); //显示当前的索引
LCD_Fill(30+40,125,30+40+48,130+16,WHITE); //清除之前的显示
LCD_Fill(30+40,145,30+200,145+48,WHITE); //清除之前的显示
if(index)
{
Show_Str(30+40,125,200,16,t9.pymb[index-1]->py,16,0); //显示拼音
Show_Str(30+40,145,160,48,t9.pymb[index-1]->pymb,16,0); //显示对应的汉字
printf("\r\n拼音:%s\r\n",t9.pymb[index-1]->py); //串口输出拼音
printf("结果:%s\r\n",t9.pymb[index-1]->pymb); //串口输出结果
}
}
int main(void)
{
u8 i=0; u8 key; u8 cur_index;
u8 result_num;
u8 inputstr[7]; //最大输入6个字符+结束符
u8 inputlen; //输入长度
Stm32_Clock_Init(9); //系统时钟设置
delay_init(72); //延时初始化
uart_init(72,9600); //串口1初始化
LCD_Init(); //初始化液晶
LED_Init(); //LED初始化
KEY_Init(); //按键初始化
TP_Init(); //触摸屏初始化
usmart_dev.init(72); //usmart初始化
mem_init(SRAMIN); //初始化内部内存池
RESTART:
POINT_COLOR=RED;
while(font_init()) //检查字库
{
LCD_ShowString(60,50,200,16,16,"Font Error!");
delay_ms(200);
LCD_Fill(60,50,240,66,WHITE);//清除显示
}
Show_Str(60,5,200,16,"战舰 STM32开发板",16,0);
Show_Str(60,25,200,16,"拼音输入法实验",16,0);
Show_Str(60,45,200,16,"正点原子@ALIENTEK",16,0);
Show_Str(30,65,200,16," KEY2:校准 KEY0:清除",16,0);
Show_Str(30,85,200,16,"KEY_UP:上翻 KEY1:下翻",16,0);
Show_Str(30,105,200,16,"输入: 匹配: ",16,0);
Show_Str(30,125,200,16,"拼音: 当前: ",16,0);
Show_Str(30,145,210,32,"结果:",16,0);
py_load_ui(30,195);
memset(inputstr,0,7); //全部清零
inputlen=0; result_num=0; cur_index=0;//清零
while(1)
{
i++; delay_ms(10);
key=py_get_keynum(30,195);
if(key)
{
if(key==1)//删除
{
if(inputlen)inputlen--;
inputstr[inputlen]='\0';//添加结束符
}else
{
inputstr[inputlen]=key+'0';//输入字符
if(inputlen<7)inputlen++;
}
if(inputstr[0]!=NULL)
{
key=t9.getpymb(inputstr); //得到匹配的结果数
if(key)//有部分匹配/完全匹配的结果
{
result_num=key; //总匹配结果
cur_index=1; //当前为第一个索引
if(key&0X80) //是部分匹配
{
inputlen=key&0X7F; //有效匹配位数
inputstr[inputlen]='\0';//不匹配的位数去掉
if(inputlen>1)result_num=t9.getpymb(inputstr);
//重新获取完全匹配字符数
}
}else{inputlen--; inputstr[inputlen]='\0';} //没有任何匹配
}else {cur_index=0; result_num=0;}
LCD_Fill(30+40,105,30+40+48,110+16,WHITE);//清除之前的显示
LCD_ShowNum(30+144,105,result_num,1,16); //显示匹配的结果数
Show_Str(30+40,105,200,16,inputstr,16,0); //显示有效的数字串
py_show_result(cur_index); //显示第cur_index的匹配结果
}
if(result_num) //存在匹配的结果
{
key=KEY_Scan(0);
switch(key)
{
case KEY_UP://上翻
if(cur_index
else cur_index=1;
py_show_result(cur_index); //显示第cur_index的匹配结果
break;
case KEY_DOWN://下翻
if(cur_index>1)cur_index--;
else cur_index=result_num;
py_show_result(cur_index); //显示第cur_index的匹配结果
break;
case KEY_RIGHT://清除输入
LCD_Fill(30+40,145,30+200,145+48,WHITE); //清除之前的显示
goto RESTART;
case KEY_LEFT://重新校准
tp_dev.adjust();
LCD_Clear(WHITE);
goto RESTART;
}
}
if(i==30) {i=0; LED0=!LED0;}
}
}
此部分代码除main函数外还有4个函数。首先,py_load_ui,该函数用于加载输入键盘,在LCD上面显示我们输入拼音数字串的虚拟键盘。py_key_staset,该函数用与设置虚拟键盘某个按键的状态(按下/松开)。py_get_keynum,该函数用于得到触摸屏当前按下的按键键值,通过该函数实现拼音数字串的获取。最后,py_show_result,该函数用于显示输入串的匹配结果,并将结果打印到串口。
在main函数里面,实现了我们在52.2节所说的功能,这里我们并没有实现汉字选择功能,但是有本例程作为基础,再实现汉字选择功能就比较简单了,大家自行实现即可。
最后,我们将test_py函数加入USMART控制,以便大家串口调试。
至此,本实验的软件设计部分结束。
52.4 下载验证 在代码编译成功之后,我们下载代码到ALIENTEK战舰STM32开发板上,得到,如图52.4.1所示:
图52.4.1 汉字输入法界面
此时,我们在虚拟键盘上输入拼音数字串,即可实现拼音输入,如图52.4.2所示:
图52.4.2 实现拼音输入
如果发现输入错了,可以通过屏幕上的DEL按钮,来退格。如果有多个匹配的情况(匹配值大于1),则可以通过WK_UP和KEY1来选择拼音。通过按下KEY0,可以清楚当前输入,通过按下KEY2,可以实现触摸屏校准。
我们还可以通过USMART调用test_py来实现输入法调试,如图52.4.3所示:
[ 本帖最后由 正点原子 于 2013-4-16 22:56 编辑 ]
我的淘宝:http://shop62103354.taobao.com