设计目的:
1.熟悉PS/2协议的原理
2.学习单片机的使用
设计内容:
依照PS/2协议,在51芯片上开发汇编程序,使得按下开发板上的按键时,能够在PC机上输出a、b、c。
实验环境:
开发板、STC12C2052AD芯片、PS/2线、PC机、Keil软件、STC-ISP程序下载器
相关参数:
单片机振荡频率6MHz(具体情况请看此型号单片机用户手册)
指令周期0.5微秒(51型单片机的指令周期是其振荡频率的12分之一)
PS/2连接器引脚定义(见参考文献《PS/2技术参考》)
能够接受的键盘时钟信号频率10-20KHz(最大33KHz,推荐设为15KHz)
设计思想:
使用开发板上的按钮产生中断信号,使单片机进入相应的中断处理程序,从而向PC机发送相应的扫描码。PC机主板中有一个解码芯片,此芯片在收到扫描码之后,引发PC机操作系统的中断(I/O的中断),转到操作系统中的中断处理程序,从面在系统中输出相应字符。
原理:
实际的通用键盘上的每一个键都对应一个唯一个扫描码,这些键会在极短的时间内被扫描一遍,以确认它们有没有被按下,如果某个键被按下了,就发送其相应的扫描码。而在开发板上,51芯片有三个按键,对应芯片上的两个中断口和一个定时/计数器输入口。中断接口可以直接使用,当按下键时就触发中断,而定时/计数器需要设置为初始值为FFH,一旦按下键便会溢出而产生中断的计数器。
主机与键盘有四根线相连,时钟信号数、数据线、接地线、电源线。
时钟信号在任何时刻都是由键盘产生的,PC机在时种的下降沿接收数据线上的信号,要是PC机向键盘发送数据,则键盘在时钟的上升沿接收数据线上的数据。虽是由键盘产生时钟信号,但是PC机对总线有着绝对的控制权,只要其将时钟线拉低(高低电平信号有这样的特性:只有一端的信号为低电平,则整条线的信号都为低电平。这就是为什么要向单片机I/O口输出一个信号,要先将外部输入单片机这个I/O口的信号释放(拉高)。否则输出的永远都是低电平),就要以抵制键盘的输出。
总线上有这些几种状态:
1、PC等待键盘输出状态(键盘可以输出状态):CLK=1,DATA=1;
2、键盘等待PC输出状态(PC可以输出状态):CLK=1,DATA=0(这个状态之前还有一些状态要生产生的,详情请见参考文献《PS/2技术参考》)
3、正在输出状态:此时的时钟线与数据线上的信号没有定值,依据所要发送的数据不同而不同,CLK=X,DATA=X
键盘从外部存储器中读取相应键位的扫描码,当要改变某个键所要发送的扫描码时,只需改变外部存储器中对应位置的扫描码,这样就可以方便地改变某键所要发送的扫描码。在存放扫描码时,只需将扫描码按顺序存放,如E0,70按存储地址从小到大顺序地排列。因为通码(make code)最多只有两个十六进制数,且如有两个则第一个必是E0H,而断码(break code)最多只有三个,且如果有三个,则第一个必是E0H,如果有二个,则第一个必是F0H。所以,当发送时,如果发现第一个是E0H或F0H的话,则再发送其后的一个扫描码。
注意事项:
1、
发送8个数据位时,是低位先发送(least significant bit first),如果是用高位先发送,主机自然是无法识别会发送的数据,会报警;
2、
如果想要精确计算时间,那么像子程序调用语句会占用两个指令周期也应该考虑到;
3、
连接线应该连在指示灯靠近51芯片的一端,否则无法接收到主机发来的信号;PS/2
4、
汇编程序前的org 语句必须按其指示的地址大小排列,小的在前,大的在后;
程序:
;
=======================================
; program
; check clk and data before every 8 bit data sending
; a function is created for send all 11bit data
; a function is created for parity calculating
; CAPSLOCK :BIG LETTER P1.3=0,SMALL LETTER P1.3=1
; =======================================
; =======================================
; VARS USED LOCALY
; R0 IS USED LOCALY AS A COUNTER
; 20H.1 20H.2 20H.3 20H.4 IS USED IN FUNCTION AS TEMP VAR
; R3,R4,R5 USED LOCALLY IN DELAY()
; ===================================
; Define Samples
; ====================================
MCLK EQU P1 .2 ; VALUE OF CLOCK LINE
MDATA EQU P1 .1 ; VALUE OF DATA LINE
SCAN EQU R1 ; VALUE OF THE SCAN CODE
RECV EQU R2 ; VALUE RECEIVED BY KEYBOARD
RECV2 EQU R6 ; THE VALUE RECEIVED SECONDLY
NEXTBIT EQU CY ; VALUE OF THE BIT WILL SENT NEXT
PARITY EQU 20H .1 ; VALUE OF PARITY
TEMP EQU 20H .2 ; THIS BIT IS FOR TEMPORITARY USE
TEMP1 EQU 20H .3 ; THIS BIT IS FOR TEMP USE
TEMP8BIT EQU 21H
LOOPCOUNTER EQU 30H ; COUNTER SPECIAL FOR SENDALLBIT
SCROLLLOCK EQU P1 .5
CAPSLOCK EQU P1 .6
NUMLOCK EQU P1 .7
ERROR_LIGHT EQU P1 .4 ; PARITY ERROR
ERROR_LIGHT_STOPBIT EQU P1 .3 ; STOP BIT RECEIVE ERROR
; ===================================
; ===================================
; ORG
; ===================================
ORG 00H
JMP MAIN
ORG 0003H
LJMP K1DOWN
ORG 000BH
LJMP K3DOWN
ORG 0013H
LJMP K2DOWN
; ============================================================
; MAIN
; ============================================================
MAIN:
; ==============================
; SET INTERRUPTER AND TIMER
mov ie , #10000101B ; 中断使能
mov ip , #00H ; 中断优先
mov tcon , #00000101b ; 中断为电平触发
; TIME0 AS A BUTTON
MOV TMOD , #06H
MOV TH0 , #0FFH
MOV TL0 , #0FFH
SETB ET0
SETB TR0
; ==============================
; ==============================
; SET CLK AND DATA LINE TO NORMAL STATUS
SETB MCLK
SETB MDATA
; ==============================
SETB CAPSLOCK ; CAPSLOCK OFF(1)
SETB NUMLOCK ; NUMLOCK OFF(1)
SETB SCROLLLOCK ; SCROLLLOCK OFF(1)
CHKSTATUS:
JNB MCLK , CHKSTATUS ; IF MCLK==0 THEN GOTO CHKSTATUS
JB MDATA , CHKSTATUS ; IF MDATA==1 THEN GOTO CHKSTAUS
; NOW MCLK=1 AND MDATA =0 ,READY TO RECEIVE DATA FROM PC
LCALL RECV_CHK_SEND ; RECEIVE DATA FROM PC
LJMP CHKSTATUS ; WAIT FOR BREAK
; =========
; program
; check clk and data before every 8 bit data sending
; a function is created for send all 11bit data
; a function is created for parity calculating
; CAPSLOCK :BIG LETTER P1.3=0,SMALL LETTER P1.3=1
; =======================================
; =======================================
; VARS USED LOCALY
; R0 IS USED LOCALY AS A COUNTER
; 20H.1 20H.2 20H.3 20H.4 IS USED IN FUNCTION AS TEMP VAR
; R3,R4,R5 USED LOCALLY IN DELAY()
; ===================================
; Define Samples
; ====================================
MCLK EQU P1 .2 ; VALUE OF CLOCK LINE
MDATA EQU P1 .1 ; VALUE OF DATA LINE
SCAN EQU R1 ; VALUE OF THE SCAN CODE
RECV EQU R2 ; VALUE RECEIVED BY KEYBOARD
RECV2 EQU R6 ; THE VALUE RECEIVED SECONDLY
NEXTBIT EQU CY ; VALUE OF THE BIT WILL SENT NEXT
PARITY EQU 20H .1 ; VALUE OF PARITY
TEMP EQU 20H .2 ; THIS BIT IS FOR TEMPORITARY USE
TEMP1 EQU 20H .3 ; THIS BIT IS FOR TEMP USE
TEMP8BIT EQU 21H
LOOPCOUNTER EQU 30H ; COUNTER SPECIAL FOR SENDALLBIT
SCROLLLOCK EQU P1 .5
CAPSLOCK EQU P1 .6
NUMLOCK EQU P1 .7
ERROR_LIGHT EQU P1 .4 ; PARITY ERROR
ERROR_LIGHT_STOPBIT EQU P1 .3 ; STOP BIT RECEIVE ERROR
; ===================================
; ===================================
; ORG
; ===================================
ORG 00H
JMP MAIN
ORG 0003H
LJMP K1DOWN
ORG 000BH
LJMP K3DOWN
ORG 0013H
LJMP K2DOWN
; ============================================================
; MAIN
; ============================================================
MAIN:
; ==============================
; SET INTERRUPTER AND TIMER
mov ie , #10000101B ; 中断使能
mov ip , #00H ; 中断优先
mov tcon , #00000101b ; 中断为电平触发
; TIME0 AS A BUTTON
MOV TMOD , #06H
MOV TH0 , #0FFH
MOV TL0 , #0FFH
SETB ET0
SETB TR0
; ==============================
; ==============================
; SET CLK AND DATA LINE TO NORMAL STATUS
SETB MCLK
SETB MDATA
; ==============================
SETB CAPSLOCK ; CAPSLOCK OFF(1)
SETB NUMLOCK ; NUMLOCK OFF(1)
SETB SCROLLLOCK ; SCROLLLOCK OFF(1)
CHKSTATUS:
JNB MCLK , CHKSTATUS ; IF MCLK==0 THEN GOTO CHKSTATUS
JB MDATA , CHKSTATUS ; IF MDATA==1 THEN GOTO CHKSTAUS
; NOW MCLK=1 AND MDATA =0 ,READY TO RECEIVE DATA FROM PC
LCALL RECV_CHK_SEND ; RECEIVE DATA FROM PC
LJMP CHKSTATUS ; WAIT FOR BREAK
; =========