注:以下所有应用实例均以MDK4.60为开发编译工具
1. norFlash的应用(以SST39x640x为例)
a) ini文件的添加
下载针对你平台(例如M3)的外设(主要是EMC)初始化的ini文件,或近似文件来修改。推荐网址:www.keil.com。修改后添加至如下图所示位置:
这一步的目的是为了让MDK编译器烧写程序之前初始化norflash外设用。打开“xflash.ini”文件,你可以看到主要是对EMC及norflash的一些初始化代码,详见附件一.
b) Norflash烧写算法的生成
在MDK的安装目录下系统提供了一个flash烧写算法编写的模板工程(D:\ProgramFiles\MDK\ARM\Flash\_Template)。你可以参考它来完成自己的FLM烧写算法文件的编写及生成(工程属性页的设置很有些讲究)。当然,如果你能让硬件工程师直接选择MDK提供算法的flash芯片就最好了。
c) Norflash烧写算法的添加
在工程属性页“Utilities”中单击“Settings”会弹出如下对话框
如果你将步骤b中生成好的FLM文件拷贝到MDK的相应安装目录(例如:D:\Program Files\MDK\ARM\Flash\),单击上图“Add”按钮,你就能找到需要添加的算法选项。
d)做好以上的3步是你能用MDK下载程序到norFlash及在线调试的关键
2. USBCDC的应用
UsbCDC类主要是为了解决现在很多笔记本电脑都没有串口对嵌入式开发带来的不便。UsbCDC是USB协议标准设备的一种,它在嵌入式终端实现一个USBCDC协议栈,通过USB线连接上PC机后,PC机只需要开发者提供一个简单的inf文件即可利用自身的usbser.sys驱动,进行新硬件驱动安装,进而在设备管理器中识别我们的终端设备为一个串口。PC机即可利用这个串口与我们的终端设备通信。Windows XP系统的inf文件参见附件二。需要根据你设备终端中实现的USBCDC协议栈中的PID和VID,对inf文件中相应项对应修改。
3. UcGUI的移植(针对TFT液晶屏)
主要有三个文件需要修改:GUIConf.h(操作系统、触摸屏等是否支持的配置);LCDConf.h(液晶屏驱动控制相关配置);LCDDummy.C(液晶屏绘制点、线、矩形等函数的实现);参见附件三。
4. 基于UcGUI的汉字库的应用
下载刘传年的基于ucOS、ucGUI的简体中文与UNICODE转换文件(已做成ucGUI能识别的数据结构)。添加到工程之后只需在GUI.h文件中增加一个外部变量声明即可,如:/*汉字库*/
externGUI_CONST_STORAGE GUI_FONT GUI_FontHZ16;
extern GUI_CONST_STORAGE GUI_FONTGUI_FontHZ24;
5. 基于UcGUI的T9输入法的移植
可上网下载类似的现有程序来参考修改(如基于miniGUI的T9输入法实现)。主要有几个内容:
a) 输入法界面的绘制:调用ucGUI的系统函数绘制点、线、颜色及字符等
b) 汉字索引的建立:可根据汉语拼音对常用基本汉字做索引数据结构,方便程序调用查找
c) 对用户输入合法性的过滤:在不同输入法状态(汉字、英文、字符)对用户输入的一些不合法字符进行处理
d) 汉字查找算法:根据用户输入的拼音,利用建立好的索引查找并显示所有合法汉字供用户选择
e) 回调函数的处理:主要是对输入法的一些控制处理,如切换输入法、删除操作、选择操作等
以上是实现一个简单的T9输入法的主要内容,参见附件四。
6. 基于UcGUI的UNICODE编码与GB2312汉字编码相互转换算法
在本项目中,这个功能主要是用在对中文短信的支持,网上有很多可参考的算法文件,筛选一个合适的来进行下简单修改即可。
7. 分散加载文件的应用
在本项目中,分散加载文件主要是为了配合IAP用。将片内flash分为system区、low区和high区;片外norflash也分为norflash_low区和norflash_high区。步骤如下:
a) 工程增加组件如图
b) 在每个组件的属性页中添加分散加载文件
c) 修改分散加载文件的内容,让程序定位到指定的flash区域,参见附件五。
8. 基于ucOS的TFT液晶屏缓存的应用
根据液晶屏的内部缓存大小开辟一个相应大小的缓存。如分辨率为320X240;RGB采取5:6:5来分配,即用2个字节来表示一个像素;这样可在sdram中开辟一个320x240x2大小的缓存。每次对液晶屏的操作(画点、线,背景颜色改变等操作)都只是操作相应的sdram缓存。利用ucOS多任务的调度,每200毫秒(视CPU的具体情况定)将全部sdram的缓存内容写入液晶屏,完成刷屏。这样能有效的减轻CPU的负担。
9. UcOS的移植及应用
UcOS是一个简单、实用的小型操作系统。移植主要针对两个文件夹:port文件夹(跟平台相关的一些定义)、sourse文件夹(操作系统相关的实现,如信号量、邮箱、队列、任务等)。UcOS的移植比较简单,一般可上网下载或找技术支持要到相应平台的ucOS源码,添加到工程中即可。UcOS的应用,我根据做项目的体会总结几点:
a) 任务划分要清晰,优先级定义有讲究
做项目之前,你需要对任务有个划分。互不干涉的事件可以放在同一个任务中顺序执行;较重要或较复杂的任务单列出来;避免结构混乱,调试时方便查找问题。优先级的定义最好按照任务的重要程序从小到大排,0~2为系统保留,最大为63。ucOS是一个多任务的操作系统,它在进行任务调度的时候会优先调度优先级高(号码小)的任务。举个很简单的例子:你在优先级为6的任务(以下简称“任务6”)中调用OSMboxPend(TcpSndBox, 0, &errr); UART0_snd("#",1); 然后你在优先级为7的任务(以下简称“任务7”)中调用OSMboxPost(TcpSndBox,(void *)iap_send_data ); UART0_snd("*",1); 任务6中OSMboxPend是一个请求信号量函数,任务7中OSMboxPost是一个释放信号量函数。所以任务6是依赖任务7的,必须等任务7中信号量释放了才能继续运行任务6。这样,表面看串口打印信息会是“*#”。实际上打印的结果却是“#*”,因为任务7刚一释放信号量,操作系统就会调度切换到任务6,执行后再切换回任务7。
b) 临界资源要保护
所谓“临界资源”其实就是指“信号量”数量为1的资源,同一时刻只允许一个任务操作它,比如一个共用缓冲区、一个全局变量等。这种资源在调用的时候都需要保护起来。例如: OS_ENTER_CRITICAL();
临界区代码
OS_EXIT_CRITICAL();
“OS_ENTER_CRITICAL”函数里做的工作就是保存中断环境变量。“OS_EXIT_CRITICAL”函数做的工作就是还原“OS_ENTER_CRITICAL”里保存的中断环境变量。这样临界区代码就不怕被中断打断,因为它可以恢复到中断之前的中断环境。UcOS中(或是其他操作系统中)不建议为了保护临界资源而关闭全部中断,因为它会严重影响操作系统的运行,造成不可预测的问题。所有的操作系统都会提供保护临界资源的方法如ucOS中: OS_ENTER_CRITICAL();
临界区代码
OS_EXIT_CRITICAL();
而且如果运用得当,不会有问题。如果你还是顽固不化的想通过关闭所有中断来处理自己的事情,那不建议你用任何操作系统了。多任务等操作系统的便利性你就无福消受了,还是回到你的裸跑时代吧。
临界资源的保护问题,是初学者比较常犯的一个错误。我在卫星电话单模项目中调试USBCDC、基于norflash的IAP等模块时,最后发现的关键问题就在于临界资源——缓冲区没有保护好,导致串口都会掉包等裸跑程序不会出现的问题。
c) 每个任务while(1)里都要根据需要用OSTimeDly进行延时,不然任务会长期占用CPU。
d)
10. 基于ucOS与norflash的IAP升级
NXP的ARM芯片提供IAP和ISP功能。我们利用其来对终端设备进行软件升级和维护。ISP可以直接用FlashMagic将生产的HEX文件烧入ARM片内FLASH,但对于要升级片外norFlash的应用来说除了H-JTAG外,IAP在线升级是一个比较好的选择。而且可以利用ucOS的多任务特性,单独用一个任务来负责处理IAP升级。IAP的命令操作函数应该可以很容易的从芯片厂商那里得到。
对于片内flash我需要特别指明一点:要烧写至M3架构的flash文件在0x1c处需要做一个修改后再写入flash才能保证程序正常运行(这也是曾小伟费劲周折才发现的一个真相)。这个修改其实就是M3中断向量表的校验和,参见附件六。
对于片外norflash也需要说明一下:不要认为norflash中存储的是字库和常量就不会变化了,只要你分散加载文件有一点变化(片内flash高、低区),编译出的norflash中的数据就会有变化,所以如果片内分了高、低区,片外norflash最好也跟着分出高、低区,升级时一并升级了,避免发生错误。
附件一:
/***********************************************************************/
/* Pre-Download 'script' for EXTERNALNOR-FLASH on the LPC1788 Board . */
/* Location: C:\cproj\boot_v4\swi_11381\XFlash.ini */
/* Written for the LPC1788 by WolfgangBuescher, 2012-01-16 . */
/* */
/* Used when downloading something via KeiluVision3 / Ulink / JTAG */
/* into a 16-bit wide static memory (Flash) on /CS0 . */
/* */
/* Initialisation of the EMC- and IOCONregisters based on WoBu's */
/* system-init: C:\drivers1\LPC1788_Board40171\system_LPC177x_8x.c ; */
/* (Note that this is utterly incompatible with the LPC2478-stuff !) */
/* plus bits and pieces from http://www.keil.com/forum/19730/ . */
/* */
/* If the IDE doesn't know how to programthe EXTERNAL FLASH, it says: */
/* > No Algorithm found for: 80000000H - 8000FFFFH ( etc ) . */
/* If that happens (which it usually does when switching the target), */
/* look at WoBu's precious screenshot of all those shiny uV3 screens: */
/* \drivers1\Doku\MKTview2_uVision3_Flash_Download_Setup.png ! */
/* Most likely, the Keil IDE has forgottenthose settings again (*): */
/* In uV4, click "Flash".."Configure FlashTools".."Settings" . */
/* (*) these settings are lost when selecting a new target in the IDE.*/
/* */
/* ONCE UPON A TIME, this file WAS part of the ARM Compiler package . */
/* */
/* SIMILAR (but not necessarily IDENTICAL) descendants of this file: */
/* - C:\cproj\boot_v4\swi_11381\XFlash.ini (for the BOOTLOADER) */
/* - C:\cproj\arm_view\swi_11382\XFlash.ini (for the APPLICATION) */
/* */
/***********************************************************************/
/* */
/* XFLASH.INI: External Flash Initialization File */
/* */
/***********************************************************************/
// Do NOT use the Configuration Wizard tomodify this file ! ! !
DEFINE INT EMC_BASE; // EMC Base Address
DEFINE INT EMC_CTRL_REG;
DEFINE INT EMC_STAT_REG;
DEFINE INT EMC_CONFIG_REG;
DEFINE INT EMC_DYN_CTRL_REG;
DEFINE INT EMC_DYN_RFSH_REG;
DEFINE INT EMC_DYN_RD_CFG_REG;
DEFINE INT EMC_DYN_RP_REG;
DEFINE INT EMC_DYN_RAS_REG;
DEFINE INT EMC_DYN_SREX_REG;
DEFINE INT EMC_DYN_APR_REG;
DEFINE INT EMC_DYN_DAL_REG;
DEFINE INT EMC_DYN_WR_REG;
DEFINE INT EMC_DYN_RC_REG;
DEFINE INT EMC_DYN_RFC_REG;
DEFINE INT EMC_DYN_XSR_REG;
DEFINE INT EMC_DYN_RRD_REG;
DEFINE INT EMC_DYN_MRD_REG;
DEFINE INT EMC_DYN_CFG0_REG;
DEFINE INT EMC_DYN_RASCAS0_REG;
//note: missing the other dyn mem registeroffsets.
DEFINE INT EMC_STA_CFG1_REG;
DEFINE INT EMC_STA_WWEN1_REG;
DEFINE INT EMC_STA_WOEN1_REG;
DEFINE INT EMC_STA_WRD1_REG;
DEFINE INT EMC_STA_WPAGE1_REG;
DEFINE INT EMC_STA_WWR1_REG;
DEFINE INT EMC_STA_WTURN1_REG;
//note: missing the other static memregister offsets.
DEFINE INT EMC_STA_EXT_W_REG;
DEFINE INT PCONP_REG;
DEFINE INT EMCDLYCTL_REG;
DEFINE INT EMCCAL_REG;
DEFINE INT EMCClock;
DEFINE INT SCS_REG;
EMC_BASE = 0x2009C000; // EMC Base Address
EMC_CTRL_REG = EMC_BASE + 0x000;
EMC_STAT_REG = EMC_BASE + 0x004;
EMC_CONFIG_REG = EMC_BASE + 0x008;
EMC_DYN_CTRL_REG = EMC_BASE + 0x020;
EMC_DYN_RFSH_REG = EMC_BASE + 0x024;
EMC_DYN_RD_CFG_REG = EMC_BASE + 0x028;
EMC_DYN_RP_REG = EMC_BASE + 0x030;
EMC_DYN_RAS_REG = EMC_BASE + 0x034;
EMC_DYN_SREX_REG = EMC_BASE + 0x038;
EMC_DYN_APR_REG = EMC_BASE + 0x03C;
EMC_DYN_DAL_REG = EMC_BASE + 0x040;
EMC_DYN_WR_REG = EMC_BASE + 0x044;
EMC_DYN_RC_REG = EMC_BASE + 0x048;
EMC_DYN_RFC_REG = EMC_BASE + 0x04C;
EMC_DYN_XSR_REG = EMC_BASE + 0x050;
EMC_DYN_RRD_REG = EMC_BASE + 0x054;
EMC_DYN_MRD_REG = EMC_BASE + 0x058;
EMC_DYN_CFG0_REG = EMC_BASE + 0x100;
EMC_DYN_RASCAS0_REG = EMC_BASE + 0x104;
EMC_STA_CFG1_REG = EMC_BASE + 0x220;
EMC_STA_WWEN1_REG = EMC_BASE + 0x224;
EMC_STA_WOEN1_REG = EMC_BASE + 0x228;
EMC_STA_WRD1_REG = EMC_BASE + 0x22C;
EMC_STA_WPAGE1_REG = EMC_BASE + 0x230;
EMC_STA_WWR1_REG = EMC_BASE + 0x234;
EMC_STA_WTURN1_REG = EMC_BASE + 0x238;
EMC_STA_EXT_W_REG = EMC_BASE + 0x080;
PCONP_REG = 0x400FC0C4;
EMCDLYCTL_REG = 0x400FC1DC;
EMCCAL_REG = 0x400FC1E0;
EMCClock = 78000000;
SCS_REG = 0x400FC1A0;
FUNC void Setup (void) // Setup the LPC1788's EMC, EMC-relatedIOCON, etc etc...
{
// If the INTERNAL FLASH (in the LPC2468) has been programmed
// shortly before the EXTERNALFLASH, programming the EXTERNAL FLASH
// fails for whatever strangereason :
// - "could not stop ARMdevice", or
// - "Error: Flash Downloadfailed - ARM7TDMI", or
// - "function 'Setup'...AGDI: cannot access target while executing .. Erase failed!"
// - "function 'Setup',error 125, line 66: AGDI: memory write failed (0xE002C018)"
// If ONLY the EXTERNAL FLASH is programmed (after this script), itworks.
// The question is, what affectsthe LPC2468 in such a way
// that the external memoryinterface gets non-functional ?
_WDWORD(PCONP_REG, 0x0528FFFF ); // LPC_SC->PCONP, as seen in uVision4
if( _RDWORD(PCONP_REG) != 0x0528FFFF )
{ printf("Failed to initialize the LPC1788's PCONP register!\r\n");
}
//------------------------------------------------------------------
// Initialise the PORT PINS for the external memory interface.
// In the good(?) old days of LPC2xx, these were a few PINSEL registers.
// In the better(?) days of LPC17xx, these are many dozens of IOCONregisters.
printf("Trying to initialize IOCON registers... \r\n");
//***************************************************************************
// PIN CONFIGURATION (a myriad of IOCONS instead of a few PINSELS..sigh..)
// Most of the register values were copied from a 'working'configuration,
// displayed in uVision4's "peripheral" window . Project#11380 .
//***************************************************************************
_WDWORD(0x4002C140, 0x000000B1 ); // LPC_IOCON->P2_16 |= 1; // CASN @P2.16 (SDRAM Column Address Strobe)
_WDWORD(0x4002C144, 0x000000B1 ); // LPC_IOCON->P2_17 |= 1; // RASN @P2.17 (SDRAM Row Address Strobe)
_WDWORD(0x4002C148, 0x000000B1 ); // LPC_IOCON->P2_18 |= 1; // CLK[0]@ P2.18 (SDRAM System Clock)
_WDWORD(0x4002C150, 0x000000B1 ); // LPC_IOCON->P2_20 |= 1; //DYCSN[0] @ P2.20 (SDRAM Chip Select)
_WDWORD(0x4002C160, 0x000000B1 ); // LPC_IOCON->P2_24 |= 1; // CKE[0]@ P2.24 (SDRAM Clock Enable)
_WDWORD(0x4002C170, 0x000000B1 ); // LPC_IOCON->P2_28 |= 1; // DQM[0]@ P2.28 (SDRAM Data Input/Output Mask)
_WDWORD(0x4002C174, 0x000000B1 ); // LPC_IOCON->P2_29 |= 1; // DQM[1]@ P2.29 (SDRAM Data Input/Output Mask)
_WDWORD(0x4002C178, 0x000000B1 ); // LPC_IOCON->P2_30 |= 1; // DQM[2]@ P2.30 (SDRAM Data Input/Output Mask)
_WDWORD(0x4002C178, 0x000000B1 ); // LPC_IOCON->P2_31 |= 1; // DQM[3]@ P2.31 (SDRAM Data Input/Output Mask)
// 32 IOCON registers to configure 32 data bus lines (sigh....)
_WDWORD(0x4002C180, 0x000000B1 ); // LPC_IOCON->P3_0 |= 1; /* D0 @ P3.0 */
_WDWORD(0x4002C184, 0x000000B1 ); // LPC_IOCON->P3_1 |= 1; /* D1 @ P3.1 */
_WDWORD(0x4002C188, 0x000000B1 ); // LPC_IOCON->P3_2 |= 1; /* D2 @ P3.2 */
_WDWORD(0x4002C18C, 0x000000B1 ); // LPC_IOCON->P3_3 |= 1; /* D3 @ P3.3 */
_WDWORD(0x4002C190, 0x000000B1 ); // LPC_IOCON->P3_4 |= 1; /* D4 @ P3.4 */
_WDWORD(0x4002C194, 0x000000B1 ); // LPC_IOCON->P3_5 |= 1; /* D5 @ P3.5 */
_WDWORD(0x4002C198, 0x000000B1 ); // LPC_IOCON->P3_6 |= 1; /* D6 @ P3.6 */
_WDWORD(0x4002C19C, 0x000000B1 ); // LPC_IOCON->P3_7 |= 1; /* D7 @ P3.7 */
_WDWORD(0x4002C1A0, 0x000000B1 ); // LPC_IOCON->P3_8 |= 1; /* D8 @ P3.8 */
_WDWORD(0x4002C1A4, 0x000000B1 ); // LPC_IOCON->P3_9 |= 1; /* D9 @ P3.9 */
_WDWORD(0x4002C1A8, 0x000000B1 ); // LPC_IOCON->P3_10 |= 1; /* D10 @P3.10 */
_WDWORD(0x4002C1AC, 0x000000B1 ); // LPC_IOCON->P3_11 |= 1; /* D11 @P3.11 */
_WDWORD(0x4002C1B0, 0x000000B1 ); // LPC_IOCON->P3_12 |= 1; /* D12 @P3.12 */
_WDWORD(0x4002C1B4, 0x000000B1 ); // LPC_IOCON->P3_13 |= 1; /* D13 @P3.13 */
_WDWORD(0x4002C1B8, 0x000000B1 ); // LPC_IOCON->P3_14 |= 1; /* D14 @P3.14 */
_WDWORD(0x4002C1BC, 0x000000B1 ); // LPC_IOCON->P3_15 |= 1; /* D15 @P3.15 */
_WDWORD(0x4002C1C0, 0x000000B1 ); // LPC_IOCON->P3_16 |= 1; /* D16 @P3.16 */
_WDWORD(0x4002C1C4, 0x000000B1 ); // LPC_IOCON->P3_17 |= 1; /* D17 @P3.17 */
_WDWORD(0x4002C1C8, 0x000000B1 ); // LPC_IOCON->P3_18 |= 1; /* D18 @P3.18 */
_WDWORD(0x4002C1CC, 0x000000B1 ); // LPC_IOCON->P3_19 |= 1; /* D19 @P3.19 */
_WDWORD(0x4002C1D0, 0x000000B1 ); // LPC_IOCON->P3_20 |= 1; /* D20 @P3.20 */
_WDWORD(0x4002C1D4, 0x000000B1 ); // LPC_IOCON->P3_21 |= 1; /* D21 @P3.21 */
_WDWORD(0x4002C1D8, 0x000000B1 ); // LPC_IOCON->P3_22 |= 1; /* D22 @P3.22 */
_WDWORD(0x4002C1DC, 0x000000B1 ); // LPC_IOCON->P3_23 |= 1; /* D23 @P3.23 */
_WDWORD(0x4002C1E0,0x000000B1 ); // LPC_IOCON->P3_24 |= 1; /* D24 @ P3.24 */
_WDWORD(0x4002C1E4, 0x000000B1 ); // LPC_IOCON->P3_25 |= 1; /* D25 @P3.25 */
_WDWORD(0x4002C1E8, 0x000000B1 ); // LPC_IOCON->P3_26 |= 1; /* D26 @P3.26 */
_WDWORD(0x4002C1EC, 0x000000B1 ); // LPC_IOCON->P3_27 |= 1; /* D27 @P3.27 */
_WDWORD(0x4002C1F0, 0x000000B1 ); // LPC_IOCON->P3_28 |= 1; /* D28 @P3.28 */
_WDWORD(0x4002C1F4, 0x000000B1 ); // LPC_IOCON->P3_29 |= 1; /* D29 @P3.29 */
_WDWORD(0x4002C1F8, 0x000000B1 ); // LPC_IOCON->P3_30 |= 1; /* D30 @P3.30 */
_WDWORD(0x4002C1FC, 0x000000B1 ); // LPC_IOCON->P3_21 |= 1; /* D31 @P3.31 */
// 22 IOCON registers to configure 22 address bus lines (sigh........)
_WDWORD(0x4002C200, 0x000000B1 ); // LPC_IOCON->P4_0 |= 1; /* A0 @ P4.0 */
_WDWORD(0x4002C204, 0x000000B1 ); // LPC_IOCON->P4_1 |= 1; /* A1 @ P4.1 */
_WDWORD(0x4002C208, 0x000000B1 ); // LPC_IOCON->P4_2 |= 1; /* A2 @ P4.2 */
_WDWORD(0x4002C20C, 0x000000B1 ); // LPC_IOCON->P4_3 |= 1; /* A3 @ P4.3 */
_WDWORD(0x4002C210, 0x000000B1 ); // LPC_IOCON->P4_4 |= 1; /* A4 @ P4.4 */
_WDWORD(0x4002C214, 0x000000B1 ); // LPC_IOCON->P4_5 |= 1; /* A5 @ P4.5 */
_WDWORD(0x4002C218, 0x000000B1 ); // LPC_IOCON->P4_6 |= 1; /* A6 @ P4.6 */
_WDWORD(0x4002C21C, 0x000000B1 ); // LPC_IOCON->P4_7 |= 1; /* A7 @ P4.7 */
_WDWORD(0x4002C220, 0x000000B1 ); // LPC_IOCON->P4_8 |= 1; /* A8 @ P4.8 */
_WDWORD(0x4002C224, 0x000000B1 ); // LPC_IOCON->P4_9 |= 1; /* A9 @ P4.9 */
_WDWORD(0x4002C228, 0x000000B1 ); // LPC_IOCON->P4_10 |= 1; /* A10 @P4.10 */
_WDWORD(0x4002C22C, 0x000000B1 ); // LPC_IOCON->P4_11 |= 1; /* A11 @P4.11 */
_WDWORD(0x4002C230, 0x000000B1 ); // LPC_IOCON->P4_12 |= 1; /* A12 @P4.12 */
_WDWORD(0x4002C234, 0x000000B1 ); // LPC_IOCON->P4_13 |= 1; /* A13 @P4.13 */
_WDWORD(0x4002C238, 0x000000B1 ); // LPC_IOCON->P4_14 |= 1; /* A14 @P4.14 */
_WDWORD(0x4002C23C, 0x000000B1 ); // LPC_IOCON->P4_15 |= 1; /* A15 @ P4.15*/
_WDWORD(0x4002C240, 0x000000B1 ); // LPC_IOCON->P4_16 |= 1; /* A16 @P4.16 */
_WDWORD(0x4002C244, 0x000000B1 ); // LPC_IOCON->P4_17 |= 1; /* A17 @P4.17 */
_WDWORD(0x4002C248, 0x000000B1 ); // LPC_IOCON->P4_18 |= 1; /* A18 @P4.18 */
_WDWORD(0x4002C24C, 0x000000B1 ); //LPC_IOCON->P4_19 |= 1; /* A19 @ P4.19 */
_WDWORD(0x4002C250, 0x000000B1 ); // LPC_IOCON->P4_20 |= 1; /* A20 @P4.20 */
_WDWORD(0x4002C254, 0x000000B1 ); // LPC_IOCON->P4_21 |= 1; /* A21 @P4.21 */
_WDWORD(0x4002C258, 0x000000B1 ); // LPC_IOCON->P4_22 |= 1; /* A22 @P4.22 */
// NOT HERE: _WDWORD(0x4002C25C, _RDWORD(0x4002C25C) | 0x1); //LPC_IOCON->P4_23 |= 1; /* A23 @ P4.23 */
// Configure a few more port pins for the STATIC memory interface .
// Unused lines (which don't apply to this hardware)
// are COMMENTED OUT but notremoved !
// If you remove these comments, you will be doomed in programmer's hell!
_WDWORD(0x4002C260, 0x000000B1 ); // LPC_IOCON->P4_24 |= 1; /* /OE @P4.24 */
_WDWORD(0x4002C264, 0x000000B1 ); // LPC_IOCON->P4_25 |= 1; /* /WE @P4.25 */
// NO: _WDWORD(0x4002C268, _RDWORD(0x4002C268) | 0x1); //LPC_IOCON->P4_26 |= 1; /* BLSN[0] @ P4.26 */
// NO: _WDWORD(0x4002C26C, _RDWORD(0x4002C26C) | 0x1); //LPC_IOCON->P4_27 |= 1; /* BLSN[1] @ P4.27 */
// NO: _WDWORD(0x4002C270, _RDWORD(0x4002C270) | 0x1); //LPC_IOCON->P4_28 |= 1; /* BLSN[2] @ P4.28 */
// NO: _WDWORD(0x4002C274, _RDWORD(0x4002C274) | 0x1); // LPC_IOCON->P4_29|= 1; /* BLSN[3] @ P4.29 */
// _WDWORD(0x4002C278, 0x000000B1 ); // LPC_IOCON->P4_30 |= 1; /*/CS0 @ P4.30 */
_WDWORD(0x4002C27C, 0x000000B1); // LPC_IOCON->P4_31 |= 1; /* CS1 @P4.31 */
// NO: _WDWORD(0x4002C27C, _RDWORD(0x4002C27C) | 0x1); //LPC_IOCON->P4_31 |= 1; /* CSN[1] @ P4.31 */
// NO: _WDWORD(0x4002C138, _RDWORD(0x4002C138) | 0x1); //LPC_IOCON->P2_14 |= 1; /* CSN[2] @ P2.14 */
// NO: _WDWORD(0x4002C13C, _RDWORD(0x4002C13C) | 0x1); //LPC_IOCON->P2_15 |= 1; /* CSN[3] @ P2.15 */
printf("Trying to initialize EMC... \r\n");
//*********************************************
// External Memory Controller (inside the LPC1788)
//*********************************************
_WDWORD(EMC_CTRL_REG, 0x1); // LPC_EMC->Control= 0x00000001;
_WDWORD(EMC_CONFIG_REG, 0x0); //LPC_EMC->Config = 0x00000000;
_WDWORD(SCS_REG, 0x00000061 ); // value seen in the LPC1788's SCS register during a debugger session
printf("Trying to initialize STATIC MEMORY CONTROLLER...\r\n");
//*********************************************
// STATIC MEMORY CONFIGURATION
// Note (WoBu): The EMC / static memory controller
// doesn't seem to work whenclocked with
// more than 80(?) MHz.
// NO NUMBER OF WAITSTATES WILLHELP THEN !
//*********************************************
_WDWORD(EMC_STA_CFG1_REG, 0x00000081); //LPC_EMC->StaticConfig1 = 0x00000081;
_WDWORD(EMC_STA_WWEN1_REG, 0x00000003); //LPC_EMC->StaticWaitWen1 = 0x00000003;/* ( n + 1 ) -> 4 clock cycles */
_WDWORD(EMC_STA_WOEN1_REG, 0x00000003); //LPC_EMC->StaticWaitOen1 = 0x00000003;/* ( n ) -> 0 clock cycles */
_WDWORD(EMC_STA_WRD1_REG, 0x00000005); //LPC_EMC->StaticWaitRd1 = 0x00000005;/* ( n + 1 ) -> 7 clock cycles */
_WDWORD(EMC_STA_WPAGE1_REG, 0x00000008); // LPC_EMC->StaticWaitPage1 =0x00000008; /* ( n + 1 ) -> 4 clock cycles */
_WDWORD(EMC_STA_WWR1_REG, 0x0000000A); // LPC_EMC->StaticWaitWr1 = 0x0000000A; /* ( n + 2 ) -> 7 clockcycles */
_WDWORD(EMC_STA_WTURN1_REG, 0x00000007); // LPC_EMC->StaticWaitTurn1 =0x00000007; /* ( n + 1 ) -> 4 clock cycles */
_sleep_(100); // Wait for some reason
//==========================================================================================
// printf("Tryingto initialize SDRAM ... \r\n");
//
// _WDWORD(EMCDLYCTL_REG, 0x00101010); // LPC_EMC->StaticConfig1 = 0x00000081;
// _WDWORD(EMC_DYN_RD_CFG_REG, 0x00000001);
// _WDWORD(EMC_DYN_RAS_REG, 0x00000303);
// _WDWORD(EMC_DYN_RP_REG, 0x00000003);
// _WDWORD(EMC_DYN_RAS_REG, 0x00000006);
// _WDWORD(EMC_DYN_SREX_REG, 0x00000009);
// _WDWORD(EMC_DYN_APR_REG, 0x00000001);
// _WDWORD(EMC_DYN_DAL_REG, 0x00000006);
// _WDWORD(EMC_DYN_WR_REG, 0x00000003);
// _WDWORD(EMC_DYN_RC_REG, 0x00000009);
// _WDWORD(EMC_DYN_RFC_REG, 0x00000009);
// _WDWORD(EMC_DYN_XSR_REG, 0x00000009);
// _WDWORD(EMC_DYN_RRD_REG, 0x00000003);
// _WDWORD(EMC_DYN_MRD_REG, 0x00000003);
//
//
// _WDWORD(EMC_DYN_CFG0_REG, 0x00000680);
// _WDWORD(EMC_DYN_CTRL_REG, 0x00000183);
// _sleep_(10000);
// _WDWORD(EMC_DYN_CTRL_REG, 0x00000103);
// _WDWORD(EMC_DYN_RFSH_REG, 0x00000002);
// _sleep_(10000);
// _WDWORD(EMC_DYN_RFSH_REG, 0x0000003b);
// _WDWORD(EMC_DYN_CTRL_REG, 0x00000083);
// _RDWORD(0xa0000000| (0x33<<12));
//
// _WDWORD(EMC_DYN_CTRL_REG, 0x00000000);
// _WDWORD(EMC_DYN_CFG0_REG, _RDWORD(EMC_DYN_CFG0_REG)|(1<<19));
//
// _sleep_(10000);
//
//
//==========================================================================================
printf("Trying to initialize the LPC1788's SP and PC...\r\n");
// SP = _RDWORD(0xa0000000); // Setup Stack Pointer
// PC = _RDWORD(0xa0000004); // Setup Program Counter
// _WDWORD(0xE000ED08, 0xa0000000); // Setup Vector Table Offset Register
SP = _RDWORD(0x00000000); // Setup Stack Pointer
PC = _RDWORD(0x00000004); // Setup Program Counter
_WDWORD(0xE000ED08, 0x00000000); // Setup Vector Table Offset Register
printf("Finished Setup() for the external FLASH memory .\r\n");
_sleep_(100); // Wait for some reason
}
Setup(); // Setup for Flash
附件二:
; Windows USB CDC Setup File
; Copyright (c) 2000 Microsoft Corporation
; Copyright (c) 2006 Recursion Co., Ltd.
[Version]
Signature="$Windows NT$"
;类选择为端口
Class=Ports
;使用的安装类GUID。该GUID类的设备为“端口 (COM和 LPT)”,
;可以在注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class中找到它。
;在设备管理器中我们可以看到最后生成的设备被放在了“端口 (COM 和 LPT)”之下。
;并且打开设备的属性可以看到设备的类型为“端口 (COM 和 LPT)”。
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
;驱动程序的提供商,它将显示在设备属性的驱动程序标签页中的驱动程序提供商中。
;驱动程序提供商名称COMPANY在该文件最后被定义,它是一个字符串。
Provider=%COMPANY%
;使用layout.inf文件
LayoutFile=layout.inf
;驱动程序的日期和版本号。驱动安装器根据此来判断驱动程序的新旧。
;它们会显示在设备属性的驱动程序标签页中。
DriverVer=05/11/2014,1.0.0.1
[Manufacturer]
;制造商名称。会在设备属性窗口的常规标签的制造商中显示。
;MFGNAME在该文件最后最后被定义。
%MFGNAME% = ManufName
[DestinationDirs]
;目标文件夹的位置。12为system32目录。
DefaultDestDir=12
[ManufName]
;这里设置显示设备的名称以及匹配的ID号。
;Modem3是在后面定义的一个字符串,修改它可以显示不同的设备名称。
;后面的USB\VID_8888&PID_0007表示该驱动所匹配的设备,需要根据自己
;的设备设置。我们的设备VID为8888,PID为0007。
%Modem3% = Modem3,USB\VID_1FC9&PID_0003
;------------------------------------------------------------------------------
; Windows 2000/XP Sections
;------------------------------------------------------------------------------
[Modem3.nt]
CopyFiles=USBModemCopyFileSection
AddReg=Modem3.nt.AddReg
[USBModemCopyFileSection]
;需要复制usbser.sys文件,该文件是windows2000/XP自带的
usbser.sys,,,0x20
[Modem3.nt.AddReg]
;增加注册表项
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,usbser.sys
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
[Modem3.nt.Services]
;增加驱动服务
AddService=usbser, 0x00000002,DriverService
[DriverService]
DisplayName=%SERVICE%
ServiceType=1
StartType=3
ErrorControl=1
ServiceBinary=%12%\usbser.sys
;------------------------------------------------------------------------------
; String Definitions
;------------------------------------------------------------------------------
;这些是根据自己需要定义的字符串,可以按照自己的需要来修改它们,
;它们只是一些供显示用的字符串,没有实际的意义,用户可以随便修改。
[Strings]
;公司名称
COMPANY="XXXXXX"
;制造商名称
MFGNAME="XX"
;设备名称,它将显示在设备管理器中
Modem3="SPST-1100A"
;服务名称
SERVICE="USB2UART Driver"
附件三:
μc/GUI 一般移植过程
移植的版本为3.90a,主要包含的文件夹如下图所示,主要涉及到:
1. Config:配置文件
2. GUI:源代码
3. GUI_X:操作系统接口函数
GUI 源代码文件:
1) AntiAlias:9 个C 文件,主要用于抗锯齿的显示效果。
2) ConvertColor:彩色显示的色彩转换支持。
3) ConvertMono:(b/w)和灰度显示的色彩转换支持。
4) Core:核心文件,提供了GUI 基本的功能。
5) Font:字库。
6) JPEG:图片操作函数。
7) LCDDriver:LCD 驱动程序
8) MenDev:Memorydevice 支持。这个东西可用在很多情况下,但最主要
的功能是防止在项目重叠时,防止屏幕的闪烁。
9) Widget:窗体控件库。
10) WM:窗口管理库。
注意:JPEG、MenDev、Widget、WM 都可以裁减掉,若要支持Widget(窗体控
件),需要WM(窗口管理器)的支持;使用控件时,需要将相应的头文件包含
进去,比如我们要使用按钮button,那么我们需要先包含button.h 头文件,否则控
件即使支持也不可用!
一、Config 文件夹配置文件修改
1. LCDConfig.h
#define LCD_XSIZE (240) // X-resolutionof LCD, Logical coor.
#define LCD_YSIZE (320) //Y-resolution of LCD, Logical coor.
#define LCD_BITSPERPIXEL (16) //像素位宽
#define LCD_FIXEDPALETTE (565) //TFT格式
#define LCD_CONTROLLER (9325) //控制器型号(-1 即可)
#define LCD_SWAP_RB (1) //是否红蓝交换
注意:LCD_SWAP_RB 会影响到颜色的正确性,倘若发现颜色是反向的,那么
不如改变LCD_SWAP_RB 的值。
2. GUIConfig.h
#define GUI_OS (0) //单任务支持
#define GUI_SUPPORT_TOUCH (1) //支持触摸屏
#define GUI_SUPPORT_UNICODE (1) //UNICODE 支持
#define GUI_DEFAULT_FONT&GUI_Font6x8 //默认字体
#define GUI_ALLOC_SIZE 7000 //动态内存(不支持内存设备可小些)
#define GUI_WINSUPPORT 1 //支持窗口操作
#define GUI_SUPPORT_MEMDEV 1//Menory devices 支持
#define GUI_SUPPORT_AA 1 //支持抗锯齿显示
3. GUI_TOUCH_Conf.h
#define GUI_TOUCH_AD_LEFT 200 //触摸屏左侧AD 测量值
#define GUI_TOUCH_AD_RIGHT 3850 //触摸屏左侧AD 测量值
#define GUI_TOUCH_AD_TOP 200 //触摸屏上方AD 测量值
#define GUI_TOUCH_AD_BOTTOM 3700 //触摸屏底部AD 测量值
#define GUI_TOUCH_SWAP_XY 0 //X、Y 方向翻转
#define GUI_TOUCH_MIRROR_X 0 //X 方向镜像
#define GUI_TOUCH_MIRROR_Y 0 //Y 方向镜像
二、LCDDriver 文件夹修改
修改LCDDriver 中c 文件,实现LCD_L0_Init() 初始化、
LCD_L0_Set_PixelIndex()画点、LCD_L0_Get_PixelIndex()读取点值、LCD_On()、
LCD_Off()。
注意:LCDDriver 下有三个文件,任选其一就行,我选择LCDDummy.c,还必
须去掉文件中的宏判断语句,否则整个文件不会被编译。
三、GUI/Core 中函数修改(不支持触摸屏可不修改)
修改GUI_TOUCH_DriverAnalog.c 中一下参数值, 使其和
GUI_TOUCH_Conf.h 中一致。
GUI_TOUCH_AD_LEFT 最左侧AD 转换值
GUI_TOUCH_AD_RIGHT 最右侧AD 转换值
GUI_TOUCH_AD_TOP 顶部AD 转换值
GUI_TOUCH_AD_BOTTOM 底部AD 转换值
四、创建GUI_X 文件夹
1. GUI_X.c:操作系统相关接口函数(不带操作系统可不修改)
注意:GUI_X.c 在sample\GUI_X 文件夹下,不在GUI 文件夹下,需
要自己手动加进去,否则会出现N 多错误。
2. GUI_X_TOUCH.c(不支持触摸屏可不修改):
void GUI_TOUCH_X_ActivateX(void) {}
void GUI_TOUCH_X_ActivateY(void) {}
int GUI_TOUCH_X_MeasureX(void) {Touch_MeasurementX();}
int GUI_TOUCH_X_MeasureY(void) {Touch_MeasurementY();}
GUI_TOUCH_X_MeasureX() 读取X 方向AD 转换值
GUI_TOUCH_X_MeasureY() 读取Y 方向AD 转换值
1) 查询方式:
专门开一个任务不停调用GUI_TOUCH_Exec()(此函数有去除抖动功能)
2) 中断方式:
读取X、Y 的AD 转换值,看AD 转换值是否合法(X 在最左、最右之间,
Y 在最上、最下之间)。如不合法,GUI_TOUCH_StoreState(-1,-1)。如果合法,
通过_AD2X()、_AD2Y()函数转换成坐标值(x,y)。GUI_TOUCH_StoreState(x,
y)将读取的坐标值告诉GUI。
附件四:
/*T9-ucGUI*/
/*author:gaojy*/
/*date:2013-4-25*/
#include "includes.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "GUI.h"
#include "t9mb.h"
#include "t9.h"
//È«¾Ö±äÁ¿
static WM_HWIN sg_hTargetWnd = 0; //ÊäÈëµÄÄ¿±ê´°¿Ú.
static WM_HWIN hIMEWnd = 0;
int IMEMode; //
const T9PY_IDX* pt9idx;
char en_Buf[MAX_KEY_CHAR]; //µ±Ç°µÄ×Öĸ(ÓÃÓÚÓ¢ÎÄÊäÈ뷽ʽ)
char py_key[MAX_PY_LENGTH+1]; //ÖÐÎÄÊäÈëÖÐÆ´ÒôÊäÈë¼üÐòÁÐ
char py_Buf[MAX_PY_SAME][MAX_PY_LENGTH+1]; //Æ´Òô
unsigned char hz_Buf[MAX_HZ_COUNT*2]; //ºº×Ö
unsigned char fh_Buf[50];
int perpagecount; //ÿҳÏÔʾµÄÎÄ×Ö¸öÊý
int input_type; //ÊäÈ뷽ʽ 0:Æ´Òô,1:Ó¢ÎÄ,2:·ûºÅ
int cur_status; //ÊäÈë״̬ 0.ÊäÈë״̬; 1.Ñ¡Ôñ״̬
int start_point; //ÏÔʾÊý¾ÝµÄÆðʼλÖÃ
int py_keycounts; //ÖÐÎÄÊäÈë¼ü¸öÊý(Æ´Òô³¤¶È)
int cur_py; //µ±Ç°Æ´ÒôÐòºÅ
int py_count; //Æ´Òô¸öÊý
//function define
static void InputKeyProcess(unsigned char key);//, LPARAM lParam);
static void init_ime_parameter(void);
static void RefreshIMEBox(WM_HWIN hWnd);//, HDC hDC);
static void ClrInBuf(void);
static unsigned char py_key_filter(char key); //Æ´ÒôÊäÈë¼üÊÇ·ñÓÐЧ
static void get_py_from_table(void);
static void get_hz_from_table(char* py);
static void get_en_from_table(char key);
static void ime_writemsg(int sindex);
static void delete_last_py(void);
char*ime_method[3]={"Æ´Òô","english",",."};
static const unsigned char fh_table[] ="~!@#$%^&*()_+{}|:\"<>?`-=[]\\;',./£¬¡£¡®¡¯¡°¡±";
//static GUI_POINT point={0,0};
GUI_POINTpPoint[]={{0,0},{IMEWidth-1,0},{IMEWidth-1,IMEHeight-1},{0,IMEHeight-1}};
//funcion process
static void init_ime_parameter(void)
{
memset(fh_Buf,0,50);
memcpy(fh_Buf,fh_table,strlen(fh_table));
perpagecount =MAX_ROW_COUNTS;
cur_py = 0;
py_keycounts = 0;
py_count = 0;
start_point = 0;
input_type = IMEMode; //ĬÈÏÊäÈ뷽ʽ
cur_status = 0; //³õʼÊäÈë״̬
}
static void ClrInBuf(void)
{
switch(input_type)
{
case 0:
memset(hz_Buf,0,MAX_HZ_COUNT*2);
memset(py_key,0,MAX_PY_LENGTH+1); //Çå³ýÆ´ÒôÊäÈë
memset(py_Buf,0,MAX_PY_LENGTH+1);
py_keycounts= 0;
cur_status= 0;
cur_py= 0;
start_point= 0;
py_count= 0;
break;
case 1:
memset(en_Buf,0,MAX_KEY_CHAR);
cur_status= 0;
break;
case 2:
cur_status= 1; //·ûºÅÊäÈëÖ±½Ó½øÈëÑ¡Ôñ״̬
break;
}
}
static void RefreshIMEBox(WM_HWIN hWnd)//, HDC hDC)
{
char str[100];
char sstr[100];
chartmppy[MAX_PY_LENGTH+1]; //µ±Ç°Æ´Òô
char tmpstr[4]; //¶ÁÈ¡ºº×Ö
// const GUI_FONT*oldFont;
int fontHeight;
int i;
int pos_x, cWidth,sWidth; //»æÖÆÑ¡Ôñ¿ò
memset(str,0,100);
strcpy(str,ime_method[input_type]); //дÊäÈ뷽ʽ±êʶ
GUI_SetBkColor(GUI_WHITE);
GUI_Clear();
GUI_SetColor(GUI_DARKGRAY);
GUI_DrawPolygon(pPoint,4,0,0);
GUI_SetFont(&GUI_FontHZ16);
GUI_SetColor(GUI_BLUE);
GUI_SetTextAlign(GUI_TA_VCENTER);
switch(input_type)
{
case 0: //input chinese
GUI_DispStringAt(str,2,POSUP);
//============================================»ÖÐÏß
GUI_SetColor(GUI_GRAY);
GUI_DrawHLine(POSMID,2, IMEWidth-4);
//============================================
fontHeight= GUI_GetFontSizeY();
cWidth= fontHeight/2; //ucguiÖÐÊÇ·ñÓлñÈ¡µ±Ç°×ÖÌå×Ö·û×î´ó¿í¶ÈµÄº¯Êý£¿£¿£¿
pos_x= (strlen(str))*cWidth;
if(py_keycounts>0)
{
get_py_from_table(); //get py from table
if(cur_status== 0) //Ï»®Ï߸ßÁÁÏÔʾѡÔñµÄÆ´Òô
{
for(i=0;i<py_count;i++)
sprintf(str,"%s%s",str,py_Buf[i]);
for(i=0;i<cur_py;i++)
pos_x+= (strlen(py_Buf[i])+1)*cWidth;
sWidth= (strlen(py_Buf[cur_py]))*cWidth+6;
GUI_SetColor(GUI_LIGHTGREEN);
GUI_FillRect(pos_x,POSUP-cWidth-2,sWidth+pos_x,POSUP+cWidth+2);
// GUI_DrawHLine(fontHeight+3,pos_x, sWidth+pos_x);
}
elseif(cur_status == 1)
sprintf(str,"%s%s",str,py_Buf[cur_py]);
GUI_SetColor(GUI_BLUE);
GUI_SetTextMode(GUI_TM_TRANS);
GUI_DispStringAt(str,2,POSUP);
memset(tmppy,0,MAX_PY_LENGTH+1);
strncpy(tmppy,py_Buf[cur_py],MAX_PY_LENGTH);
get_hz_from_table(tmppy); //get hz from table
memset(str,0,4*perpagecount+2);
if((start_point>= perpagecount) && (cur_status == 1))
sprintf(str,"%s","<");
else
sprintf(str,"%s","");
memset(sstr,0,4*perpagecount);
for(i=0;i<perpagecount;i++)
{
memset(tmpstr,0,4);
tmpstr[0]= hz_Buf[(start_point+i)*2];
tmpstr[1]= hz_Buf[(start_point+i)*2+1];
tmpstr[2]= '\0';
if(tmpstr[0]!='\0'|| tmpstr[1] != '\0')
{
if(cur_status== 0) sprintf(sstr,"%s %s",sstr,tmpstr);
elseif(cur_status == 1) sprintf(sstr,"%s%d.%s",sstr,i,tmpstr);
}
}
if((((start_point+perpagecount)*2)< strlen(hz_Buf)) && (cur_status == 1))
sprintf(str,"%s%s%s",str,sstr,">");
else
sprintf(str,"%s%s%s",str,sstr,"");
GUI_SetColor(GUI_BLUE);
GUI_DispStringAt(str,2,POSDOWN);
}
break;
case 1: //Ó¢ÎÄÊäÈëÏÔʾ
GUI_DispStringAt(str,2,POSUP);
memset(str,0,60);
//============================================»ÖÐÏß
GUI_SetColor(GUI_GRAY);
GUI_DrawHLine(POSMID,2, IMEWidth-4);
//============================================
// GetTextExtent(HDC_SCREEN, en_Buf, strlen(en_Buf), &size);
fontHeight= GUI_GetFontSizeY();
for(i= 0; i < strlen(en_Buf); i++){
if(cur_status== 0)
sprintf(str,"%s%c",str,en_Buf[i]);
elseif(cur_status == 1)
sprintf(str,"%s%d.%c",str,i,en_Buf[i]);
}
// TextOut(hDC,2+2,size.cy+2,str);
GUI_SetColor(GUI_BLUE);
// GUI_SetFont(&GUI_Font10_1);
GUI_DispStringAt(str,2+2,POSDOWN);
break;
case 2: //·ûºÅÊäÈë
GUI_DispStringAt(str,2,POSUP);
fontHeight= GUI_GetFontSizeY();
memset(str,0,4*perpagecount+2);
//============================================»ÖÐÏß
GUI_SetColor(GUI_GRAY);
GUI_DrawHLine(POSMID,2, IMEWidth-4);
//============================================
if((start_point>= perpagecount) && (cur_status == 1))sprintf(str,"%s","< ");
else sprintf(str,"%s"," ");
memset(sstr,0,4*perpagecount);
for(i=0;i<perpagecount;i++){
if((start_point+i)<32)
sprintf(sstr,"%s%d %c",sstr,i,fh_Buf[start_point+i]);
else{
if((fh_Buf[32+(start_point+i-32)*2]!= '\0')||(fh_Buf[32+(start_point+i-32)*2+1] != '\0')){
memset(tmpstr,0,4);
tmpstr[0]= fh_Buf[32+(start_point+i-32)*2];
tmpstr[1]= fh_Buf[32+(start_point+i-32)*2+1];
sprintf(sstr,"%s%d %s",sstr,i,tmpstr);
}
}
}
if((start_point+perpagecount)< 38 && (cur_status == 1))
sprintf(str,"%s%s%s",str,sstr," >");
else
sprintf(str,"%s%s%s",str,sstr," ");
GUI_SetColor(GUI_BLUE);
GUI_DispStringAt(str,2,POSDOWN);
break;
}
}
static void get_hz_from_table(char* py)
{
int i;
unsigned charmatchflag = 0;
pt9idx = t9PY_index;
memset(hz_Buf,0,MAX_HZ_COUNT*2);
while(pt9idx->PY[0]!= '\0'){
matchflag =1;
if(strlen(pt9idx->PY)== py_keycounts){
for(i=0;i<py_keycounts;i++){
if(py[i]!= pt9idx->PY[i])
matchflag= 0;
}
}
else
matchflag= 0;
if(matchflag){
i =0;
while(pt9idx->MB[i]!= '\0'){
hz_Buf[i]= pt9idx->MB[i];
i++;
}
break;
}
pt9idx++;
}
}
static void get_py_from_table(void)
{
int i;
unsigned charmatchflag;
pt9idx = t9PY_index;
py_count = 0;
for(i=0;i<MAX_PY_SAME;i++)
memset(py_Buf[i],0,MAX_PY_LENGTH+1);
while(pt9idx->T9[0]!= '\0'){
matchflag =1;
if(strlen(pt9idx->T9)== py_keycounts){
for(i=0;i<py_keycounts;i++){
if(py_key[i]!= pt9idx->T9[i]) matchflag = 0;
}
}
else
matchflag= 0;
if(matchflag){
strcpy(py_Buf[py_count++],pt9idx->PY);
}
pt9idx++;
}
}
static unsigned char py_key_filter(char key)
{
chartmpkey[MAX_PY_LENGTH];
int i;
unsigned charmatchflag;
unsigned charnewpyflag; //ÊäÈë¼üÊÇ·ñÓÐЧ
pt9idx = t9PY_index;
strcpy(tmpkey,py_key); //¼Ç¼ÒÑÊäÈë¼üÐòÁÐ
if(py_keycounts <MAX_PY_LENGTH){
sprintf(tmpkey,"%s%c",tmpkey,key); //ÔÝ´æÐÂÊäÈë¼ü
newpyflag =0;
while(pt9idx->T9[0]!= '\0'){
matchflag= 1;
if(strlen(pt9idx->T9)== py_keycounts +1){
for(i=0;i<py_keycounts+1;i++){
if(tmpkey[i]!= pt9idx->T9[i]) matchflag = 0;
}
}
else
matchflag= 0;
if(matchflag)return 1;
pt9idx++;
}
}
return 0;
}
static void get_en_from_table(char key)
{
T9EN_IDX* penidx;
int i = 0;
penidx =(T9EN_IDX*)t9EN_index;
for(i=0;i<8;i++){
if(key ==penidx->key[0]){
strcpy(en_Buf,penidx->Letter);
cur_status= 1;
break;
}
penidx++;
}
}
static void ime_writemsg(int sindex)
{
// WORD wDByte;
unsigned char cc [10];
WM_MESSAGE msg = {0};
switch(input_type){
case 0: /*½«Ñ¡ÔñµÄºº×ÖдÈëÎı¾¿ò*/
if(sindex< perpagecount){
cc[0]= hz_Buf[(start_point + sindex)*2];
cc[1]= hz_Buf[(start_point + sindex)*2 + 1];
cc[2]= 1;
strcat(cc,py_Buf[cur_py]);
msg.MsgId= WM_CHAR;
msg.Data.p= cc;
msg.hWinSrc= hIMEWnd;
if(sg_hTargetWnd&& ((cc[0]!=0)||(cc[1]!=0)))
{
WM_SendMessage(sg_hTargetWnd,&msg);
ClrInBuf();
}
}
break;
case 1: /*½«Ñ¡ÔñµÄÓ¢ÎÄ×ÖĸдÈëÎı¾¿ò*/
if((sg_hTargetWnd)&&(en_Buf[sindex] != '\0')){
cc[0]= en_Buf[sindex];
cc[1]= 1;
cc[2]= en_Buf[sindex];
cc[3]= 0;
msg.MsgId= WM_CHAR;
msg.Data.p= cc;
msg.hWinSrc= hIMEWnd;
WM_SendMessage(sg_hTargetWnd,&msg);
ClrInBuf();
}
break;
case 2: /*½«Ñ¡ÔñµÄ·ûºÅдÈëÎı¾¿ò*/
if(sindex< perpagecount){
msg.MsgId= WM_CHAR;
if((start_point+ sindex)<32){
cc[0]= fh_Buf[start_point + sindex];
cc[1]= 1;
cc[2]= fh_Buf[start_point + sindex];
cc[3]= 0;
msg.Data.p= cc;
msg.hWinSrc= hIMEWnd;
if(sg_hTargetWnd)
WM_SendMessage(sg_hTargetWnd,&msg);
}
else{
cc[0]= fh_Buf[32+(start_point+sindex-32)*2];
cc[1]= fh_Buf[32+(start_point+sindex-32)*2+1];
cc[2]= 1;
cc[3]= fh_Buf[32+(start_point+sindex-32)*2];
cc[4]= fh_Buf[32+(start_point+sindex-32)*2+1];
cc[5]= 0;
msg.Data.p= cc;
msg.hWinSrc= hIMEWnd;
if (sg_hTargetWnd)
WM_SendMessage(sg_hTargetWnd,&msg);
}
}
break;
}
WM_SetFocus(hIMEWnd);
}
/*ɾ³ý×î½üÒ»¸öÆ´Òô×Öĸ*/
static void delete_last_py(void)
{
chartmpkey[MAX_PY_LENGTH];
memset(tmpkey,0,MAX_PY_LENGTH);
memcpy(tmpkey,py_key,py_keycounts-1);
memset(py_key,0,MAX_PY_LENGTH);
memcpy(py_key,tmpkey,py_keycounts--);
cur_py = 0;
start_point = 0;
}
static void InputKeyProcess(unsigned char key)//, LPARAM lParam)
{
const char ckey[] ="0123456789";
char skey = 0;
int sel_index = 0;
skey = (char)ckey[key- myKEY_0];
sel_index = (int)(key- myKEY_0);
switch(cur_status){
case 0: //¼üÅÌÊäÈë״̬(Ö»ÓÐÖÐ/Ó¢ÎÄÊäÈë²Å½øÈë´Ë״̬)
if(key>= myKEY_2)
{
switch(input_type){
case0: //ÖÐÎÄÊäÈë
if(py_key_filter(skey))
{
sprintf(py_key,"%s%c",py_key,skey); //±£´æÊäÈë¼ü
cur_py=0;
start_point=0;
py_keycounts++;
}
break;
case1: //Ó¢ÎÄÊäÈë
if(key>= myKEY_0)
get_en_from_table(skey);
break;
}
}
// elseif(key == myKEY_0)
// if(sg_hTargetWnd)PostMessage(sg_hTargetWnd,MSG_KEYDOWN,SCANCODE_SPACE,0);
break;
case 1: //Ñ¡Ôñ״̬
ime_writemsg(sel_index);
break;
}
}
//-------------------ÊäÈë·¨´°¿Ú»Øµ÷º¯Êý------------------
void T9IMEWinProc (WM_MESSAGE *msg)
{
// HDC hdc;
WM_MESSAGE msgTemp =*msg;
switch(msg->MsgId)//message)
{
caseWM_CREATE:
init_ime_parameter(); //³õʼ»¯ÊäÈë·¨
memset(en_Buf,0,MAX_KEY_CHAR);
memset(py_key,0,MAX_PY_LENGTH+1);
memset(py_Buf,0,MAX_PY_SAME* (MAX_PY_LENGTH+1));
memset(hz_Buf,0,MAX_HZ_COUNT*2);
break;
case WM_KEY:
switch(msg->Data.v)
{
caseGUI_KEY_ESCAPE: //.ESC¼ü¹Ø±ÕÊäÈë·¨
msgTemp.MsgId= WM_DELETE;
WM_SendMessage(hIMEWnd,&msgTemp);
break;
caseGUI_KEY_BACKSPACE: //.Backspace¼ü(#)
switch(input_type)
{
case0:
if(cur_status== 1)
cur_status= 0;
else
{
if(strlen(py_key)>0)
{
delete_last_py(); //ɾ³ýÇ°Ò»¸öÆ´Òô×Öĸ
WM_Paint(hIMEWnd);
}
else
{
if(sg_hTargetWnd)
WM_SendMessage(sg_hTargetWnd,&msgTemp);
}
}
break;
case1:
if(cur_status== 1)
{
ClrInBuf(); //Çå³ýÓ¢ÎÄÊäÈ룿
WM_Paint(hIMEWnd);
}
else
{
if(sg_hTargetWnd)
WM_SendMessage(sg_hTargetWnd,&msgTemp);
}
break;
case2:
if(sg_hTargetWnd)
WM_SendMessage(sg_hTargetWnd,&msgTemp);
break;
}
break;
caseGUI_KEY_UP:
// caseSCANCODE_TAB: //.Tab¼ü(*): Çл»ÊäÈë·¨
#if0
if(++input_type> 2)
{
if(nCurrentLanguage== EN)
{
input_type= 1;
}
else
{
input_type= 0;
}
}
#endif
ClrInBuf();
WM_Paint(hIMEWnd);
break;
caseGUI_KEY_DOWN:
if(sg_hTargetWnd)
{
msgTemp.Data.v= GUI_KEY_SPACE;
WM_SendMessage(sg_hTargetWnd,&msgTemp);
}
caseGUI_KEY_LEFT: //ÏòÇ°·Ò³
switch(input_type)
{
case0:
if(cur_status== 0 && py_count > 0 && cur_py >0)
cur_py--;
elseif(cur_status == 1 && (strlen(hz_Buf)/2) > perpagecount)
{
if(start_point>= perpagecount)
start_point-= perpagecount;
}
elseif(py_count == 0)
{
if(sg_hTargetWnd)
{
msgTemp.Data.v= GUI_KEY_LEFT;
WM_SendMessage(sg_hTargetWnd,&msgTemp);
}
}
break;
case1:
if(sg_hTargetWnd)
{
msgTemp.Data.v= GUI_KEY_LEFT;
WM_SendMessage(sg_hTargetWnd,&msgTemp);
}
break;
case2:
if(start_point>=perpagecount) start_point -= perpagecount;
break;
}
WM_Paint(hIMEWnd);
break;
caseGUI_KEY_RIGHT: //Ïòºó·Ò³
switch(input_type)
{
case0:
if(cur_status== 0 && py_count >0 && cur_py < py_count-1)
cur_py++;
elseif(cur_status == 1 && (strlen(hz_Buf)/2) > perpagecount)
{
if((start_point +perpagecount) < strlen(hz_Buf)/2)
start_point+= perpagecount;
}
elseif(py_count == 0)
{
if(sg_hTargetWnd)
{
msgTemp.Data.v= GUI_KEY_RIGHT;
WM_SendMessage(sg_hTargetWnd,&msgTemp);
}
}
break;
case1:
if(sg_hTargetWnd)
{
msgTemp.Data.v= GUI_KEY_RIGHT;
WM_SendMessage(sg_hTargetWnd,&msgTemp);
}
break;
case 2:
if((start_point+ perpagecount) < 38)
start_point+= perpagecount;
break;
}
WM_Paint(hIMEWnd);
break;
//ÊäÈëÑ¡Ôñ
caseGUI_KEY_ENTER: //Enter¼ü
switch(input_type)
{
case0:
if(hz_Buf[0]!= '\0')
{
if(cur_status==0)
{
cur_status= 1;
WM_Paint(hIMEWnd);
}
else
{
ime_writemsg(0);
}
}
else
{
msgTemp.MsgId= WM_INPUT_OVER;
WM_SendMessage(sg_hTargetWnd,&msgTemp);
}
break;
case1:
if(en_Buf[0]!= '\0')
{
ime_writemsg(0);
}
else
{
msgTemp.MsgId= WM_INPUT_OVER;
WM_SendMessage(sg_hTargetWnd,&msgTemp);
}
break;
case2:
// ime_writemsg(0);
msgTemp.MsgId= WM_INPUT_OVER;
WM_SendMessage(sg_hTargetWnd,&msgTemp);
break;
}
break;
}
break;
caseWM_CHAR:
if((unsigned char)(msg->Data.v)>=myKEY_0 && (unsigned char)(msg->Data.v) <= myKEY_9)
InputKeyProcess((unsignedchar)(msg->Data.v));
WM_Paint(hIMEWnd);
break;
caseWM_PAINT:
RefreshIMEBox(hIMEWnd);
break;
// caseWM_DELETE:
// WM_DeleteWindow(hIMEWnd);
// break;
default:
WM_DefaultProc(msg);
}
}
WM_HWIN T9IMEWindow(WM_HWIN host, int x0, int y0, int imemode)
{
if((imemode<3)&&(imemode>0))
IMEMode =imemode;
else
IMEMode = 0;
sg_hTargetWnd = host;
hIMEWnd =WM_CreateWindow(x0,y0,IMEWidth,IMEHeight,WM_CF_SHOW,T9IMEWinProc,0);
return hIMEWnd;
}
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x00000000 { ; load region size_region
SYSTEM_LOW.bin 0x00000000
{
*.o (RESET, +First)
*(InRoot$$Sections)
startup_lpc177x_8x.o (+RO)
system_lpc177x_8x.o (+RO)
main.o (+RO)
}
SRAM_SYSTEM 0x10000000
{
startup_lpc177x_8x.o(+RW,+ZI)
; system_lpc177x_8x.o (+RW,+ZI)
; main.o (+RW,+ZI)
}
}
ROM_LOW 0x00008000
{
LOW.bin 0x00008000
{
program_entry.o(i.start_boot, +First)
*.o (+RO)
}
SDRAM_LOW 0xa00000000x1000000
{
.ANY(+RW,+ZI)
}
}
LR_ROM2 0x90000000 0x00300000 {
NORFLASH_LOW.bin 0x900000000x00300000 { ; load address = execution address
; *.o (.constdata)
hzk16.o
hzk24.o
_bm*.o
t9.o (.constdata)
gui_ucs2gb.o (.constdata)
gui_gb2ucs.o (.constdata)
f6x8.o (.constdata)
f08_1.o (.constdata)
f08_ascii.o (.constdata)
f13_1.o (.constdata)
f13_ascii.o (.constdata)
f16_ascii.o (.constdata)
f24_ascii.o (.constdata)
fd24x32.o (.constdata)
fd32.o (.constdata)
}
}
附件六:
//计算M3向量表校验和,写入0x0000001c
iap_update_area= (uint8_t*)IAP_BUFFER_SYSTEM;
for(i=0;i<=24; i+=4)
{
vector_table_add+= iap_update_area[i] + (iap_update_area[i+1]<<8) +(iap_update_area[i+2]<<16) + (iap_update_area[i+3]<<24);
}
vector_table_add= 0- vector_table_add;
iap_update_area[28]= (uint8_t)vector_table_add;
iap_update_area[29]= (uint8_t)(vector_table_add>>8);
iap_update_area[30]= (uint8_t)(vector_table_add>>16);
iap_update_area[31]= (uint8_t)(vector_table_add>>24);