《电子技术应用》
您所在的位置:首页 > 嵌入式技术 > 业界动态 > 80C196单片机鼠标接口程序设计实例

80C196单片机鼠标接口程序设计实例

2008-10-16
作者:杨国田 白 焰1 徐培民2

    摘  要: 通过对鼠标底层通信原理及协议的深入分析,探讨了鼠标在80C196单片机系统中的应用价值与可行性,并介绍了鼠标接口软件设计的原理及方法,给出了80C196单片机与Microsoft鼠标的具体接口程序。 

    关键词: 鼠标  接口技术  软件设计  接口程序

 

    80C196单片机由于价格低、处理能力强,在信号分析、数据采集等很多领域得到广泛应用,在目标系统中使用各种规格的液晶或CRT显示器也越来越多。因此在这样的单片机系统中引入鼠标,将会方便操作,提高工作效率。鼠标内核本质上是一个二维的角度或位移信号检测装置,耗电极少、可靠性高、价格低廉,可以在许多场合发挥作用。鼠标与主机之间通过RS-232标准串行接口" title="串行接口">串行接口进行通信,信息传送是单方向、无条件、无应答连续进行的。此外80C196的UART不直接支持鼠标的接口协议,在程序设计" title="程序设计">程序设计中必须予以注意。本文主要探讨80C196单片机与Microsoft兼容鼠标接口程序的设计实现。 

1 鼠标信号发送协议与过程 

    鼠标是一个功能高度集中的小型机电一体化系统。它首先将直线位移转换成角度位移,再转变成数字量,然后与按钮状态统一编码,通过RS-232串口" title="串口">串口发出。鼠标工作所需功率从RS-232串行接口的控制线上窃取(PS/2、USB接口鼠标除外)。当鼠标被拖动" title="拖动">拖动超过一个最小距离或某一按钮被按下时,它按照规定的协议将移动的距离和按钮状态通过一次或几次信息发送到主机;主机上的鼠标驱动程序将信息变换成鼠标位置和按钮状态供其它程序模块调用。每发生一次移动或按钮状态变化,鼠标向上发送一次信息。通常一般鼠标的分辨率为400DPI。理论上即沿着某一方向每拖动一英寸(一般速度),会产生400次信息发送过程。如果拖动较快,则信息发送次数减少,但所反映的总的移动距离仍然是400步。 

    各种串行接口鼠标在物理层普遍采用标准的串行通信协议,波特率为1200bps。帧格式为7个数据位、2个停止位,无奇偶校验位。上层协议则在此基础上以十六进制数形式直接发送鼠标信息,包括:初始化报告;移动方向、距离、按钮状态。其一般形式如表1所示。 

 

 

2 鼠标接口程序设计 

    80C196系列单片机内设RS-232收发器,但需要配置接口芯片实现电平转换。考虑到鼠标从串口窃取功率,接口芯片必须具有一定的驱动能力,而不能采用简单的准RS-232电平转换器。这里采用MAX232E作为接口芯片。 

    图1中左侧为80C196单片机,P2.0(TXD)、P2.1(RXD)通过MAX232E形成满足鼠标要求的串行接口,包括生成标准RS-232C电平和提供电源供应。图1中最右边为9针或25针标准串行接插件。由于鼠标的电源供应采用功率窃取方案,由DTR/RTS提供,这里为DTR加限流电阻防止对鼠标造成伤害。RTS由MAX232E的信号发送端提供,通过80C196的P2.0控制MAX232E的10脚(对应的输出脚为7脚)电平高低以改变7脚电位,使鼠标可以接收来自RTS的控制命令,以实现鼠标安装与否的检测。在MAX232E的11脚(对应的输入脚为14脚)设置高电平以保证14脚电位为负RS-232电位,满足鼠标发送信号时的电平要求。 

 

 

    从链路层看,80C196串行接口的四种工作方式" title="工作方式">工作方式均不满足鼠标的帧格式要求;但其工作方式1(1位起始位、8位数据位、1位停止位)的总传送位数与鼠标(1位起始位、7个数据位、2个停止位)相同,均为10位。接收过程中80C196收到7个数据位后,将2个停止位中的第一个作为数据位装入接收缓冲器的最高位,由于停止位在物理层是高电平,作为数据被接收后相当于逻辑“0”;剩下的第二个停止位恰好为80C196 提供了有效的停止位。利用80C196的工作方式1完全可以保证正确接收鼠标信息。 

    单片机起动后,通过鼠标驱动模块对鼠标进行初始化,即通过P2.0使RTS电平翻转一次而令鼠标发送初始化报告,以确认鼠标是否安装。之后,鼠标即可随着拖动或按钮操作向单片机发送动作信息,经接口模块翻译即可反应鼠标位置和按钮状态。 

    鼠标接口模块主要包括按钮状态识别和位置识别两个部分。80C196将根据接收到的鼠标信息不断刷新鼠标信息缓冲区。由于鼠标事件间隔不确定,采用扫描方式不但会浪费CPU时间,还可能因来不及处理而丢失信息。有效的处理方法是采用中断方式接收,应用模块通过软件接口获得鼠标信息。完整的鼠标接口程序流程图如图2所示。在初始化阶段,首先检查鼠标是否存在,根据结果设置标志位,以备以后取鼠标信息时判断用;根据需要设定鼠标初始位置、按钮原始状态;最后设置串行接口参数(帧格式等)并开放鼠标中断。鼠标发送信息时,每三个字节为一个完整的信息报告。但80C196每接收到一个字节,就产生一次中断,然后根据当前字节是否大于40H确定其性质。若是信息报告的首字节,则还要进一步通过有效性检验后保存;若不是首字节,则必须经过一系列检验后保存起来。收到三个字节后立即进行命令分析和执行。具体处理过程可参看源程序。用户模块通过特定接口模块(图2(b))获得鼠标当前位置和按钮状态,并可通过进位标志C=0/1判断鼠标是否安装。 

 

 

 

    下面是图2、3程序流程图对应的程序清单。该程序要求80C196单片机的工作频率为12MHz;如果采用其它工作频率,通过修改串行口的波特率设置参数以及延时程序的时间常数即可。 

; 

; 8098 特殊功能寄存器预定义 

    R0          EQU   00H:Word 

    SBUF        EQU   07H:Byte 

    INT_MASK    EQU   08H:Byte 

    INT_PEND    EQU   09H:Byte 

    BAUD_RT     EQU   0EH:Byte 

    IOP2            EQU   10H:Byte 

    SP_CON      EQU   11H:Byte 

    SP_STAT     EQU   11H:Byte 

    IOC1        EQU   16H:Byte 

    SP          EQU   18H:Word 

    ; 

    ; 通用寄存器预定义 

    RSEG    AT     1CH 

        AX:     DSW    1 

        DX:     DSW    1 

        AL      EQU    AX:BYTE 

        AH      EQU    (AX+1):BYTE 

        DL      EQU    DX:BYTE 

        DH      EQU    (DX+1):BYTE 

        SCRNW   EQU    640  ;显示屏宽度 

        SCRNH   EQU    480  ;显示屏高度 

; 

; 变量区 

RSEG    AT      20H 

        M_X :  DSW    1        ;光标X值 

        M_Y  :  DSW    1        ;光标Y值 

        M_BUF:  DSB    4        ;接收缓冲区 

        M_P  :  DSW    1        ;接收指针 

        BX   :  DSW    1 

        LRB_OK: DSB    1        ;鼠标状态, 

;Bit7: 存在, Bit5: 左键, Bit4: 右键 

; 

CSEG    AT      2000H 

        DCW     INIT 

CSEG    AT      200CH 

        DCW     SIOINT 

        DCW     INIT 

        DCW     0 

        DCB     0, 0, 0, 0, 0, 0 

        DCB     08DH 

        DCB     000H 

        DCB     027H, 0FEH 

; 

CSEG    AT      2080H 

INIT:   LD      SP, #0100H     ;设堆栈指针 

        LD      M_X, #SCRNW/2  ;初始化指针 

        LD      M_Y, #SCRNH/2 

        ANDB    LRB_OK, #7CH 

        LD      M_P, #M_BUF 

        CLRB    INT_PEND        ;清除中断 

        LDB     INT_MASK, #40H ;开串行中断 

        LDB     AL, SP_STAT        ;清除RI/TI 

        LDB     SP_CON, #09H   ;设串口模式 

        LDB     BAUD_RT, #9BH  ;1200,12MHz 

        LDB     BAUD_RT, #80H 

        EI 

        ANDB    IOP2, #0FEH        ;P2.0=0 

        LD      AX, #8000H     ;延迟200ms 

DLY0:   DEC     AX 

        JNE     DLY0 

        LDB     AL, LRB_OK 

        JBS     AL,7, M_OK 

        ANDB    INT_MASK, #0BFH 

M_OK:NOP 

;  ... ... ... 

; 

;清单二:取鼠标信息,  

        AL=鼠标及按钮状态, BX=X, DX=Y 

GET_M:ANDB  INT_MASK, #0BFH  

        LDB     AL, LRB_OK     ;取鼠标信息 

        LD      BX, M_X 

        LD      DX, M_Y 

        ORB     INT_MASK, #40H 

        RET 

; 

;清单三:串口中断服务程序 

SIOINT: PUSHF               ;中断服务 

        PUSH    AX 

        LDB     AL, SBUF 

        LDB     AH, SP_STAT 

        JBS     AL, 6, ISB0       ;第一个字节 

        CMP     M_P, #M_BUF 

        JNE     SIO_1 

        SJMP    C99             ;缓冲区空,出错 

SIO_1:CMP   M_P, #M_BUF+2 

        JH      C98             ;缓冲区满,出错 

        STB     AL, [M_P]+     ;存储收到字节 

        CMP     M_P, #M_BUF+3 

        JNE     C99 

        LD      M_P, #M_BUF    ;已收到完整命令 

GOLR:LDB    AL, 1[M_P]     ;处理X方向位移 

        SHLB    AL, #2 

        EXTB    AL 

        SHRA    AX, #2 

        ADD     M_X, AX 

CKL:    CMP     M_X, #0 

        JGE     CKR 

        CLR     M_X 

CKR:    CMP     M_X, #SCRNW 

        JLT     GOUD 

        LD      M_X, #SCRNW 

GOUD:   LDB     AL, 2[M_P] ;处理Y方向位移 

        SHLB    AL, #2 

        EXTB    AL 

        SHRA    AX, #2 

        ADD     M_Y, AX 

CKU:    CMP     M_Y, #0 

        JGE     CKD 

        CLR     M_Y 

CKD:    CMP     M_Y, #SCRNH 

        JLT     ELRUD 

        LD      M_Y, #SCRNH 

ELRUD:  SJMP    C98 

ISB0:   STB     AL, M_BUF 

        ANDB    AL, #0FH 

        CMPB    AL, #03H 

        JE      C97             ;=X3H, 

        CMPB    AL, #0CH 

        JE      C97             ;=XCH 

        CMPB    AL, #0DH 

        JNE     C98             ;<>XDH 

        ORB     LRB_OK, #80H   ;确认鼠标正常 

C97:    ANDB    AL, M_BUF, #30H 

        ANDB    LRB_OK, #80H 

        ORB     LRB_OK, AL     ;更新左右键状态 

        LD      M_P, #M_BUF+1 

        SJMP        C99 

C98:    LD      M_P, #0000H 

C99:    POP     AX 

        POPF 

        RET 

; 

        END 

参考文献 

1 INTEL. 8XC196Kx,8XC196Jx,87C196CA Micro-controller Family User's Manual, 

2 徐君毅,张友德.单片微型计算机原理及应用.上海:上海科学技术出版社,1989 

3 孙涵芳,徐爱卿.MCS51-96系列单片机原理及应用.北京:北京航空学院出版社,1988 

4 MAXIM.新产品数据手册,第四卷.1995

本站内容除特别声明的原创文章之外,转载内容只为传递更多信息,并不代表本网站赞同其观点。转载的所有的文章、图片、音/视频文件等资料的版权归版权所有权人所有。本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如涉及作品内容、版权和其它问题,请及时通过电子邮件或电话通知我们,以便迅速采取适当措施,避免给双方造成不必要的经济损失。联系电话:010-82306118;邮箱:aet@chinaaet.com。