| 51.3 软件设计 打开上一章的工程,首先在HARDWARE文件夹所在的文件夹下新建一个ATKNCR的文件夹。将ALIETENK提供的手写识别库文件(ATKNCR_M_V2.0.lib、ATKNCR_N_V2.0.lib、atk_ncr.c和atk_ncr.h这四个个文件,在光盘à 4,程序源码à ATKNCR(数字字母手写识别库) 文件夹里面)拷贝到该文件夹下,然后在工程里面新建一个ATKNCR的组,将atk_ncr.c和ATKNCR_M_V2.0.lib加入到该组下面(这里我们使用内存管理版本的识别库)。最后,将ATKNCR文件夹加入头文件包含路径。 关于ATKNCR_M_V2.0.lib和atk_ncr.c前面已有介绍,我们这里就不再多说,我们在test.c里面修改main函数如下: //最大记录的轨迹点数 atk_ncr_point READ_BUF[200];                               int main(void) {                   u8 i=0;                       u8 tcnt=0;            u8 res[10];        u8 key;                       u16 pcnt=0;        u8 mode=4;                  //默认是混合模式                        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);     //初始化内部内存池             alientek_ncr_init();        //初始化手写识别         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);//清除显示                   } RESTART:       Show_Str(60,10,200,16,"战舰 STM32开发板",16,0);                                               Show_Str(60,30,200,16,"手写识别实验",16,0);                                           Show_Str(60,50,200,16,"正点原子@ALIENTEK",16,0);                                           Show_Str(60,70,200,16,"KEY0:MODE KEY2:Adjust",16,0);                             Show_Str(60,90,200,16,"识别结果:",16,0);                           LCD_DrawRectangle(19,114,220,315);       POINT_COLOR=BLUE;              Show_Str(96,207,200,16,"手写区",16,0);           tcnt=100;        while(1)        {               key=KEY_Scan(0);               if(key==KEY_LEFT)               {                      TP_Adjust();        //屏幕校准                      LCD_Clear(WHITE);                       goto RESTART;     //重新加载界面               }               if(key==KEY_RIGHT)                 {                      LCD_Fill(20,115,219,314,WHITE);//清除当前显示                      mode++;                      if(mode>4)mode=1;                      switch(mode)                      {                             case 1: Show_Str(80,207,200,16,"仅识别数字",16,0); break;                                                 case 2: Show_Str(64,207,200,16,"仅识别大写字母",16,0); break;                                          case 3: Show_Str(64,207,200,16,"仅识别小写字母",16,0); break;                                 case 4: Show_Str(88,207,200,16,"全部识别",16,0); break;                       }                      tcnt=100;               }                             tp_dev.scan(0);//扫描              if(tp_dev.sta&TP_PRES_DOWN)//有按键被按下               {                                                  delay_ms(1);//必要的延时,否则老认为有按键按下.                     tcnt=0;//松开时的计数器清空                                            if((tp_dev.x<220&&tp_dev.x>=20)&&(tp_dev.y<315&&tp_dev.y>=115))                      {                                                TP_Draw_Big_Point(tp_dev.x,tp_dev.y,BLUE);//画图                              if(pcnt<200)//总点数少于200                             {                                    if(pcnt)                                    {                                           if((READ_BUF[pcnt-1].y!=tp_dev.y)&&(READ_BUF[pcnt-1].x!= tp_dev.x))//x,y不相等                                           {                                                  READ_BUF[pcnt].x=tp_dev.x;                                                  READ_BUF[pcnt].y=tp_dev.y;                                                   pcnt++;                                           }                                         }else                                     {                                           READ_BUF[pcnt].x=tp_dev.x;                                           READ_BUF[pcnt].y=tp_dev.y;                                            pcnt++;                                    }                                           }                                                                                                }                 }else //按键松开了                {                      i++;tcnt++;delay_ms(10); //延时识别                            if(tcnt==40)                      {                             if(pcnt)//有有效的输入                                     {                                    printf("总点数:%d\r\n",pcnt);                                    alientek_ncr(READ_BUF,pcnt,6,mode,(char*)res);                                    printf("识别结果:%s\r\n",res);                                    pcnt=0;                                                                                     POINT_COLOR=BLUE;//设置画笔蓝色                                   LCD_ShowString(60+72,90,200,16,16,res);                             }                             LCD_Fill(20,115,219,314,WHITE);                      }                }                 if(i==30) { i=0; LED0=!LED0;}                                  }                                                                                                      }
 该函数同触摸屏实验的main函数有点类似,不过加入了一些处理,以实现51.1.2节提到的功能。其中,READ_BUF用来存储输入轨迹点阵,大小为200,即最大输入不能超过200点,注意:这里我们采集的都是不用的点阵(即相邻的坐标不相等)。这样可以大大减少重复点阵的大小,而重复点阵对识别是没有帮助的。  至此,本实验的软件设计部分结束。51.4 下载验证 在代码编译成功之后,我们下载代码到ALIENTEK战舰STM32开发板上,得到,如图51.4.1所示:
 
 图51.4.1 手写识别界面
 此时,我们在手写区写数字/字母,即可得到识别结果,如图51.4.2所示: 
 图51.4.2 手写识别结果
 按下KEY0可以切换识别模式,同时在识别区提示当前模式。按下KEY2可以进行屏幕校准。每次识别结束,会在串口打印本次识别的输入点数和识别结果,大家可以通过串口助手查看。 |