原文:http://article.ednchina.com/Embedded/20071209103917.htm
来源:中电网 | 作者:杨振坤 甘朝晖 蒋旻

  引言

  近年来,嵌入式技术发展迅速,嵌入式系统在各行各业得到了广泛的应用。然而,由于嵌入式计算机的专用性,系统的硬件、软件结构千差万别,其输入设备也不再像通用计算机那样单一。

  嵌入式计算机的输入设备一般有鼠标、键盘、触摸屏、按钮、旋钮等,而光电编码器(俗称“单键飞梭”)作为一种输入设备,由于其具有输入灵活,简单可靠等特点,因此特别适合应用在嵌入式仪器和手持式设备上,整个系统可以只用一个键作为输入。触摸屏由于其方便灵活、节省空间、界面直观等特点也备受青睐,但存在寿命短,长时间使用容易产生误差等缺点。如果用光电编码器辅助触摸屏作为输入设备,必将大大增强系统的可靠性,使得人机接口更加人性化。但由于光电编码器并不是WinCE的标准输入设备,因此其驱动程序在嵌入式操作系统Windows CE Platform Builder中并未给出。本文以三星公司S3C2410(ARM9芯片)为CPU的嵌入式系统开发板为平台,详细阐述了嵌入式操作系统WinCE下光电编码器驱动程序的设计方法,以供同行参考。

  1 光电编码器的工作原理

  光电编码器(Optical Encoder)俗称“单键飞梭”,其外观好像一个电位器,因其外部有一个可以左右旋转同时又可按下的旋钮,很多设备(如显示器、示波器等)用它作为人机交互接口。下面以美国Greyhill公司生产的光电编码器为例,介绍其工作原理及使用方法。光电编码器的内部电路如图1所示,其内部有1个发光二极管和 2个光敏三极管。当左右旋转旋钮时,中间的遮光板会随旋钮一起转动,光敏三极管就会被遮光板有次序地遮挡,A、B相就会输出图2所示的波形;当按下旋钮时,2、3两脚接通,其用法同一般按键。

光电编码器的内部电路

图1 光电编码器的内部电路

光电编码器的输出波形

图2 光电编码器的输出波形

  当顺时针旋转时,光电编码器的A相相位会比B相超前半个周期;反之,A相会比B相滞后半个周期。通过检测A、B两相的相位就可以判断旋钮是顺时针还是逆时针旋转,通过记录A或B相变化的次数,就可以得出旋钮旋转的次数,通过检测2、3脚是否接通就可以判断旋钮是否按下。其具体的鉴相规则如下:

  ① A为上升沿,B=0时,旋钮右旋;

  ② B为上升沿,A=1时,旋钮右旋;

  ③ A为下降沿,B=1时,旋钮右旋;

  ④ B为下降沿,A=0时,旋钮右旋;

  ⑤ B为上升沿,A=0时,旋钮左旋;

  ⑥ A为上升沿,B=1时,旋钮左旋;

  ⑦ B为下降沿,A=1时,旋钮左旋;

  ⑧ A为下降沿,B=0时,旋钮左旋。

  通过上述方法,可以很简单地判断旋钮的旋转方向。在判断时添加适当的延时程序,以消除抖动干扰。

  2 WinCE提供的驱动模型

  WinCE操作系统支持两种类型的驱动程序。一种为本地驱动程序,是把设备驱动程序作为独立的任务实现的,直接在顶层任务中实现硬件操作,因此都有明确和专一的目的。本地设备驱动程序适合于那些集成到Windows CE平台的设备,诸如键盘、触摸屏、音频等设备。另一种是具有定制接口的流接口驱动程序。它是一般类型的设备驱动程序。流接口驱动程序的形式为用户一级的动态链接库(DLL)文件,用来实现一组固定的函数称为“流接口函数”,这些流接口函数使得应用程序可以通过文件系统访问这些驱动程序。本文讨论的光电编码器就属于流接口设备。

  2.1 流设备驱动加载过程

  WinCE.NET系统运行时会启动负责流驱动的加载进程DEVICE.exe。DEVICE.exe进程对驱动的加载是通过装载注册表列举器(RegEnum.dll)实现的。在WinCE.NET中,所有设备的资源信息都由OAL负责记录在系统注册表中,RegEnum.dll一个一个扫描注册表项HEKY_LOCAL_MACHINE\Driver\BuiltIn下的子键,发现新设备就根据每个表项的内容进行硬件设备初始化。

  2.2 中断与中断处理

  如果一个驱动程序要处理一个中断,那么驱动程序需要首先使用CreateEvent函数建立一个事件,调用 InterruptInitialize函数将该事件与中断标识绑定。然后驱动程序中的IST就可以使用WaitForSingleObject函数来等待中断的发生。在一个硬件中断发生之后,操作系统进入异常处理程序,异常处理程序调用OAL的OEMInterruptHandler函数,该函数检测硬件并将中断标识返回给系统;系统得到该中断标识便会找到该中断标识对应的事件,并唤醒等待相应事件的线程(IST),然后IST进行中断处理。处理完成之后,IST需要调用InterruptDone函数来告诉操作系统中断处理结束,操作系统再次调用OAL中的OEMInterruptDone函数,最后完成中断的处理。

图3为WinCE.NET中断处理的流程框图。

WinCE.NET中断处理流程框图

图3 WinCE.NET中断处理流程框图

  3 光电编码器驱动程序的设计

  3.1 光电编码器与S3C2410的硬件接口

  光电编码器与S3C2410的接口电路如图4所示。光电编码器的A、B相为集电极开路输出,由于S3C2410的I/O口电平为3.3 V,所以将其通过电阻上拉到3.3 V后再分别接到CPU的EINT0和EINT1上;将P1直接接到3.3 V,P2通过电阻下拉到GND。当旋钮按下时,P2口输出为高电平,否则输出为低电平。

光电编码器与S3C2410的接口电路

图4 光电编码器与S3C2410的接口电路

  工作状态下,将EINT0、EINT1配置成上升沿和下降沿均触发的外部中断,将EINT2配置成上升沿触发的中断,旋钮按下时EINT2引脚产生上升沿触发中断。

  3.2 外部中断初始化及中断服务程序的编写

  首先必须完成CPU的I/O口和中断的初始化工作,然后再编写中断处理程序。具体分为4个步骤:

  ① 初始化I/O口。在Port_Init()函数中,将EINT0和EI

NT1初始化为上升沿和下降沿均触发的中断,将EINT2初始化为上升沿触发的中断。

  ② 添加中断号。在oalintr.h下添加光电编码器中断向量的宏定义。代码为

  #define SYSINTR_OED(SYSINTR_FIRMWARE+20)

  ③ 添加中断的初始化、禁止、复位等函数,分别在OEMInterruptEnable()、OEMInterruptDisable()、OEMInterruptDone()等函数中加入相关代码。

  ④ 返回中断标识,由OEMInterruptHandler()函数返回中断标识(SYSINTR_OED)。

  3.3 编写流接口驱动程序

  Windows CE.net把中断处理分成两个部分:中断服务程序(ISR)和中断服务线程(IST)。ISR通常要求越短、越快越好,它的唯一任务就是返回中断标识。正由于ISR很小,只能做少量的处理,因此中断处理器就调用IST执行大多数的中断处理。中断服务线程(IST)在从 WaitForSingleObject()函数得到中断已经发生的信号前一直保持空闲;当接收到中断信号后,它就在本机设备驱动程序的PDD层调用子程序,这些程序反过来访问硬件以获得硬件的状态。IST使用InterruptInitialize()函数来注册自己,然后使用 WaitForSingleObject()函数等待中断信号。如果这时中断信号到来,则应将光电编码器的状态记录下来,保存在变量OED_Status 中。OED_Status=1表示旋钮按下,OED_Status=2表示旋钮逆时针旋转,OED_Status=3表示旋钮顺时针旋转。

  这里还有一种比较简单的鉴相规则,具体步骤是,当创建线程时读出EINT1的电平状态并保存在变量PreEINT1中,每次中断到来时首先判断 EINT2是否为高电平。如果为高电平,则说明按钮按下;如果EINT2为低电平,则判断EINT0电平是否与PreEINT1相同。如果相同,则说明旋钮逆时针旋转;反之,旋钮顺时针旋转,判断的流程如图5所示。

光电编码器鉴相流程框图

图5 光电编码器鉴相流程框图

  Windows CE流接口驱动程序模型要求驱动程序开发者编写10个接口函数,针对光电编码器的驱动主要应完成设备初始化和数据读取2个函数的编写。Windows CE设备文件名前缀由3个大写字母组成,操作系统使用这3个字母来识别与流接口驱动程序相对应的设备。这里定义设备文件名前缀为“OED” (Optical Encoder),其中设备初始化函数OED_Init()在Windows CE装载驱动程序时用于创建中断事件和中断服务线程。在函数OED_Read()中将光电编码器的状态(OED_Status)返回。

  3.4 封装驱动程序并加入到WinCE中

  根据上述方法编译出动态链接库(DLL)还不够,因为它的接口函数还没有导出,还需要告诉链接程序输出什么样的函数,因此必须建立一个后缀名为def的文件。在本设计中为OpticalEncoder.def。下面是此文件的内容:

LIBRARY OpticalEncoder
  EXPORTS
  OED_Close
  OED_Deinit
  OED_Init
  OED_IOControl
  OED_Open
  OED_PowerDown
  OED_PowerUp
  OED_Read
  OED_Seek
  OED_Write

一个具体的流接口驱动程序和注册表是密不可分的。向WinCE内核添加注册表项的方法有两种:一种是直接修改Platform Builder下的reg文件;另一种是自己编写一个注册表文件,通过添加组件的方法将动态链接库文件添加到内核中。这里用第2种方法,将 OpticalEncoder.dll添加到内核中。编写的注册表文件内容如下:

[HKEY_LOCAL_MACHINE\Drivers\Built In\STRINGS]
  Index=dword :1
  Prefix=OED
  Dll=OpticalEncoder.dll
  Order=dword :0

  最后编写一个CEC文件,完成对定制内核注册表部分的修改并将OpticalEncoder.dll添加到系统内核中去,然后在Platform Builder中就可以直接添加已经编写好的驱动程序了。

  结语

  本文主要介绍了光电旋转编码器的原理及应用方法,并详细介绍了WinCE驱动程序的结构,成功地开发出了光电编码器在嵌入式操作系统WinCE下的驱动程序。实验证明,该方法正确可行,程序运行稳定可靠。

转载于:https://www.cnblogs.com/harber/archive/2008/01/25/1053861.html

WinCE下光电编码器的驱动程序设计相关推荐

  1. WindowsCE.Net下CAN卡的驱动程序设计

    近年来电力行业为了快速部署变电站,采用了建造整体变电所的方法:在生产基地将变电站的内部设备安装.调试完成,只留下与外界的接口,整体运到变电站所在地后进行安装和简单调试即可投入运行.其内部设备通过CAN ...

  2. 如何在wince下添加和删除驱动(作者:wogoyixikexie@gliet)

    刚才我在C:/WINCE500/PLATFORM/SMDK2440A/Src/Drivers下直接把Dirs文件中的camera删除掉了,这样就不会编译camera文件夹下的代码了,但是却会出现如下编 ...

  3. WinCE下的USB游戏手柄驱动 GamePad Joystick

    USB接口的游戏手柄和键盘一样,称之为USB HID设备,在CE 系统已经有了 键盘/鼠标 两种HID 设备的驱动. 在public\common\oak\drivers\usb 下面已经有了两种设备 ...

  4. 开发wince下的usb音频设备驱动总结

    在做usb audio设备驱动开发前我还不知道有usb audio device class,以为这是个HID类型的驱动,开发起来应该容易实现,后来才发现原来自己进入了一个未知领域.幸亏之前有开发过m ...

  5. Wince下usb驱动详细总结(史无前例的详细)

    0,前言: 1, 本篇文章只讲wince下的usb host驱动,并深入解析HID驱动.本博客的目的并不是只是为了讲怎么写驱动, 更重要的是: 1,了解wince驱动的架构. 2,学习微软的写作方法, ...

  6. wince下sources\sources.cmn\Makefile.def的相关作用

    1:首先是Makefile.def: ---------------------------------------- 在所有驱动的makefile中有!INCLUDE $(_MAKEENVROOT) ...

  7. 基于WinCE的I2C驱动程序设计

    http://www.mcu123.com/news/Article/rtos/WinCE/200607/88.html 引言 随着以计算机技术.通信技术和软件技术为核心的信息技术的迅速发展,嵌入式系 ...

  8. 【WinCE】SD card技术了解并WINCE下SDHC驱动开发(updated)

    SD Card Driver on ADS Summary 了解SD card. 1 WinCE 5.0下SD Stack. 6 Bus Driver 7 Host Controller Driver ...

  9. WINCE下SOS驱动开发

    ********************************LoongEmbedded************************ 作者:LoongEmbedded(kandi) 时间:201 ...

最新文章

  1. linux 推荐硬件配置,2012最受欢迎的Linux用户硬件配置
  2. 30种编程语言的比较选择问题
  3. swift编写命令行工具
  4. Apache ActiveMQ 远程代码执行漏洞记录(CVE-2016-3088,端口:8186)
  5. 没想到!谷歌排名第一的编程语言,这样的学的话,更容易成为高手!
  6. 南阳理工acm括号配对问题
  7. C语言的风花雪夜(C语言下雪动画)
  8. 华为路由交换工程师学习笔记汇总
  9. 快速从入门到精通!黑马java课程大纲
  10. android桌面小部件开发
  11. 2.5导入和混合配置 P61 Spring实战 第四版
  12. 医院云PACS管理系统源码
  13. wps交叉表_使用WPS图表功能中的堆叠条形图制作日程交叉图
  14. 长安大学微型计算机原理与接口技术答案,长安大学微机原理与接口技术B卷答案...
  15. 总体规划,循序渐进,分步实施
  16. 菜鸟站长之家SEO工具大礼包多达上百个小工具
  17. Python中的GIL和异步Asyncio、Futures
  18. IOS – OpenGL ES 图像马赛克圆点 GPUImagePolkaDotFilter
  19. “阿里中台架构”15篇刷屏文章精选,快收藏!
  20. XML入门(四)使用STAX解析XML

热门文章

  1. a16z:推翻互联网的偶然君主制,如何设计Web3平台治理?
  2. 计算机word做课程表实验报告,《用Word制作课程表》“学讲方式”案例分析
  3. 软件破解网站列表--整理于2014-3-30
  4. 最形象的卷积神经网络详解:从算法思想到编程实现(转载)
  5. 中国商务电话服务行业市场供需与战略研究报告
  6. 用python实现随机生成银行卡号,输出卡号和密码信息
  7. 最新kali之swaks
  8. 计算机专业河南单招,河南单招计算机专业专科学校排名
  9. Misc,院赛:两道签到、忘记密码
  10. 人生修煉電影篇之-------------------- 《海王》