当前位置:文档之家› 嵌入式控制系统综合实验

嵌入式控制系统综合实验

《嵌入式控制系统综合实验》课程实验报告项目名称 基于STM32的手机输入法南京理工大学2017年6月目录1 设计背景 (2)2 系统总体方案 (3)3 系统具体设计 (4)3.1 手写识别原理 (4)3.2手写识别程序设计 (6)3.3手写识别硬件设计 (10)3.4拼音九键输入原理 (10)3.5拼音九键软件设计 (11)3.6拼音九键硬件设计 (13)4 编译调试 (14)4.1 手写识别、拼音输入法单项调试 (14)4.2 手写识别、拼音输入法组合调试 (18)5总结 (19)1 设计背景随着计算机技术和微电子技术的迅速发展,嵌入式系统应用领域越来越广泛。

随着IC设计的发展,出现了工业化ARM芯片,ARM微处理器及技术已经深入到各大领域,并取得了很大成功,如无线通信领域、蓝牙技术、网络应用领域、消费类电子产品领域、信息家电领域等。

目前几乎所有带触摸屏的手机都能实现拼音输入和手写识别输入。

Cortex-M3采用ARM V7构架,不仅支持Thumb-2指令集,而且拥有很多新特征。

较之ARM7 TDMI,Cortex-M3拥有更强劲的性能、更高的代码密度、位带操作、可嵌套中断、低成本、低功耗等众多优势。

本次嵌入式实验,我们采用基于STM32F103带4.3寸触摸屏的嵌入式开发板来模拟一个手机输入法,该输入法功能主要有手写识别跟拼音九键。

嵌入式开发平台如图1所示。

图1 STM32F103嵌入式开发平台2 系统总体方案本次嵌入式实验设计了“手机输入法”功能,该输入法功能主要包括两种输入方式——拼音九键+手写识别。

下面首先介绍一下本设计的软、硬件基础,然后介绍本设计的总体方案。

软件基础:本次嵌入式综合实验,我们利用MDK软件来开发STM32。

MDK 源自德国的KEIL公司,是RealView MDK的简称。

在全球MDK被超过10万的嵌入式开发工程师使用。

MDK5向后兼容MDK4和MDK3等,以前的项目同样可以在MDK5上进行开发(但是头文件方面得全部自己添加),MDK5同时加强了针对Cortex-M微控制器开发的支持,并且对传统的开发模式和界面进行升级,MDK5由两个部分组成:MDK Core和Software Packs。

其中,Software Packs可以独立于工具链进行新芯片支持和中间库的升级。

硬件基础:本次嵌入式综合实验所使用的STM32开发板选择的是STM32F103ZETT6作为MCU,该芯片是STM32F103里面配置非常强大的了,它拥有的资源包括:64KB SRAM、512KB FLASH、2个基本定时器、4个通用定时器、2个高级定时器、2个DMA控制器(共12个通道)、3 个SPI、2个IIC、5 个串口、1个USB、1个CAN、3个12位ADC、1个12位DAC、1个SDIO 接口、1个FSMC接口以及112个通用IO口。

该芯片的配置十分强悍,并且还带外部总线(FSMC)可以用来外扩SRAM和连接LCD等,通过FSMC驱动LCD,可以显著提高LCD的刷屏速度,本设计要完成输入法的界面设计、功能实现以及不同输入方式之间的来回切换,还必须与键盘、LCD等硬件设备结合。

总体方案如下:(1)设计输入法的总体要实现的功能,画出功能块图;(2)将整个输入法设计分成两大模块,一是手写识别,二是拼音输入,分别对他们进行程序设计;(3)画出手写识别与拼音输入的程序流程图,并编写相应的程序;(4)最后,将设计好的两个输入法模块整合起来,并编写相应的程序,使之可以完美地进行来回切换。

系统总体设计框图如图2:图2 系统总体设计框图我们将整个嵌入式综合实验分成2步:第一步,分别设计出手写识别功能和拼音九键输入功能;第二步,将以上设计好的功能模块整合在一起,实现这两种输入方式的来回切换。

3 系统具体设计基于STM32的输入法功能实现,一开始系统默认是手写识别(其实也可以初始化为拼音九键模式,这是可以自行设计的,我们把手写识别模式作为系统的默认输入模式)。

3.1 手写识别原理我们在STM32开发板上实现了一个简单的数字、字母手写识别功能。

手写识别,是指对在手写设备上书写时产生的有序轨迹信息进行识别的过程,是人际交互最自然、最方便的手段之一。

随着智能手机和平板电脑等移动设备的普及,手写识别的应用也被越来越多的设备采用。

手写识别能够使用户按照最自然、最方便的输入方式进行文字输入,易学易用,可取代键盘或者鼠标。

用于手写输入的设备有许多种,比如电磁感应手写板、压感式手写板、触摸屏、触控板、超声波笔等。

STM32嵌入式开发板自带的TFTLCD触摸屏可以用来作为手写识别的输入设备。

手写识别系统分为两个过程:训练学习过程;识别过程。

如图3所示:图3 字母、数字识别系统示意图图3中虚线部分为训练学习过程,该过程首先需要使用设备采集大量数据样本,样本类别数目为0~9,a~z,A~Z总共62类,每个类别5~10个样本不等(样本越多识别率就越高)。

对这些样本进行传统的把方向特征提取,提取后特征维数为512 维,这对STM32 来讲,计算量和模板库的存储量来说都难以接受,所以需要运行一些方法进行降维,这里采用LDA 线性判决分析的方法进行降维,所谓线性判决分析,即是假设所有样本服从高斯分布(正态分布)对样本进行低维投影,以达到各个样本间的距离最大化。

这里将维度降到64维,然后针对各个样本类别进行平均计算得到该类别的样本模板。

而对于识别过程,首先得到触屏输入的有序轨迹,然后进行一些预处理,预处理主要包括重采样,归一化处理。

重采样主要是因为不同的输入设备不同的输入处理方式产生的有序轨迹序列有所不同,为了达到更好的识别结果我们需要对训练样本和识别输入的样本进行重采样处理,这里主要应用隔点重采样的方法对输入的序列进行重采样;而归一化就是因为不同的书写风格采样分辨率的差异会导致字体太小不同,因此需要对输入轨迹进行归一化。

这里把样本进行线性缩放的方法归一化为64*64像素。

接下来进行同样的八方向特征提取操作。

所谓八方向特征就是首先将经过预处理后的64*64输入进行切分成8*8的小方格,每个方格8*8个像素;然后对每个8*8个小格进行各个方向的点数统计。

如某个方格内一共有10个点,其中八个方向的点分别为:1、3、5、2、3、4、3、2那么这个格子得到的八个特征向量为[0.1, 0.3, 0.5,0.2, 0.3,0.4,0.3,0.2]。

总共有64个格子于是一个样本最终能得到64*8=512 维特征。

由于训练过程进行了LDA降维计算,所以识别过程同样需要对应的LDA降维过程得到最终的64维特征。

这个计算过程就是在训练模板的过程中可以运算得到一个512*64 维的矩阵,那么我们通过矩阵乘运算可以得到64维的最终特征值。

最后将这64维特征分别与模板中的特征进行求距离运算。

得到最小的距离为该输入的最佳识别结果输出。

3.2手写识别程序设计ALIENTEK提供了一个数字、字母识别库,这样我们就不需要关心手写识别是如何实现的,只需要知道这个库怎么用,就能实现手写识别。

ALIENTEK 提供的手写识别库由4个文件组成:A TKNCR_M_V2.0.lib、A TKNCR_N_V2.0.lib、atk_ncr.c和atk_ncr.h。

ATKNCR_M_V2.0.lib和A TKNCR_N_V2.0.lib是两个识别用的库文件(两个版本),使用的时候,选择其中之一即可。

ATKNCR_M_V2.0.lib用于使用内存管理的情况,用户必须自己实现alientek_ncr_malloc和alientek_ncr_free两个函数。

而A TKNCR_N_V2.0.lib用于不使用内存管理的情况,通过全局变量来定义缓存区,缓存区需要提供至少3K左右的RAM。

ALIENTEK手写识别库资源需求:FLASH:52K 左右,RAM:6K左右。

atk_ncr.c代码如下:#include "atk_ncr.h"#include "malloc.h"//内存设置函数void alientek_ncr_memset(char *p,char c,unsigned long len){mymemset((u8*)p,(u8)c,(u32)len);}//内存申请函数void *alientek_ncr_malloc(unsigned int size){return mymalloc(SRAMIN,size);}//内存清空函数void alientek_ncr_free(void *ptr){myfree(SRAMIN,ptr);}这里,主要实现了alientek_ncr_malloc、alientek_ncr_free和alientek_ncr_memset 等三个函数。

atk_ncr.h 则是识别库文件同外部函数的接口函数声明:#ifndef __A TK_NCR_H#define __A TK_NCR_H#define A TK_NCR_TRACEBUF1_SIZE 500*4 //定义第一个tracebuf大小(单位为字节),如果出现死机,请把该数组适当改大#define A TK_NCR_TRACEBUF2_SIZE 250*4 //定义第二个tracebuf大小(单位为字节),如果出现死机,请把该数组适当改大//输入轨迹坐标类型__packed typedef struct _atk_ncr_point{short x; //x轴坐标short y; //y轴坐标}atk_ncr_point;//外部调用函数//初始化识别器//返回值:0,初始化成功// 1,初始化失败unsigned char alientek_ncr_init(void);//停止识别器void alientek_ncr_stop(void);//识别器识别//track:输入点阵集合//potnum:输入点阵的点数,就是track的大小//charnum:期望输出的结果数,就是你希望输出多少个匹配结果//mode:识别模式//1,仅识别数字//2,仅识别大写字母//3,仅识别小写字母//4,混合识别(全部识别)//result:结果缓存区(至少为:charnum+1个字节)void alientek_ncr(atk_ncr_point * track,int potnum,int charnum,unsigned char mode,char*result);//内存设置函数void alientek_ncr_memset(char *p,char c,unsigned long len);//动态申请内存,当使用A TKNCR_M_Vx.x.lib时,必须实现.void *alientek_ncr_malloc(unsigned int size);//动态释放内存,当使用A TKNCR_M_Vx.x.lib时,必须实现.void alientek_ncr_free(void *ptr);#endif此段代码中,我们定义了一些外部接口函数以及一个轨迹结构体等。

相关主题