📄 hospital.asm.bak
字号:
;***********************************************************************
;医院寻呼,无线发射部分
;全部在键盘唤醒中断里完成
;
;***********************************************************************
; I/O PORT PIN DEFINED
KEY1 BIT P0.1 ;暂定为4个按键
KEY2 BIT P0.2
KEY3 BIT P0.3
KEY4 BIT P0.4
LED BIT P0.0 ;按键按下,LED亮
CS_93C BIT P0.6
SK_93C BIT P0.7
DI_93C BIT P1.0
DO_93C BIT P1.1
DATAOUT BIT P0.5 ;数据输出
;=================== PHILIPS PLC SFR DEFINED BEGAIN =======================
HPCON DATA 087H
;PD bit 087h.1 ;不能位寻址
AUXR1 EQU 0A2h ; 附助功能寄存器
;KBF BIT AUXR1.7
CMP1 EQU 0ACh ; 比较器 1 控制 寄存器
CMP2 EQU 0ADh ; 比较器 2 控制 寄存器
DIVM EQU 095h ; cpu 时钟 控制
I2CFG EQU 0C8h ; I2C 设置寄存器
CT0 bit I2CFG.0 ; 时钟选择0
CT1 bit I2CFG.1 ; 时钟选择1
TIRUN bit I2CFG.4 ; 计时器 I 使能位
CLRTI bit I2CFG.5 ; 清除计时器I
MASTRQ bit I2CFG.6 ; 主控器请求
SLAVEN bit I2CFG.7 ; 被控器使能
I2CON EQU 0D8h ; I2C 控制寄存器
MASTER bit I2CON.1 ; 主控器状态位
STP bit I2CON.2 ; 停止探测标志
STR bit I2CON.3 ; 开始探测标志
ARL bit I2CON.4 ; 仲裁失败标志
DRDY bit I2CON.5 ; 数据准备标志位
ATN bit I2CON.6 ; 注意: I2C 中断标志位
RDAT bit I2CON.7 ; I2C 读数据
I2DAT EQU 0D9h ; I2C 数据寄存器
IEN0 EQU 0A8h ; 中断使能0
ETO BIT IEN0.1 ;定时器0中断使能
EBO bit IEN0.5 ; 节电方式中断使能
EWD bit IEN0.6 ; 看门狗中断使能
IEN1 EQU 0E8h ; 中断使能寄存器 1
EI2 bit IEN1.0 ; I2C 中断使能
EKB bit IEN1.1 ; 键盘中断使能
EC2 bit IEN1.2 ; 比较器 2 中断使能
EC1 bit IEN1.5 ; 比较器 1 中断使能
ETI bit IEN1.7 ; 计时器 I 中断使能
IP0 EQU 0B8h ; 中断优先 0 低位
PBO bit IP0.5 ; 节电方式中断优先
KBI EQU 86h ; 键盘中断
CMP2O bit P0.0 ; 比较器2 输出
CIN2B bit P0.1 ; 比较器2 输入B
CIN2A bit P0.2 ; 比较器2 输入A
PT0AD EQU 0F6H ;0口数字输入禁能
P0M1 EQU 84H
P0M2 EQU 85H
P1M1 EQU 91H
P1M2 EQU 92H
;***********************************************************************
; 自己使用的RAM的定义
SEND_FINISH BIT 00H ;发送完成标志位。=1,还未完成。20H.1
KEY_VALUE EQU 31H ;按键值,2BIT
TIME_ADD EQU 32H ;地址是10BTI
TIME_CD_NUM EQU 33H ;自身地址是8位,两次都是。
TIMERS EQU 34H ;一共10次
SENDING_DATA EQU 35H
TIME_REP EQU 36H ;在发送0、1的子程序里使用,6BIT
ADD_93C_L EQU 37H
BYTE1_93C EQU 38H
BYTE2_93C EQU 39H
SEND_BUFFER1 EQU 40H ;要发送的数据暂存区
DATA1 EQU 42H
DATA2 EQU 43H
;***********************************************************************
ORG 0000H
AJMP SYS_START
ORG 0003H ; INT0外部中断0
CLR EX0
RETI
NOP
NOP
ORG 000BH ; TIME0 OUT定时0中断
CLR ET0
RETI
NOP
NOP
ORG 0013H ; INT1外部中断1
CLR EX1
RETI
NOP
NOP
ORG 001BH ; TIME1 OUT定时1中断
CLR ET1
RETI
NOP
NOP
NOP
ORG 0023H ; COM I/O串口中断
CLR ES
RETI
NOP
NOP
ORG 002BH ;TIME2 OUT 降压检测中断
CLR IEN0.5
RETI
NOP
NOP
ORG 0033H ;I2C中断
CLR IEN1.0
RETI
NOP
NOP
ORG 003BH ;键盘中断
CLR IEN1.1
AJMP KEYINT
NOP
NOP
ORG 0043H ;比较器2中断
CLR IEN1.2
RETI
NOP
NOP
ORG 0053H ; WDT TIMER OUT
CLR IEN0.6
RETI
NOP
NOP
ORG 0063H ;比较器1中断
CLR IEN1.5
RETI
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ORG 050H
SYS_START:
;MOV PT0AD,#00H ;P0作为I/O,不使用比较器
MOV P0M1,#00H ; P0 准双向口
MOV P0M2,#041H ;P0.0驱动LED,P0.6时93C46的CS,所以选择上拉。
MOV P1M1,#01H ;P1.0是93C46的DI,选择仅为输入
MOV P1M2,#02H ;P1.1是93C46的DO,选择上拉
ORL AUXR1,#50H ;禁止掉电检测,并关掉EPROM部分模拟电路
CLR EWD ;关掉看门狗
SETB EA
MOV KBI,#01EH ;4个按键中断
SETB EKB ;最后是使能键盘中断
CLR SEND_FINISH
MAIN:
JB SEND_FINISH,MAIN ;循环等待所有的完成,然后进入休眠状态
;ORL HPCON,#02H ;PD=1,进入低功耗模式
AJMP MAIN
;*****************************************************************
;键盘中断处理程序
;*****************************************************************
KEYINT:
PUSH PSW
NOP ;奇怪的是:没有这两个NOP,AUXR1和7FH与的值不变
NOP
ANL AUXR1,#07FH ;CLEAR KBF
CLR EKB ;禁止键盘中断
JB P0.1,KY2
ACALL DELAY10MS
JB P0.1,NOKEY
AJMP KEY1_IN
KY2:
JB P0.2,KY3
ACALL DELAY10MS
JB P0.2,NOKEY
AJMP KEY2_IN
KY3:
JB P0.3,KY4
ACALL DELAY10MS
JB P0.3,NOKEY
AJMP KEY3_IN
KY4:
JB P0.4,NOKEY
ACALL DELAY10MS
JB P0.4,NOKEY
AJMP KEY4_IN
NOKEY:
SETB EKB
CLR SEND_FINISH
ANL AUXR1,#07FH ;CLEAR KBF中断开始清0了一次,此处仍要清0,奇怪!
POP PSW
RETI
KEY1_IN:
NOP
MOV KEY_VALUE,#00H ;用2个BYTE来表示4个按键
AJMP KEY_FINISH
KEY2_IN:
NOP
MOV KEY_VALUE,#01H
AJMP KEY_FINISH
KEY3_IN:
MOV KEY_VALUE,#02H
AJMP KEY_FINISH
KEY4_IN:
MOV KEY_VALUE,#03H
KEY_FINISH: ;问题在于唤醒省电模式之前的指令是如何运行的?
SETB LED ;灯亮
ANL HPCON,#0FDH ;PD=0唤醒省电模式
CLR EKB ;UNABLE THE KEY INTERUPTER
;*******************************************************************
;93C46里首先是2BYTE的地址,A1-A10,后的6BIT用0补。
;第3个BYTE是自身地址前8BIT,第4个BYTE的高位是自身地址后4位,低位是KEY-VALUE
;********************************************************************
MOV ADD_93C_L,#00H ;首先读10BIT(2BYTE)的ADDRESS
ACALL READ_93C46
MOV R0,#SEND_BUFFER1
MOV A,BYTE1_93C ;从93C46里读出来的数据放在SEND——BUFFER1里
MOV @R0,A
INC R0
MOV A,BYTE2_93C
MOV @R0,A
MOV ADD_93C_L,#02H ;再读12BIT的自身地址(2BYTE)
ACALL READ_93C46
MOV A,BYTE1_93C
MOV DATA1,A
MOV A,BYTE2_93C
MOV DATA2,A
MOV A,DATA1
CLR C ;第1个BIT为0,说明是第1个数据
RRC A
MOV DATA1,A
MOV A,DATA2
RRC A
SETB C ;第1个BIT为1,说明是第2个数据
RRC A
ANL A,#0FCH ;1111 1100
ORL A,KEY_VALUE ;;最后把按键值放在最后一位.共4BYTE
MOV DATA2,A
;此处改动是为了调试,把地址全部为0,自身的地址任意设
MOV R0,#SEND_BUFFER1
MOV @R0,#00H
INC R0
MOV @R0,#00H
MOV DATA1,#00H
MOV DATA2,#0H
;***********开始发送address$data**************************
SENDING:
MOV TIMERS,#00AH ;一共10次
SENDING_1:
;**********开始发送空白和S********************************
CLR DATAOUT
ACALL DELAY10MS
SETB DATAOUT
ACALL DELAY80US
ACALL DELAY80US
ACALL DELAY80US
;ACALL DELAY80US
CLR DATAOUT
ACALL DELAY80US
;***********************************************************
MOV TIME_ADD,#00AH ;地址是10BTI
MOV TIME_CD_NUM,#08H ;自身地址是8位,两次都是。
MOV R0,#SEND_BUFFER1 ;前2个BYTE是地址
INC R0 ;@R0是第1个地址(前8BIT)
MOV A,R1 ;@R1是第2个地址(后2BIT)
MOV R1,A ;注意:只有R0、R1才可以使用@Rn,其他的几个不行
SEND_ADD_NEXT:
CLR C ;左移,从最高位开始发送
MOV A,@R1
RLC A
MOV @R1,A
MOV A,@R0
RLC A
MOV @R0,A
JC SEND_ADD1 ;最高位
SEND_ADD0:
ACALL SEND0
AJMP SEND_AD_NEXT1
SEND_ADD1:
ACALL SEND1
AJMP SEND_AD_NEXT1
SEND_AD_NEXT1:
DJNZ TIME_ADD,SEND_ADD_NEXT
AJMP SEND_CODE
SEND_CODE: ;地址发送完,发送自身地址
MOV R0,#DATA1 ;从第3个地址开始是自身地址
SEND_NEXT:
MOV A,@R0
RLC A ;从最高位开始发送
MOV @R0,A
JC SEND_CD1
SEND_CD0:
ACALL SEND0
AJMP SEND_CD_NEXT
SEND_CD1:
ACALL SEND1
AJMP SEND_CD_NEXT
SEND_CD_NEXT:
DJNZ TIME_CD_NUM,SEND_NEXT ;第几个BIT
;一共连续发送10次
DJNZ TIMERS,SENDING_1
;************;第2次发送****************
MOV TIMERS,#00AH ;一共10次
SENDING_2:
;**********开始发送空白和S********************************
CLR DATAOUT
ACALL DELAY10MS
SETB DATAOUT
ACALL DELAY80US
ACALL DELAY80US
ACALL DELAY80US
;ACALL DELAY80US
CLR DATAOUT
ACALL DELAY80US
;***********************************************************
MOV TIME_ADD,#00AH ;地址是10BTI
MOV TIME_CD_NUM,#08H ;自身地址是8位,两次都是。
MOV R0,#SEND_BUFFER1
INC R0
MOV A,R0
MOV R1,A
SD2_ADD_NEXT:
CLR C
MOV A,@R1
RLC A
MOV @R1,A
MOV A,@R0
RLC A
MOV @R0,A
JC SD2_ADD1
SD2_ADD0:
ACALL SEND0
AJMP SD2_AD_NEXT2
SD2_ADD1:
ACALL SEND1
AJMP SD2_AD_NEXT2
SD2_AD_NEXT2:
DJNZ TIME_ADD,SD2_ADD_NEXT
AJMP SD2_CODE
SD2_CODE: ;地址发送完,发送自身地址
MOV R0,#DATA2 ;第4BYTE是第2个数据:地址和KEY-VALUE
SD2_NEXT:
MOV A,@R0
RLC A
MOV @R0,A
JC SD2_CD1
SD2_CD0:
ACALL SEND0
AJMP SD2_CD_NEXT
SD2_CD1:
ACALL SEND1
AJMP SD2_CD_NEXT
SD2_CD_NEXT:
DJNZ TIME_CD_NUM,SD2_NEXT
;一共连续发送10次
DJNZ TIMERS,SENDING_2
ajmp sending
SETB SEND_FINISH ;发送完成,置位,使进入休眠状态
SETB EKB ;重新开启键盘中断
ANL AUXR1,#07FH ;CLEAR KBF
POP PSW
RETI
;*****************子程序*******************************************
SEND0:
MOV R3,#024H ;0010 01+00
MOV TIME_REP,#06H
SEND0_LOOP:
MOV A,R3
RLC A
MOV R3,A
MOV DATAOUT,C
ACALL DELAY80US
DJNZ TIME_REP,SEND0_LOOP
RET
SEND1:
MOV R3,#06CH ;0110 11+00
MOV TIME_REP,#06H
SEND1_LOOP:
MOV A,R3
RLC A
MOV R3,A
MOV DATAOUT,C
ACALL DELAY80US
DJNZ TIME_REP,SEND1_LOOP
RET
;**************************************************************************
;
; 93C46 Read Program 16 BIT MODE
;
; Input : ADD_93C_H Address High 1 Bit
; ADD_93C_L Address Low 8 Bit
;
; Output : BYTE1_93C First BYTE 8 Bit
; BYTE2_93C Secend BYTE 8 Bit
;
; AFFECTED : R1 - R5 , PSW , ACC
;**************************************************************************
READ_93C46:
RET ;实验!
NOP
NOP
ACALL CS1_93C ; CS 1
NOP
NOP
MOV R5,#03H
MOV A,ADD_93C_L
ANL A,#07EH
MOV R4,A
MOV R2,#0CH ; COMMAND 11 BIT
NOP
NOP
READ_ADDR46:
CLR SK_93C ; SK LOW
MOV ACC,R5
MOV C,ACC.3
MOV DI_93C,C
NOP
SETB SK_93C ; SK HIGH
MOV A,R4
RLC A
MOV R4,A
MOV A,R5
RLC A
MOV R5,A
NOP
NOP
DJNZ R2,READ_ADDR46
NOP
NOP
MOV R2,#10H ; READ 16 BIT
NOP
NOP
READ_16BIT46:
SETB SK_93C ; SK HIGH
NOP
NOP
NOP
NOP
MOV R3,#05H
NOP
NOP
CLR SK_93C ; SK LOW
NOP
READ_16BIT_1:
MOV C,DO_93C
RLC A
MOV C,DO_93C
MOV F0,C
RLC A
ANL A,#03H
NOP
NOP
JZ READ_1BIT_OK
XRL A,#03H
JZ READ_1BIT_OK
NOP
NOP
DJNZ R3,READ_16BIT_1
NOP
NOP
READ_1BIT_OK:
MOV C,F0
MOV A,BYTE2_93C
RLC A
MOV BYTE2_93C,A
MOV A,BYTE1_93C
RLC A
MOV BYTE1_93C,A
NOP
NOP
DJNZ R2,READ_16BIT46
NOP
NOP
CLR CS_93C ; CS 0
CLR SK_93C
CLR DI_93C
SETB DO_93C
NOP
NOP
RET
NOP
NOP
CS1_93C:
NOP
SETB CS_93C ; CS 1
SETB DO_93C
MOV R3,#0
MOV R2,#0
NOP
TEST_93C:
NOP
JB DO_93C,TEST_93C_END
DJNZ R2,TEST_93C
DJNZ R3,TEST_93C
AJMP TEST_93C_ERROR
TEST_93C_END:
NOP
NOP
TEST_93C_ERROR:
RET
NOP
NOP
;*******************************************************************
; DELAY 100MS
;*******************************************************************
DELAY100MS: MOV R6,#96H
MOV R7,#0C3H
DELAY_100MS:
DJNZ R6,DELAY_100MS
DJNZ R7,DELAY_100MS
RET
NOP
NOP
;*********************************************************
DELAY10MS:
MOV R7,#075H
DELAY_10MS:
ACALL DELAY80US
DJNZ R7,DELAY_10MS
RET
;*******************************************************************
; DELAY 80US ;仿真器设置EMULATOR(6M)
;******************************************************************
DELAY80US: MOV R6,#026H
DELAY_80: DJNZ R6,DELAY_80
RET
; ORG 07FBH
; NOP ; SYSTEM_ERROR
; NOP
; NOP
; AJMP SYS_START
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -