📄 shepin.asm
字号:
;MCU:89S51 COLCK:11.0592MHZ
;;;作者 :马良
;;;实验目的: 1. 通过实验了解非接触IC卡的工作原理和用软件读取信号的编程方法
;;;P1.5接OUT端;P1.4接CFE端。
TLL EQU 20H
TLH EQU 44H
THL EQU 62H
THH EQU 091H
TDL EQU 88H
TDL1 EQU 2DH
BLK1 EQU 70H ;接收数据缓冲区首地址
RFIDOK BIT 79H ;RFIDOK(读卡成功标志位)为调试/测试位,RFIDOK为0时表示没读到卡
RFIDOK1 BIT 7AH ;读头码成功标志位
OUT BIT P1.5 ;信号输入
RS EQU P1.2 ;LCD-RS ;注意这4个条线要连接!
RW EQU P1.1 ;LCD-RW
E EQU P1.0 ;LCD-E
LS BIT P1.3 ;蜂鸣器
ORG 0000H
LJMP RDDD
ORG 0050H
;;-------------------------
;;;;;;READ RF CARD
;---------------------------
RDDD: MOV P1,#0FFH
MOV P3,#0ffH
MOV 70H,#00H
MOV 71H,#00H
MOV 72H,#00H
MOV 73H,#00H
MOV 74H,#00H
MOV 75H,#00H
MOV 76H,#00H
MOV 77H,#00H
MOV 78H,#00H
MOV 79H,#00H
MOV 7AH,#00H
MOV P2,#01H ;清除屏幕
ACALL ENABLE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;增加串口功能;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RS232: ; 串行口发送到电脑显示 波特率为19200.
MOV TMOD,#20H;设定T1为定时方式2
MOV TH1,#0FDH;定时初值
MOV TL1,#0FDH;
MOV PCON,#80H;波特率为19200
SETB TR1;;;;;启动定时器
MOV SCON,#50H;串口方式1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;增加串口功能;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOV P2,#38H;8位点阵方式
ACALL ENABLE
MOV P2,#0FH;开显示
ACALL ENABLE
MOV P2,#06H;移动光标
ACALL ENABLE
MOV P2,#01H;清除屏幕
ACALL ENABLE
ACALL DELAYG
MOV P2,#80H;显示位置
ACALL ENABLE
mov r0,#011h
mov dptr,#table1;送数据表
call write1
MOV P1,#0FFH
MOV P3,#0ffH
MOV R4,#04H ;每次读卡都连续读4次
RDDD1: ACALL RFID ;读ID卡
JB RFIDOK,ZHCX0 ;读到卡转
DJNZ R4,RDDD1
AJMP RDDD ;没读到返回
;;;;;把卡号合并成4个字节数据还是存在33H,32H,31H,30H4个存储器中
;;;;;因为10位10进制的卡号是用8位16进制的数据转换而成的,所以就舍弃
;;;;;前两位,把后8位数据合成4个字节
ZHCX0: MOV R2,#4
MOV R1,#BLK1
MOV R0,#33h
inc r1
inc r1
ZHCX: MOV A,@R1
MOV R3,A
INC R1
MOV A,@R1
SWAP A
ADD A,R3
MOV @R0,A
dec R0
INC R1
DJNZ R2,ZHCX
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;
;4字节十六进制整数转换成10个字节BCD码整数
;待转换的4字节十六进制整数在33H,32H,31H,30H中,高位33H低位在30H如F83A2E34H,
;高位33H中是F8H,低位30H是34H
; 转换后的十字节BCD码整数在R3,R4,R5,R6,R7中,如F83A2E34H,
;转换后的十字节BCD码整数 :4164562484,R3=41,R4=64。。。。。。R7=84
;再把数据存入60H开始的10个地址中60H:04,61H:01........68H:08,69H:04
CLR A ;BCD码初始化
MOV R3,A
MOV R4,A
MOV R5,A
MOV R6,A
MOV R7,A
MOV R2,#32 ;转换双字节十六进制整数
HB3: MOV A,30H;从高端移出待转换数的一位到CY中
RLC A
MOV 30H,A
MOV A,31H
RLC A
MOV 31H,A
MOV A,32H
RLC A
MOV 32H,A
MOV A,33H
RLC A
MOV 33H,A
MOV A,R7 ;BCD码带进位自身相加,相当于乘2
ADDC A,R7
DA A ;十进制调整
MOV R7,A
MOV A,R6 ;BCD码带进位自身相加,相当于乘2
ADDC A,R6
DA A ;十进制调整
MOV R6,A
MOV A,R5 ;BCD码带进位自身相加,相当于乘2
ADDC A,R5
DA A ;十进制调整
MOV R5,A
MOV A,R4
ADDC A,R4
DA A
MOV R4,A
MOV A,R3
ADDC A,R3
DA A
MOV R3,A
DJNZ R2,HB3;处理完16bit
;;;;;;;;;;;;;;;;;;;;;;;
mov a,r3 ;;
mov r1,a
swap a
anl a,#0fh
mov 60h,a
mov a,r1
anl a,#0fh
mov 61h,a
;-----------
mov a,r4
mov r1,a
swap a
anl a,#0fh
mov 62h,a
mov a,r1
anl a,#0fh
mov 63h,a
;--------------
mov a,r5
mov r1,a
swap a
anl a,#0fh
mov 64h,a
mov a,r1
anl a,#0fh
mov 65h,a
;-----
mov a,r6
mov r1,a
swap a
anl a,#0fh
mov 66h,a
mov a,r1
anl a,#0fh
mov 67h,a
;-----------------
mov a,r7
mov r1,a
swap a
anl a,#0fh
mov 68h,a
mov a,r1
anl a,#0fh
mov 69h,a
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;LCD依次显示卡号,卡号为0-F的16进制的数据和10进制的数据
;;;;在第一行显示: HEX:X X X X X X X X X X ;16进制的数据
;;;;在第二行显示: BCD:X X X X X X X X X X ;10进制的数据
WW0:
MOV P2,#38H;8位点阵方式
ACALL ENABLE
;
MOV P2,#0FH;开显示
ACALL ENABLE
MOV P2,#06H;移动光标
ACALL ENABLE
MOV P2,#01H;清除屏幕
ACALL ENABLE
ACALL DELAYG ;清屏后延时一段时间
ACALL DELAYG
ACALL DELAYG
MOV p2,#80H;第一行的位置显示: HEX:X X X X X X X X X X ;16进制的数据
ACALL ENABLE
mov r0,#04h
mov dptr,#table3;送数据表
call write1
;
mov dptr,#table2
call write3
mov p2,#0c0h;第二行的位置显示: BCD:X X X X X X X X X X ;10进制的数据
call enable
;;;;;
mov r0,#04h
mov dptr,#table4;送数据表
call write1
;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;增加串口功能;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOV R1,#60H;;数据地址指针
MOV R0,#0AH;;;数据长度
AAA0: MOV A,@R1
MOV SBUF,A;发送一个数据
INC R1;;;;;;;;数据地址指针加1
AAA1: JBC TI,AAA2;;;
SJMP AAA1;;;;
AAA2: DJNZ R0,AAA0;;数据发送完了吗?
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;增加串口功能;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov dptr,#table2
call write4
mov p2,#090h;
call enable
CLR LS ;提示音
MOV R5,#01
ACALL W0
SETB LS ;关闭提示音
ACALL WW
ACALL WW
lJMP RDDD
ENABLE:
CLR RS
CLR RW
CLR E
ACALL DELAY
SETB E
RET
write1: ;写数据
mov r1,#00h
a1:mov a,r1
movc a,@a+dptr
call write2
inc r1
djnz r0,a1
ret
write2:
mov p2,a
setb rs
clr rw
clr e
call delay
setb e
ret
write3: ;写数据
mov r1,#blk1
mov r0,#0ah
a2:mov a,@r1
swap a
movc a,@a+dptr
call write2
inc r1
djnz r0,a2
ret
;;;-------------
write4: ;写数据
mov r1,#60h
mov r0,#0ah
a3:mov a,@r1
movc a,@a+dptr
call write2
inc r1
djnz r0,a3
ret
delay:
mov r7,#01
d1:mov r6,#255
d2:djnz r6,d2
djnz r7,d1
ret
WW : MOV R5,#04H
W0: MOV R6,#080H
W1: ACALL DELAYG
DJNZ R6, W1
DJNZ R5, W0
RET
DELAYG: MOV R7,#080H
LOOPG: NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R7,LOOPG
RET
table1: db 20h,20h,20h,4eh,4fh,20h,43h,41h,52h,44h,20h,20h,20h,20h,20h,20h,20h,20h,20H,20H
;数据空格空格空格NO空格CARD
table3: db 48h,45h,58h,3ah,20h,20h,20h,20h,20h,20h,20h,20h,20h,20h,20h,20h
;数据HEX:
table2: db 30H,31H,32H,33H,34H,35H,36H,37H,38H,39H,41H,42H,43H,44H,45H,46H
;数据0123456789ABCDEF空格
table4: db 42h,43h,44h,3ah
;;;;;读ID卡子程序 (RFID.ASM)
;读ID卡软件包的底层子程序
;;;;MCU:89C2051 Clock:11.0592MHZ
;;;如 Clock为22.1184请去掉带";"程序前的";"即可
;;;入口参数:无
;;出口参数: 接收数据缓冲区BLK1(10个字节,每个字节的高4位有效,低4位为0),读卡成功标志位RFIDOK
;占用:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;-----------------------
RFID:
;----------------------------
MOV 70H,#00H ;数据缓冲区清0
MOV 71H,#00H
MOV 72H,#00H
MOV 73H,#00H
MOV 74H,#00H
MOV 75H,#00H
MOV 76H,#00H
MOV 77H,#00H
MOV 78H,#00H
MOV 79H,#00H
MOV 7AH,#00H
mov 7bh,#100 ;重复读100次(允许出错100次)
RDD: CLR RFIDOK1
LCALL EDGEMu ;读头码11111111
JB RFIDOK1,RDOK ;如读到头码转读取卡号
RDD0:
DJNZ 7BH,RDD ;未完待续
CLR RFIDOK ;失败返回,RFIDOK=0
RET
;;读取卡号
;;以下接收11个数据,每个字节5位
RDOK: CLR RFIDOK ;读卡成功标志位先清0
RDD1: MOV R0,#BLK1 ;数据存储地址
RDDL0: MOV R6,#0BH; ;接收11个数据
RBL: CLR A
MOv @R0,A
RDDL1: MOV R5,#05H ;每个字节5位
RDDL2: JB OUT, RDDL5 ;读数据
MOV A,#00H
RDDL3: CJNE A,#TDL1,RDDL4 ;时间比较
LJMP RDD0 ;超时返回
RDDL4: JB OUT ,RDDLK ;输入有跳变转?
INC A ;计时加一
NOP
;;;;;;*****一下几个NOP的用处是延长时间,因为原来是11.0592MHZ
;;;;;;现改为22.1184MHz
;NOP
;NOP
; NOP
; NOP
; NOP
; NOP
;NOP
;NOP
;;;;;;**************************
SJMP RDDL3
RDDL5: MOV A,#00H ;高电平计时清0
RDDL51: CJNE A,#TDL1,RDDL6 ;是否超时?
LJMP RDD0 ;超时返回
RDDL6: JNB OUT, RDDLK ;输入有跳变转?
INC A ;计时加一
NOP
;;;;**********用处是延长时间,因为原来是11.0592MHZ
;;;;;;现改为22.1184MHz
; NOP
; NOP
; NOP
; NOP
; NOP
; NOP
;NOP
;NOP
;;;;***************************
SJMP RDDL51
RDDLK: MOV C,OUT
CPL C
MOV A,@R0
RLC A
MOV @R0,A ;保存数据
MOV R1,#TDL; 延时
NOP
DJNZ R1,$
;;;;;;;****用处是延长时间,因为原来是11.0592MHZ
;;;;;;现改为22.1184MHz
; MOV R1,#TDL;YSTNEXT
; NOP
; DJNZ R1,$
;;;;;;;**************************
DJNZ R5,RDDL2
INC R0
DJNZ R6,RBL ;未完待续
;;数据校验
;;;;; ----------------------------
;;;;;;10 行偶校验
DC: MOV R6,#0AH
D2C: MOV R0,#70H
D2C1:MOV A,@R0
RRC A
ANL A,#0FH
MOV 20H,C
ANL C,/PSW.0
MOV 21H,C
MOV C,20H
CPL C
ANL C,PSW.0
ORL C,21H
JC D2C2
MOV @R0,A
INC R0
DJNZ R6,D2C1
AJMP D2D0 ;行偶校验正确转列奇校验
D2C2: CLR RFIDOK1;;;;;校验出错
AJMP RDD0 ;行偶校验出错反回
;;;;;;4列奇校验
D2D0: MOV R7,#04H ;
MOV A,7AH
RR A
MOV 7AH,A
ANL 7AH,#0FH
D2D:MOV R6,#0AH
CLR C
MOV R0,#70H
D2D2: MOV A,@R0
RL A
JNB ACC.4,D2D1
CPL C
D2D1:MOV @R0,A
INC R0
DJNZ R6,D2D2
MOV A,7AH
RL A
MOV 7AH,A
JB ACC.4,D2D3
JC D2D4
D2D5: DJNZ R7,D2D
AJMP XXXX
D2D3: JC D2D5
D2D4: AJMP RDD3
XXXX: MOV B,#0FH
AJMP XX1
RDD3: CLR RFIDOK1
AJMP RDD0
XX1: SETB RFIDOK ; 读卡成功标志位置1
RET
;;;读头码既读8个1
EDGEMu : MOV R7,#0ffh ;读头码允许最大出错255次
EDGE0: MOV R1,#08H ;读8个1
NOP
DJNZ R7,EDGE3
EDGER:CLR RFIDOK1 ;未读到头码,标志位清0
RET
;------------------
;- --- --- --- --- --- --- --- --- ---
;--- --- --- --- --- --- --- --- ---
;-----------------
EDGE3:mov A,#00H ;读低电平
EDGER0: INC A
JZ EDGER ;超时出错,不是头码返回
JNB OUT,EDGER0
MOV A,#0000H
EDGE4: INC A ;读高电平
;;;;;*****用处是延长时间,因为原来是11.0592MHZ
;;;;;;现改为22.1184MHz
; nop
;nop
; nop
; nop
; nop
JZ EDGER ;超时出错,不是头码返回
JB OUT, EDGE4
MOV B,A ;
CLR C
SUBB A,#TLH ;如长于半周期的上限
JNC EDGE0 ;说明不是头码重新开始
MOV A,B
CLR C
SUBB A,#TLL ;如短于半周期的下限
JC EDGER ;说明不是头码返回
MOV A, B
CLR C
SUBB A,#TLH
JNC EDGE0
DJNZ R1,EDGE3 ;未读完8个1继续
MOV R1,#TDL
DJNZ R1,$
;;;;;;******用处是延长时间,因为原来是11.0592MHZ
;;;;;;现改为22.1184MHz
; MOV R1,#TDL
; DJNZ R1,$
;;;;;;********************
SETB RFIDOK1 ;已读到头码,标志位置1
RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -