📄 pt2272.asm
字号:
DJNZ R5, GETC_3P ;循环接收8个数据位,进行16次采样
SETB SIGING
CLR C
RET
GETC_E: CLR SIGING
GETC_F: SETB C
RET
; =========================================================================================
; =========================================================================================
FIND: MOV A, RBUF44 ;分析代码
CJNE A, #MYA0_3, FIND_E
MOV R4, RBUF81
MOV R5, RBUF82
MOV R6, #7
MOV R0, #00H
MOV R1, #00H
FIND_L: MOV A, R0 ;结果乘以 3
CLR C
RLC A
MOV B, A
MOV A, R1
RLC A
XCH A, B
ADD A, R0
MOV R0, A
MOV A, B
ADDC A, R1
MOV R1, A ;结果乘以 3 结束
MOV A, R4
RLC A
MOV R4, A ;D7-->C
MOV A, R5
RL A
MOV R5, A
ANL A, #01H ;D7-->A.0
ADDC A, R0 ;A.0+C+R0
MOV R0, A
MOV A, R1
ADDC A, #00H
MOV R1, A
DJNZ R6, FIND_L ;确定A4-A10的编码结果
CLR A
MOV C, RBUF81.0 ;分析代码,确定是否主控手机
MOV ACC.0, C
MOV C, RBUF82.0
ADDC A, #00H ;A=(0,1,2)。A=0:非主控手机;A=1:主控手机;A=2:无效手机
JB ACC.1, FIND_E ;A=2!
MOV CODEL, R0
MOV CODEH, R1
CLR C
RET ;A=0/1
FIND_E: SETB C
RET
; =========================================================================================
; =========================================================================================
EECHK: MOV EEPTRL, #00H ;0000H记录不用,因为0000H用于判断EEPROM是否空
MOV EEPTRH, #00H
MOV EEBUF, #00H
MOV EEBUF+1, #00H
EECHK0: MOV CODEL, EEBUF ;放到编码缓冲区
MOV CODEH, EEBUF+1
ANL CODEH, #0FH
MOV DPL, EEPTRL ;读取栈底的两个字节
MOV DPH, EEPTRH
INC DPTR
INC DPTR ;指向下一个记录,但是暂时不修改指针
MOV A, DPH
ADD A, #HIGH(65536-EESIZE) ;???
JC EECHK9 ;已经检查完所有记录空间。
MOV EEPOL, DPL
MOV EEPOH, DPH ;暂时保存在这里
MOV R0, #EEBUF
MOV B, #02H
ACALL I2CD_R
MOV A, EEBUF+1
ANL A, #0F0H
XRL A, #PWDF
JNZ EECHK9
MOV EEPTRL, EEPOL
MOV EEPTRH, EEPOH
AJMP EECHK0
EECHK9: CLR EEEMPTY ;假设非空
MOV A, EEPTRL
ORL A, EEPTRH
JNZ EECHKE
SETB EEEMPTY ;声明EEPROM空
EECHKE: RET
; =========================================================================================
; =========================================================================================
EEPUSH: MOV EEBUF, CODEL ;写入EEPROM栈,采用实栈顶
MOV EEBUF+1, CODEH
ORL EEBUF+1, #PWDF ;标志,50H
MOV DPL, EEPTRL
MOV DPH, EEPTRH
INC DPTR ;每个记录进入,指针加 2
INC DPTR
MOV A, DPH ;进行堆栈溢出检查
ADD A, #HIGH(65536-EESIZE)
JC EEPUSHE
ANL DPL, #0FEH
MOV EEPTRL, DPL
MOV EEPTRH, DPH
MOV R0, #EEBUF
MOV B, #02H
ACALL I2CD_W
CLR EEEMPTY ;声明EEPROM非空
EEPUSHE:RET
; =========================================================================================
; =========================================================================================
EEPOP: MOV A, EEPTRL ;EEPROM退出操作
ORL A, EEPTRH
JZ EEPOPB
EEPOP0: MOV EEPOL, EEPTRL
MOV EEPOH, EEPTRH
CLR C ;指针减 2,指向上一个数据
MOV A, EEPTRL
SUBB A, #02H
MOV EEPTRL, A
MOV A, EEPTRH
SUBB A, #00H
MOV EEPTRH, A ;指针已经更新
MOV A, EEPTRL ;检查退出一个记录后,堆栈是否变空?
ORL A, EEPTRH
JNZ EEPOP1
MOV CODEL, A
MOV CODEH, A
SETB EEEMPTY ;声明EEPROM空
AJMP EEPOP9
EEPOP1: MOV DPL, EEPTRL ;读取栈顶记录
MOV DPH, EEPTRH
MOV R0, #EEBUF
MOV B, #02H
ACALL I2CD_R
MOV CODEL, EEBUF ;放到编码缓冲区
MOV CODEH, EEBUF+1
ANL CODEH, #0FH ;屏蔽掉标志
EEPOP9: MOV EEBUF, #00H ;清除刚才已经退栈的记录
MOV EEBUF+1, #00H
MOV DPL, EEPOL
MOV DPH, EEPOH
MOV R0, #EEBUF
MOV B, #02H
ACALL I2CD_W
ACALL TOBUF ;送到显示缓冲区
ACALL LEDOFF
EEPOPB: MOV A, #2-1
ACALL BELL_S ;鸣响
; MOV BELLTM, #30
EEPOPE: RET
; =========================================================================================
; =========================================================================================
TOBUF: MOV A, CODEL ;填写显示缓冲区
MOV B, CODEH ;/100
MOV R2, #00H
TOBUF_0:CLR C
SUBB A, #100
XCH A, B
SUBB A, #00H
XCH A, B
JC TOBUF_8
INC R2
AJMP TOBUF_0
TOBUF_8:ADD A, #100
MOV B, #10
DIV AB
MOV DPTR, #FONT
MOVC A, @A+DPTR
MOV DBUF1, A
MOV A, B
MOVC A, @A+DPTR
MOV DBUF0, A
MOV A, R2
MOVC A, @A+DPTR
MOV DBUF2, A
MOV CODELK, CODEL
MOV CODEHK, CODEH
RET
; =========================================================================================
; =========================================================================================
DELAY: PUSH ACC ;延迟时间=A*10ms
MOV A, #20
DLY1: PUSH ACC
MOV A, #250
DJNZ ACC, $ ;500us
POP ACC
DJNZ ACC, DLY1
POP ACC
DJNZ ACC, DELAY
RET
;======= I2C 子程序 =================================================================
; I2CD_W, I2CD_R ;LAYER 1
; I2C_O, I2C_I ;LAYER 2
; I2C_BG, I2C_ED ;LAYER 3
;========================================================================================
; 向存储器写入几个字节,最多8个字节。
; 入口:DPTR 要写的EEPROM存储单元地址。
; R0 指向要写入字节在RAM的首地址。
; B 写入字节个数。
; 出口:如果 C=1,说明写出错。
I2CD_W: ACALL I2C_BG
MOV A, #10100000B ;写命令
ACALL I2C_O
JC I2CD_WE ;C=1, 未收到 ACK 位,出错,不再继续处理,直接返回
MOV A, DPH
ACALL I2C_O
JC I2CD_WE
MOV A, DPL
ACALL I2C_O
JC I2CD_WE
I2CD_WL:MOV A, @R0
ACALL I2C_O
JC I2CD_WE
INC R0
DJNZ B, I2CD_WL
ACALL I2C_ED
CLR C
RET
I2CD_WE:ACALL I2C_ED
SETB C
RET
; =========================================================================================
; 从 EEPROM 读入几个字节
; 入口:DPTR 要读的存储单元地址。
; R0 指向要读缓冲区在RAM的首地址。
; B 读入字节个数。
; 出口:读到的内容在缓冲区中,如果 C=1,说明读出错。
I2CD_R: ACALL I2C_BG
MOV A, #10100000B ;先发送[写]命令
ACALL I2C_O
JC I2CD_RE ;C=1, 未收到 ACK 位,出错,不再继续处理,直接返回
MOV A, DPH ;发送地址低位
ACALL I2C_O
JC I2CD_RE
MOV A, DPL ;发送地址低位
ACALL I2C_O
JC I2CD_RE
ACALL I2C_BG
MOV A, #10100001B ;发送读命令
ACALL I2C_O
JC I2CD_RE
I2CD_IB:MOV DPL, #08H ;取得一个字节
SETB SDA
I2CD_IL:SETB SCL ;SCL=1
NOP
MOV C, SDA ;MCU 采样 SDA,送到 C 中
RLC A ;C->ACC.0
CLR SCL ;SCL=0
DJNZ DPL, I2CD_IL ;得到的一个字节在 ACC 中
MOV @R0, A
INC R0
MOV A, B
XRL A, #01H
JZ I2CD_GO
CLR SDA
NOP
I2CD_GO:SETB SCL
NOP
CLR SCL
DJNZ B, I2CD_IB ;取得不止一个字节
ACALL I2C_ED
CLR C
RET
I2CD_RE:ACALL I2C_ED
SETB C
RET
; =========================================================================================
;向 IIC 总线发送一个字节
I2C_O: PUSH B
MOV B, #08H
I2C_OLP:RLC A ;ACC.7 -> C
MOV SDA, C
SETB SCL ;SCL=1
NOP
CLR SCL ;SCL=0
DJNZ B, I2C_OLP
SETB SDA ;准备接收 ACK 位
SETB SCL ;SCL=1, [SDA=1]
NOP
MOV C, SDA
CLR SCL
POP B
RET ;C=1, 未收到 ACK 位,出错, C=0, 收到 ACK 位,正常
; =========================================================================================
I2C_BG: SETB SCL ;确保SCL=HIGH
CLR SDA ;向 IIC 总线发送开始位
NOP
CLR SCL
RET
; =========================================================================================
I2C_ED: CLR SDA
SETB SCL
NOP
SETB SDA ;向 IIC 总线发送停止位
RET
; =========================================================================================
;最好显示000-999=1000个,否则容易造成误解,这里显示全部2187个,0-9,A-F,H,L,P,U,Y
; =========================================================================================
FONT: DB 0FDH ;"0"
DB 061H ;"1"
DB 0DBH ;"2"
DB 0F3H ;"3"
DB 067H ;"4"
DB 0B7H ;"5"
DB 0BFH ;"6"
DB 0E1H ;"7"
DB 0FFH ;"8"
DB 0F7H ;"9"
DB 0EFH ;"A"
DB 03FH ;"B"
DB 09DH ;"C"
DB 07BH ;"D"
DB 09FH ;"E"
DB 08FH ;"F"
DB 06FH ;"H"
DB 071H ;"J"
DB 01DH ;"L"
DB 0CFH ;"P"
DB 07DH ;"U"
DB 077H ;"Y"
; =========================================================================================
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -