WinCE下的SPI键盘硬件及驱动程序设计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
l t
Wi nCE下的SPI键盘硬件及驱动程序设计
■华北电力大学(保定)
■保定市排水总公司 支lJ智国
张伟丽
关键词 SPI通信协议 WinCE PDD层8051¥3C2410
1 硬件设计
系统的核心CPU采用韩国三星电子公司的嵌入式 ARM9系列芯片¥3C241O。该芯片内部集成了SPI、I C、 USB、I CD等多种接口。针对其SPI接口,用8051外接一 个4×4键盘电路,并用P0口实现一个SPI协议接口与 ¥3C2410的通信。
1.1 硬件电路连接
SPI接线电路如图1所示。
5.1k.q。][ ×4.
rNT1 正 l
nSS1/GPB6 PO.7 /1 P1.7 SPICLK一1,GPG7 PO・0 P1.6 -,q SPrMISO一1/GPE5 P0.1 -,q SPIM0SI一1/GPE6 PO.2 P1・5 P1.4 P1.0 EINT1/GPF1 PO.3 P1.1 P1.2 P1.3
图1 SPI接线电路
SPI接口:nSS1(从SPI设备的片选信号)、SPICI K一 1(同步时钟信号)、SPIMISO一1(SPI接收信号)、SPIMOSI 1(SPI发送信号)、EINT1(键盘按键中断信号)。 键盘按键:数字键0~9,方向键十、 、一、一,确定
键,取消键。
1.2 SPI通信协议
SPI(Serial Peripheral Interface)协议是一种串行通信 协议,时钟信号SCK产生同步脉冲,MISO为输入信号, MOSI为输出信号。¥3C2410使用V2.11版本SPI协议, 并支持DMA方式。¥3C2410 SPI时序如图2所示。
Cyde
S尸lCLK
MoSl
MlSo 1 I 2 l 3 I 4}5 l 6 I 7 l 8
图2¥3C2410 SPI时序
1.3 用8051实现SPI协议
当用户按下4×4键盘中的任意一个按键时,INT1端 变低,向CPU发出中断请求,执行中断服务程序扫描键 盘,判断按键。然后,设置P0.3为低电平,产生INT1中 断到¥3C2410。随后,¥3C2410通过SPI接口读取8051发 出的串行信号,并转换为具体的键值。具体的8051硬件
代码可参考驱动程序的代码。
2 WinCE键盘驱动结构
2.1 WinCE驱动程序的基本结构
WinCE下的驱动程序结构有两种:单体结构和分层 结构。单体结构即将通用的驱动程序接口和特定的硬件 接口在同一层面上实现;分层结构将同一设备的驱动程序 分成两层——平台相关驱动PDD和模型设备驱动MDD。 前者和具体的设备绑定在一起,是针对特定设备特定型号 的;后者是同一类设备驱动中公用的部分,主要由CE的
系统支持提供,通常不需要修改。
7 8《平 机 嵌入式条诧应内》l圈匝圈匝盈圈唧 adv@mesnet.corn.cn(广告专用)
维普资讯 http://www.cqvip.com 2.2 WinCE键盘驱动框架结构及接口函数
2.2.1键盘驱动框架结构
键盘驱动结构分为多层:键盘布局管理器和当前平台输
人语言属于MDD层,基本 上由WinCE操作系统实 现;矩阵键盘平台相关驱 动和矩阵键盘平台相关驱 动属于PDD层,与硬件设 备密切相关,由用户实现; 图形窗口引擎系统负责对
键盘驱动进行调用及管 理。矩阵键盘驱动结构框 图如图3所示。 I图形窗口引擎系统(GwEs)I ● ’ …, … J键盘布局管理器f ▲ ’ 矩阵键盘平台相关驱动l 当前平台 输入语言
} f l矩阵键盘设备布局
图3矩阵键盘驱动结构框图
2.2.2键盘驱动接口函数定义
由用户实现的键盘接口函数如下:
KeybdDriverlnitializeEx //键盘驱动初始化函数
KeybdDriverPowerHandler //电源管理
KeybdDriverGetInfo //获取驱动信息
KeybdDriverSetMode //设置驱动模式 KeybdDriverInitStates //初始化状态
KeybdDriverVKeyToUnicode//虚拟键码转换 KeybdDriverMapVirtualKey //虚拟键映射
LayoutMgrGetKeyboardType//键盘布局管理函数
… //省略部分不关键函数 Matrix //PDD矩阵键盘人口函数
2.3键盘驱动程序加载
winCE系统运行时默认启动NK.exe、GWES。exe、
FileSys。exe和Device.exe四个进程。其中GWES。exe进
程负责流键盘驱动的加载。GWES。exe进程会查找注册
表中的HKEY—I ()CAL—MACHINE\HARDWARE\DE—
VICEMAP\KEYBD中DriverName,将其加载到内存中,
然后调用kbdmouse。dll的KeybdDriverlnitializeEx函数
初始化键盘驱动。
2.4对键盘i/o口及寄存器操作
winCE对外部硬件的操作主要是通过控制硬件的
I/O接口及内部控制寄存器来实现的。由于WinCE通过 MMU(内存管理)单元操作内存,不能直接访问外部接口
及寄存器,因此必须用VirtualAlloc分配一块虚拟地址空
间,然后用VirtualCopy将硬件设备寄存器的物理地址与
VirtualAlloc分配的虚拟地址做一个映射关系,再通过操
纵虚拟地址操纵相应的寄存器及I/O接口。 2.5 中断处理
WinCE对外部硬件的响应主要是通过中断实现的,
主要包括中断初始化、中断等待及中断处理,流程如图4
所示。
r 广…一…] 虱IST I I
OEM硬件
图4 中断处理流程
①硬件设备向Kernel发送中断异常的代码。如果检
测到这个中断异常,就会被Kernel层的异常处理所截获。
②中断服务调度程序会调用OAL例程中的OEM—
InterruptDisable函数。这个函数会通知硬件在处理完这
一中断前关闭特殊的中断,但其他中断仍然处于开放
状态。
③调用中断服务例程ISR以决定如何处理这一
中断。
④Kernel接收到ISR的返回值以得知如何处理这一 中断。它的响应结果之一是忽略掉这一中断不作处理 (sYsINTR—N()P),另一结果是准备执行IST。
⑤Kernel引发中断服务调度程序来唤醒中断服务线
程去工作。IST是常规的Win32线程,一旦启动后,它会
创建必要的EVENT然后等待该EVENT被激发。中断
服务调度通过调用PulseEvent函数来激发EVENT,从而
唤醒IST线程运行。
⑥当唤醒以后,IST会对中断进行必要的处理,如将
数据移动到缓冲区或其他有意义的事。 ⑦如果需要,IST会借助于I/O支持例程访问硬件
设备。 ⑧当IST处理完成后,它会调用InterruptDone函数
通知Kernel。 ⑨Kernel调用OEMInterruptDone函数完成此次中
断的处理过程,OAL例程通知硬件设备重新启用中断。
3矩阵键盘驱动实现
人口函数KeybdDriverInitia1izeEx调用定义的键盘
PDD函数(g—rgpfnPddEntries定义),实现对SPI设备初
始化、外部键盘中断处理、虚拟键码转换等功能。
… … … r船碹士田、 h :………ll…R_F k ~… 7
9 维普资讯 http://www.cqvip.com 艨
3.1 SPl设备初始化
初始化主要包括:映射I/O控制寄存器及SPI寄存
器;初始化SPI设备两部分。 (1)映射I/o控制寄存器及SPI寄存器 ①读取注册表键值。主要有中断号、I/O控制寄存 器基地址、SPI控制寄存器基地址。 ②映射SPI控制及I/O控制寄存器。 //SPI控制寄存器v—pSPIregs基地址映射
v—pSPIregs=VirtualAlloc(0,sizeof(¥3C2410X—SPI—REG), MEM—RESERVE,PAGE—NOACCESS); VirtualCopy((PVOID)v—pSPIregs,(PVOID)(dwSSPBase), sizeof(¥3C2410X~SPI—REG),PAGE—READWRITE l PAGE— N()CACHE) I/O控制寄存器基地址v—plOPregs的映射与上面的 代码类似。 (2)初始化SPI设备 主要是对上面已经映射了的V pSPIregs、V pIOPregs 进行操作。 //设置EINT1(KBDINT)中断
v—pIOPregs GPFCON&=(~(0x3《2)I(0x2《2)); //设置GPF1脚为中断
v—pIOPregs EXTINTO&一(~(0x7《4)l(0x2《4)); //设置EINT1为下降沿触发 //设置SPI I/()接口
v—pIOPregs GPGCON&=~((Ox3《10)l(0x3<<12)l
(0x3《14));
v—pIOPregs一>GPGCON l=((0x3《10)l(0x3《12)I (0x3《14)); //设置nSS信号(nSS_KBD)
v_pIOPregs GPBCON .=(~(0x3<<12)I(ONEBIT<< 12)); //设置SPI寄存器
v—pSPIregs~>SPCON1=(ONEBIT<<5)I(ONEBIT<<4)l (ONEBIT<<3)I(0xO《2)I(ONEBIT<<1); //设置时钟频率
V pSPIregs SPPRE1—255:,//99.121 kHz
3.2按键信号中断处理
在Interruptlnitialize中初始化中断,然后在KeybdlstLoop 中调用WaitForSingleObject监听中断并调用,之后在中断处 理函数KeybdPdd_GetEventEx2对中断进行处理。关键代
码如下: //创建键盘事件、初始化中断
m—hevInterrupt—CreateEvent(NULL,FALSE,FALSE, NULL): InterruptInitialize(g—dwSysIntr—Keybd,rfl—hev!nterrupt, NULL,0) //关联中断事件、系统中断号、中断处理函数、键码虚拟码 //转换函数 keybdIst.hevInterrupt—m—hevInterrupt; keybdIst.dwSysIntr—Keybd=g—dwSysIntr—Keybd; //系统中断号 keybdIst.uiPddId=v—uiPddId; //PDD标识 keybdIst.pfnGetKeybdEvent=KeybdPdd—GetEventEx2; //键盘中断处理函数 keybdIst.pfnKeybdEvent—v_pfnKeybdEvent: //调用WaitForSingleObject监听中断 KeybdlstLoop(&keybdIst):
3.3键盘中断处理函数
在中断处理函数Keybd— Pdd_GetEventEx2中,主要完 成键盘数据的读取,数据流 程如图5所示。 关键代码如下: //选通键盘设备 选通键盘设备 + 等待设备准备好 ● 等待读取完毕 + 设置设备为非选通状态 + 读取键盘值
v_plOPregs GPBDAT 图5 SPl键盘数据读取流程
一~(ONEBIT<<6);//等待SPI设备准备好 while((v—pSPIregs SPSTA1&.ONEBIT)一一O); //开始读取
v—pSPIregs SPTDAT1—0xFF} //等待读取完毕
while((v—pSPIregs SPSTA1&ONEBIT)一一0); //设置设备为非选通状态
v—pIOPregs GPBDAT l一(ONEBIT<<6); //读取键盘值 Key=v—pSPIregs SPRDAT1;
3.4虚拟键码映射
虚拟键码映射主要是根据虚拟键码表把相应的硬件 码转换为WinCE系统键码,然后把WinCE系统键码传递
给layoutmgr。涉及的主要结构如下:
static DEVICE—LAYOUT dlMatrixEngUs={ sizeof(DEVICE—LAYOUT),MATRIX_PDD, rgscvkMatrixEngUSTables, dim(rgscvkMatrixEngUSTables),//虚拟键码表 MatrixUsRemapVKey //虚拟键转换函数 ); 其中函数MatrixUsRemapVKey负责硬件key到虚
拟键码转换。虚拟键码表格式如下: VirtualKeyMapping rgscvkMatrixEngUSTables[]一 {{1 ,VK—F1},{ 2 ,VK—F2},…}
3.5与应用程序交互
由键盘布局管理器(1ayoutmgr)调用函数SendRe— mappedEvent,产生键盘事件Keybd~Event给GWES,然
80 《平I亨机 嵌入式豪诧应用》 adv@mesnet.corn.on(广告专用)
维普资讯 http://www.cqvip.com