×

T9输入法在嵌入式设备中的实现方案资料下载

消耗积分:5 | 格式:pdf | 大小:328.2KB | 2021-04-13

李鸿洋

分享资料个

引言T9输入法全名为智能输入法,由美国特捷通讯(Tegic Communications)软件公司开发,是目前小型嵌入式人机交互设备中常用的文字输入法,可以直观、简捷、快速地输入简短文字。 在研制基于STM32F107VCT6(以下简称STM32)芯片的人机交互设备时,需要输入文字(主要是汉字)进行人机交互,但是可用的键盘已定型固化而且按键极其有限(仅有7个)。根据T9输 入法的基本原理,研究了一种利用有限键盘资源实现输入汉、英文字的方案。1 总体设计方案硬件由4部分组成:中心控制芯片STM32F107VCT6、驱动芯片SSD1963QL9AU315AF控制的7寸480×240像素的TFT显示屏、预装中文字库容量为64 Mb的W25Q64的FLASH芯片、简单的键盘。其逻辑组成如图1所示。程序的功能实现方面主要由4个功能模块组成:STM32F107VCT6的系统驱动程序、TFT屏幕驱动和显示程序、按键控制程序、T9输入法程序。本文的总体设计方案是外部键盘输入、T9算法、存储并显示这3部分通过与STM32控制芯片的交互,实现文字的输入、显示与存储。系统开始工作前先将点阵字库文件存放到W25Q64芯片的FLASH中(通过SPI接口实现与STM32的信息交换)。系统启动后,在TFT显示屏上绘制T9输入界面,包括提示信息和拼音输入表,通过扫描按键得到输入信号,利用T9算法得到存放在W25Q64的FLASH芯片中的字符点阵,并显示在TFT屏幕上。1.1 硬件设计STM32F107VCT6是ST公司设计的一种低功耗、低成本的内核为32位的CortexM3处理器,其最高工作频率达72 MHz,内部含有256 KB的FLASH 和64 KB的SRAM,实时性好,且具有很强的中断处理能力[1],目前广泛应用于各种嵌入式和手持设备中,是本设计的核心部件。W25Q64是华邦公司推出的大容量SPI FLASH产品,容量为8 MB,支持标准SPI,最大SPI时钟可达80 MHz[1],在本设计中则是利用STM32自带的SPI来实现对外部FLASH W25Q64的读写。本设计中,键盘由四向操纵杆的4个方向键和3个按键组成。文字的输入需要借助TFT显示屏上的光标位置并结合键盘操作来完成,是一种充分利用现有资源的集约设计。其中3个按键分别称为确定1键、确定2键、输入方式切换键,其具体功能如表1所列。TFT显示屏及其显示芯片在本设计中作为外部存储器使用,对TFT驱动芯片SSD1963QL9AU315AF的操作进行简单编程,利用指针实现对TFT的读写操作。由于键盘已定型固化而且按键有限,因此本设计中TFT显示屏还将结合键盘,模拟T9数字键盘的功能。1.2 程序设计本系统中,T9算法的代码在ST公司自带的库文件上编写。初始化阶段先配置好STM32F107VCT6的内部时钟、SPI、键盘、W25Q64、TFT等设备的接口,并分别初始化启动,进入到T9输入法界面。设计的T9输入法包括汉字拼音输入和英文(含数字、标点、大小写英文)两种方式,并且两种输入方式可相互切换。T9输入法实际上就是一个查找、判断输入数字串与拼音组合之间的映射关系过程[4]。本设计中采用的是简单的循环结构[2],首先通过扫描键盘获得输入信号,然后判断是数字序列还是处理信号;若是数字序列则再判断是汉字输入状态还是英文输入状态;根据输入内容不断修正与拼音码表及汉字排列表的映射关系进行定位,获得文字的机内码并在数组中存储;根据机内码在字库中获取相应的点阵数组,在LCD显示屏上显示;若键盘输入的是字符处理信号,则需要对已输入的数字序列进行相应的删除、选择等处理。算法的主体结构流程如图2所示。2 T9输入法的实现T9输入法的实现过程可看作是根据键盘输入信号查找拼音组合,进而确定相应汉字的过程,其中难点在于数字串到拼音的映射往往是多对多的映射关系,而拼音到同音的汉字排列表是一对多的映射关系。因此为了理清T9输入法的基本映射原理,使文字的输入过程更加明晰,可以将T9输入法代码从逻辑上分为3部分:拼音输入与汉字查找的数据结构(即码表设计)、码表的查找过程、界面显示设计。2.1 码表设计中的重要数据结构在T9输入法中,采用汉语拼音的汉字输入方式比较复杂。在输入过程中,首先需要获得正确组合的数字序列,根据数字序列找到对应的拼音码表进行初步定位,再根据该拼音码在汉字库中找到对应的汉字,然后根据汉字的机内码到汉字字库中查找汉字的点阵数组,这一过程称为“码表查找”。从保证码表查找过程的简捷、高效这一意义上讲,码表的设计是码表查找的关键[3]。在T9算法的码表设计里用到两种数据结构,即拼音索引数据结构和汉字字模数据结构。2.1.1 拼音索引数据结构本文拼音索引的数据结构是一个包括输入数字序列、拼音、拼音码表的结构体,这三者构成一个完整的三级映射关系。其定义如下:typedef struct {u8 *py_input;//输入的数字序列u8 *py;//数字序列对应的拼音u8 *pymb;//拼音码表}py_index;其中具体的拼音索引表(部分)如下所示:Const py_indexpy_index_li[] ={{"2","a",(u8*)PY_mb_a},{"2","b",(u8*)PY_mb_b},{"2","c",(u8*)PY_mb_c},……{"2264","bang",(u8*)PY_mb_bang},{"2264","cang",(u8*)PY_mb_cang},……} //拼音索引表与拼音码表对应的汉字排列表(部分)如下所示:const u8 PY_mb_a[]={"啊阿腌吖锕厑嗄錒呵腌"};const u8 PY_mb_b[]={"不把被百比"};const u8 PY_mb_c[]={"才出吃次成"};……const u8 PY_mb_bang[]={"邦帮梆榜膀绑棒磅蚌镑傍谤蒡浜"};const u8 PY_mb_cang[]={"苍舱仓沧藏伧"};const u8 PY_mb_zhu[]={"助主住注祝竹珠蛛朱株猪诸诛逐烛煮拄瞩嘱著柱蛀……"};const u8 PY_mb_xiu[]={"臭宿休修羞朽嗅锈秀袖绣咻溴貅馐岫庥鸺髹"};……//拼音汉字排列表2.1.2 汉字字模数据结构汉字字模数据结构是一个包括汉字的机内码(两个字节)、点阵码的结构体,其定义如下:typedef struct {//汉字字模数据结构unsigned char Index[2];//汉字内码索引unsigned char Msk[32];//点阵码数据}FNT_GB16;汉字的点阵码数据是横向取模,根据所用显示屏特性,数据排列方式为从左到右、从上到下。以汉字“啊”为例,如下所示:const FNT_GB16 GBHZ_16[] = {//宋体12,对应的点阵为:宽×高=16×16"啊",0x00,0x00,0x0E,0xFC,0xEA,0x08,0xAA,0x08,0xAA,0xE8,0xAA,0xA8,0xAC,0xA8,0xAA,0xA8,0xAA,0xA8,0xAA,0xA8,0xEA,0xE8,0xAA,0xA8,0x0C,0x08,0x08,0x08,0x08,0x28,0x08,0x10,……"帮",0x08,0x00,0x08,0x7C,0xFF,0x48,0x08,0x50,0x7E,0x48,0x08,0x44,0xFF,0x54,0x10,0x48,0x20,0x40,0x41,0x00,0xBF,0xF8,0x21,0x08,0x21,0x08,0x21,0x28,0x21,0x10,0x01,0x00,"助",0x00,0x20,0x7C,0x20,0x44,0x20,0x44,0x20,0x44,0xFC,0x7C,0x24,0x44,0x24,0x44,0x24,0x7C,0x24,0x44,0x24,0x44,0x24,0x44,0x44,0x4E,0x44,0xF0,0x84,0x01,0x28,0x02,0x10,……};2.2T9 算法的查找流程与实现在本设计中,一个输入事件就是输入一串外部信号,通过软硬件的交互处理,在相应的文本框中显示与外部输入信号对应的文字。由于本设计中键盘有限,相同的操作在不同的环境下可能有不同的意义,因此为了更进一步明晰每一个外部信号的作用,输入界面加入了其他成型的输入设备中不常出现的“数字”、“当前索引”、“匹配数”等提示信息。图3是本设计T9拼音输入下输入“互助相帮”文字过程中的显示界面。py查找流程是一个随着外部信号的输入而不断变化的动态过程,以输入汉字“帮”为例,将T9输入法的拼音输入汉字的过程简略概括如下:首先扫描键盘,结合光标在TFT显示屏的位置,通过右键结合确定键2输入数字串“2264”,根据数字串到py_index型自定义数据结构py_index3[]中搜索相应的py和pymb,其中与“2264”对应的py有两种,即“bang”和“cang”,而其分别对应的同音汉字也有两组,具体情形参考2.1.1小节中的内容。在本设计自定义的拼音索引表py_index_li[]中,拼音顺序按英文字母表顺序排列。拼音“bang”的位置比“cang”靠前,是第一个匹配拼音(图3中“当前索引”为1),即当前的“拼音匹配”。将当前“拼音匹配”“bang”音的汉字存放到数组u8 buf_store[]中,并将前8个汉字,即“邦帮梆榜膀绑棒磅”分别按1至8的顺序排列显示(参见图3)。扫描按键,如果是左键按下,则将“当前索引”修改为2,“拼音匹配”修改为“cang”,将拼音匹配“cang”音的汉字存放到数组u8 buf_store[]中,并将其前8个汉字按顺序排列显示。若是光标1结合确定2键按下,即执行删除操作,则数字序列最后一位被删去,变为“226”,其py有“ban”、“bao”、“can”、“cao”四种,其中“ban”为第一个匹配拼音,并显示其前8个汉字。选定拼音后(设选定“bang”),下一步需要选定汉字。扫描键盘,若输入信号是确定1键按下,则会将“bang”音的前8个汉字按顺序排列(参见图3),而“帮”在“bang”音汉字数组{"邦帮梆榜膀绑棒磅……"}中排第2位,则利用右键将光标移动到2的位置,按下确定2键,即可利用赋值语句从存储数组buf_store[]中取出汉字“帮”的汉字机内码码0xB0和0xEF;然后利用“帮”的汉字机内码到FLASH中存储的GBHZ_16[]中查找汉字“帮”的显示点阵,将之显示到显示屏上,并存储其汉字内码到u8 buf_message[]中,从而完成一次完整拼音输入、汉字查找并显示的过程。具体过程如图4所示。英文输入过程相对简单,映射关系也相对清晰,可以参考py到pymb一对多的映射和搜索过程,在此不再赘述。结语当前嵌入式人机交互设备在各行业获得广泛应用,输入法是不可或缺的重要组成部分,而商用输入法的成本较高[5]且具有一定的安全风险,因此自行设计具备中英文切换功能的输入法是很有必要的。鉴于此,根据T9输入法的基本思想,本文介绍了一个比较简单但能满足基本文字交互要求的输入法实现方案。本设计方案中所有程序代码采用C语言编写,代码具有较强的可移植性,并可根据需要添加词组和联想功能,目前本方案己经应用在数种型号的嵌入式人机交互设备中。(mbbeetchina)

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.lene-v.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'T9输入法在嵌入式设备中的实现方案资料下载',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"//www.lene-v.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);