📄 new51pro.a51
字号:
PUSH DPL
PUSH DPH
GC5_REP:VPP_05V ;VPP=5V
CLR IO_W_A ;Is ATMEL
LCALL Sing_C5x_ini
C5xx_CORP:
MOV P0,#0FFH
MOV DPTR,#0030H ;CORP.
READ_C5xx_DATA
CJNE A,#1EH,NO_ATC5
IS_ATC5:MOV DPTR,#MSG_ISAT
SJMP ANS_COR
NO_ATC5:MOV DPTR,#MSG_NOAT
ANS_COR:LCALL SEND_MSG
C5xx_SIZE:
MOV P0,#0FFH
MOV DPTR,#0031H ;SIZE
READ_C5xx_DATA
LCALL SEND_BYTE
C5xx_V_PP:
MOV DPTR,#MSG_VPP
LCALL SEND_MSG
MOV P0,#0FFH
MOV DPTR,#0032H ;VPP
READ_C5xx_DATA
CJNE A,#05H,IS_C12V
SJMP C5xx_Vp
IS_C12V:MOV A,#12H
C5xx_Vp:LCALL SEND_BYTE
LCALL Read_C5x_ini
GET_C5x_END:
POP DPH
POP DPL
RET
;;;;;;; TRAP ;;;;;;;;;;;;;
NOP
NOP
LJMP RESET
;====== AT89C5x 加密功能子程序 ===================
LOCK_C5xx:
MOV A,RX_PAR1 ;加密控制字
L5x_B0: JB ACC.0,LK_C5xx_B0
LJMP L5x_B1
LK_C5xx_B0:
VPP_05V
LCALL LK0_C5x_ini
SEL_VPP VPP
SET_C5x_PROG
L5x_B1: JB ACC.1,LK_C5xx_B1
LJMP L5x_B2
LK_C5xx_B1:
VPP_05V
LCALL LK1_C5x_ini
SEL_VPP VPP
SET_C5x_PROG
L5x_B2: JB ACC.2,LK_C5xx_B2
LJMP L5x_END
LK_C5xx_B2:
VPP_05V
LCALL LK2_C5x_ini
SEL_VPP VPP
SET_C5x_PROG
L5x_END:VPP_05V
LCALL Read_C5x_ini
RET
;;;;;;; TRAP ;;;;;;;;;;;;;
NOP
NOP
LJMP RESET
;====== AT89C5x 查空子程序 =====================
;一次性查完,退出由 EADD 控制
BANK_C5xx:
VPP_05V ;?
LCALL Read_C5x_ini
MOV DPH,SADD_H
MOV DPL,SADD_L
BC5_LOP:MOV P0,#0FFH ;开始读出循环
READ_C5xx_DATA
CPL A
BC5_CHK:JNZ BC5_END ;非空!
MOV CADD_H,DPH ;
MOV CADD_L,DPL ;
LCALL CHK_OVE
JC BC5_END ;结束
BC5_NXT:INC DPTR ;Address Increment
SJMP BC5_LOP
BC5_END:CPL C
RET ;C=0:全空;C=1:非空
;;;;;;; TRAP ;;;;;;;;;;;;;
NOP
NOP
LJMP RESET
;====== AT89C5x IO 初始化子程序 ===============
Read_C5x_ini:
CLR IO_W_A ;Is ATMEL
SETB AT_BSY ;set free
SETB AT_PRG ;
CLR AT_P26 ;\
SETB AT_P36 ;-Read or writ Enabled
SETB AT_P37 ;/
SETB AT_P27 ;Read line prep.
DEL_mS 50
RET
;;;;;;; TRAP ;;;;;;;;;;;;;
NOP
NOP
LJMP RESET
;-----------------------------------------------------
Prog_C5x_ini:
CLR IO_W_A ;Is ATMEL
SETB AT_BSY ;
CLR AT_P26 ;...
SETB AT_P27 ;in WRIT Mode!
SETB AT_P36 ;...
SETB AT_P37 ;...
SETB AT_PRG ;prep.
DEL_mS 50
RET
;;;;;;; TRAP ;;;;;;;;;;;;;
NOP
NOP
LJMP RESET
;-----------------------------------------------------
Eras_C5x_ini:
CLR IO_W_A ;Is ATMEL
SETB AT_BSY ;set free
SETB AT_PRG ;
SETB AT_P26
CLR AT_P27
CLR AT_P36
CLR AT_P37
DEL_mS 50
RET
;;;;;;; TRAP ;;;;;;;;;;;;;
NOP
NOP
LJMP RESET
;-----------------------------------------------------
Sing_C5x_ini:
SETB AT_BSY ;
SETB AT_PRG ;\
CLR AT_P26 ; \
CLR AT_P27 ;--READ SIGNATURE
CLR AT_P36 ; /
CLR AT_P37 ;/
RET
;;;;;;; TRAP ;;;;;;;;;;;;;
NOP
NOP
LJMP RESET
;-----------------------------------------------------
LK0_C5x_ini:
SETB AT_P26
SETB AT_P27
SETB AT_P36
SETB AT_P36
RET
;;;;;;; TRAP ;;;;;;;;;;;;;
NOP
NOP
LJMP RESET
;-----------------------------------------------------
LK1_C5x_ini:
SETB AT_P26
SETB AT_P27
CLR AT_P36
CLR AT_P36
RET
;;;;;;; TRAP ;;;;;;;;;;;;;
NOP
NOP
LJMP RESET
;-----------------------------------------------------
LK2_C5x_ini:
SETB AT_P26
CLR AT_P27
SETB AT_P36
CLR AT_P36
RET
;;;;;;; TRAP ;;;;;;;;;;;;;
NOP
NOP
LJMP RESET
;*********************************************
;****** 针对 W7xE5x 的功能子程序 ***************
;*********************************************
;====== W78E5x 读出子程序 =====================
;一次性读完,读出量有 RX_PAR2 控制
READ_E5xx:
JB IN_RED,RE5_INI
RE5_PRE:VPP_05V ;?
LCALL Read_E5x_ini
SETB IN_RED
;开始读出循环
RE5_INI:MOV DPH,SADD_H
MOV DPL,SADD_L
MOV R2,#10H
MOV R0,#TXD_BUF
RE5_LOP:MOV P0,#0FFH ;帧循环
READ_E5xx_DATA
MOV @R0,A ;Move Data
INC R0 ;Move Point
MOV CADD_H,DPH ;
MOV CADD_L,DPL ;
INC DPTR ;Address Increment
WAIT 10
DJNZ R2,RE5_LOP ;帧循环
RE5_END:RET
;;;;;;; TRAP ;;;;;;;;;;;;;
NOP
NOP
LJMP RESET
;====== W78E5X 烧写子程序 =================
PROG_E5X:
JB IN_PRG,PE5_INI
LCALL PE5_PRE
PE5_INI:MOV DPH,SADD_H
MOV DPL,SADD_L
MOV R0,#RXD_BUF
MOV R2,RX_LENG ;计数器
DEC_n R2,2
PE5_LOP:MOV P1,DPL ;Out L_Address
MOV P2,DPH ;Out H_Address
MOV A,@R0 ;Get Data
MOV P0,A ;Out Data
INC R0 ;Move Point
MOV CADD_H,DPH
MOV CADD_L,DPL
INC DPTR ;Address Increment!
SET_E5x_PROG
DJNZ R2,PE5_LOP ;
PE5_END:SETB IN_PRG
RET
;;;;;;; TRAP ;;;;;;;;;;;;;
NOP
NOP
LJMP RESET
;----------------------------------
PE5_PRE:VPP_05V
LCALL Prog_E5x_ini
SETB IN_PRG
SEL_VPP VPP
RET
;====== W7xE5x 擦除子程序 =======================
ERS_E5xx:
VPP_05V
LCALL Eras_E5x_ini
SEL_VPP VEP
CLR WB_P36 ;\
DEL_mS 15 ;-ALL ERASE
SETB WB_P36 ;/
VPP_05V
LCALL Read_E5x_ini
EW5_END:RET
;;;;;;; TRAP ;;;;;;;;;;;;;
NOP
NOP
LJMP RESET
;====== ===========================
GET_E5x:VPP_05V
MOV DPTR,#MSG_UNTYP
LCALL SEND_MSG
RET
;====== W78E5x 加密功能子程序 ========
LOCK_E5xx:
VPP_05V
LCALL Prog_E5x_ini
SEL_VPP VPP
LE5x_B: MOV A,RX_PAR1
ORL A,#0F0H
MOV P0,A
MOV P1,#0FFH
MOV P2,#0FFH
WAIT 100
SET_E5x_PROG
VPP_05V
LCALL Read_E5x_ini
RET
;;;;;;; TRAP ;;;;;;;;;;;;;
NOP
NOP
LJMP RESET
;====== W78E5x 查空子程序 =====================
;一次性查完,退出由 EADD 控制
BANK_E5xx:
VPP_05V ;?
LCALL Read_E5x_ini
MOV DPH,SADD_H
MOV DPL,SADD_L
BE5_LOP:MOV P0,#0FFH ;开始读出循环
READ_E5xx_DATA
CPL A
BE5_CHK:JNZ BE5_END ;非空!
MOV CADD_H,DPH ;
MOV CADD_L,DPL ;
LCALL CHK_OVE
JC BE5_END ;结束
BE5_NXT:INC DPTR ;Address Increment
SJMP BE5_LOP
BE5_END:CPL C
RET ;C=0:全空;C=1:非空
;;;;;;; TRAP ;;;;;;;;;;;;;
NOP
NOP
LJMP RESET
;====== W7xE5x IO 初始化子程序 ==================
Read_E5x_ini:
SETB IO_W_A ;Is WINBOND
CLR WB_P30 ;...
CLR WB_P31 ;READ!
CLR WB_P33 ;READ!
CLR WB_PRG ;==L!
CLR WB_P36 ;...
SETB WB_P37 ;Read line prep.
RET
;;;;;;; TRAP ;;;;;;;;;;;;;
NOP
NOP
LJMP RESET
;-----------------------------------------------
Prog_E5x_ini:
SETB IO_W_A ;Is WINBOND
CLR WB_P30
CLR WB_P31
CLR WB_P33
SETB WB_P36
SETB WB_P37
RET
;;;;;;; TRAP ;;;;;;;;;;;;;
NOP
NOP
LJMP RESET
;-----------------------------------------------
Eras_E5x_ini:
SETB IO_W_A ;Is WINBOND
SETB WB_P30
CLR WB_P31
CLR WB_P33
CLR WB_PRG
SETB WB_P36
SETB WB_P37
RET
;;;;;;; TRAP ;;;;;;;;;;;;;
NOP
NOP
LJMP RESET
;-----------------------------------------------
;====== 其他功能子程序 ===============
;------ 读写结束判断 -----------------
;IN: CADD,EADD
;OUT: C=0: no over; C=1: is over
CHK_OVE:PUSH ACC
CLR C
MOV A,CADD_L
SUBB A,EADD_L
MOV A,CADD_H
SUBB A,EADD_H
OVE_END:CPL C
POP ACC
RET
;;;;;;; TRAP ;;;;;;;;;;;;;
NOP
NOP
LJMP RESET
;============================================
;======= 发送一个字节的代码 ===================
SEND_BYTE:
CLR ES
PUSH ACC
MOV B,A
SWAP A
ANL A,#0FH
LCALL SEND_HEX
MOV A,B
ANL A,#0FH
LCALL SEND_HEX
POP ACC
SETB ES
SB_END: RET
;=======================================
SEND_HEX:
PUSH DPH
PUSH DPL
MOV DPTR,#ASC
MOVC A,@A+DPTR
MOV SBUF,A
JNB TI,$
CLR TI
POP DPL
POP DPH
SH_END: RET
ASC: DB "0123456789ABCDEF"
;====== 发送字符串子程序 ====================================
;IN: DPTR
;OUT: SBUF
;USE: ACC,DPTR
SEND_MSG:
CLR ES
CLR A
MOVC A,@A+DPTR
CJNE A,#'$',SEND_0
SJMP MSG_END
SEND_0: MOVE TB8,P
MOV SBUF,A
JNB TI,$ ;
CLR TI ;
INC DPTR
SJMP SEND_MSG
MSG_END:SETB ES
RET
;;;;;;;;;;;;;;;;;;
LJMP RESET
NOP
NOP
;****** 算法子程序 ********************************
;====== ASCII TO HEX =============================
ASC2HEX:CLR C
PUSH DPH
PUSH DPL
SUBB A,#30H
MOV DPTR,#ASC2
MOVC A,@A+DPTR
POP DPL
POP DPH
RET
ASC2: DB 0,1,2,3,4,5,6,7,8,9,0AH,0BH,0CH,0DH,0EH,0FH
DB 0,0AH,0BH,0CH,0DH,0EH,0FH
;====== 输出 AT89C5X 地址 ========================
AT_ADDR:PUSH ACC
PUSH PSW
AT_ADDL:MOV P1,DPL
AT_ADDM:MOV A,DPH
MOVE P2.0,ACC.0
MOVE P2.1,ACC.1
MOVE P2.2,ACC.2
MOVE P2.3,ACC.3
MOVE P2.4,ACC.4
MOVE P2.5,ACC.5
MOVE AT_A14,ACC.6
MOVE AT_A15,ACC.7
;Wait 4 Cyc already in AT_ADDR Sub
POP PSW
POP ACC ;2 Cyc=4Cyc OK!
RET ;2 Cyc/
;====== 针对AT89CX051的P1口翻转字节位次序 ===========
X051_DATA:
PUSH B
MOV B,A
MOV C,B.7
MOV ACC.0,C
MOV C,B.6
MOV ACC.1,C
MOV C,B.5
MOV ACC.2,C
MOV C,B.4
MOV ACC.3,C
MOV C,B.3
MOV ACC.4,C
MOV C,B.2
MOV ACC.5,C
MOV C,B.1
MOV ACC.6,C
MOV C,B.0
MOV ACC.7,C
POP B
RET
;====== 通用二循环延时子程序==================
;T=[X(X+7) + 4]*(12/Fosc)
DELAY2: PUSH DEL_X
DELm1: DJNZ DEL_X,DELm1
POP DEL_X
DJNZ DEL_X,DELAY2
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
NOP
NOP
LJMP RESET
NOP
NOP
;====== 通用三循环延时子程序==================
DELAY3: PUSH DEL_X
DEL31: PUSH DEL_X
DEL32: DJNZ DEL_X,DEL32
POP DEL_X
DJNZ DEL_X,DEL31
POP DEL_X
DJNZ DEL_X,DELAY3
RET
;*********************************************************
;****** 串行中断子程序:收命令、发数据 ***********************
;****** 以下代码速度优化( ) ***********************
;*********************************************************
S_INTR: PUSH PSW
PUSH ACC
MOV PSW,#AREA2 ;切换至二区
JBC RI,RX_STAR
JBC TI,TX_STAR
S_QUIT: POP ACC
POP PSW
RETI
;;;;;;; TRAP ;;;;;;;;;;;;;
NOP
NOP
LJMP RESET
;====== 发送程序 ==================================================
;发送计数: R3 : 00, 01, 02, 03, 04, 05, ..., 19, 20.
;发送中报文(分析) : CODE, 04H, PAR1, PAR2, SUM.
;发送长报文(读出) : CODE, LEN, PAR1, PAR2, D_0, D1, ..., D_F, SUM.
;发送缓冲区(地址) : 30H, 31H, 32H, 33H, 34H, 35H, ..., 43H, 2FH.
;-----------------------------------------------------------------
TX_STAR:MOV A,TX_LENG
ADD A,#02H
CJNE A,TX_CNT,TX_FRAM;
TX_SUM: MOV A,TX_SUMB
MOVE TB8,P
MOV SBUF,A
JNB TI,$
CLR TI ;发完
TX_OK: CLR IN_TXD ;清正在发送标记
SETB OK_TXD ;置发送结束标志
SETB SM2
SETB REN ;开放接受
MOV R1,#TXD_HAD ;
MOV R3,#00H ;
TX_END: SJMP TX_QUIT
;------------------------------------------
TX_FRAM:MOV A,@R1
INC R1 ;指针指向下一个位置
MOVE TB8,P
MOV SBUF,A
ADD A,TX_SUMB ;-计算累加和
MOV TX_SUMB,A ;/
TX_NEXT:INC R3
TX_QUIT:SJMP S_QUIT
;;;;;;; TRAP ;;;;;;;;;;;;;
NOP
NOP
LJMP RESET
;====== 接收程序 =================================================
;接收短报文(擦析) :CODE, 00H, SUM.
;接收中报文(密置) :CODE, 02H, PAR1, PAR2, SUM.
;接收中报文(空预) :CODE, 04H, SADH, SADL, EADH, EADL, SUM.
;接收长报文(写入) :CODE, LEN, SADH, SADL, D_0, D_1, ..., D7F, SUM.
;接收缓冲区(地址) : 7CH, 7DH, 7EH, 7FH, 80H, 81H, ..., FFH, 7BH.
;接收计数: R2 : 00, 01, 02, 03, 04, 05, ..., 131, 132.
;----------------------------------------------------------------
RX_STAR:MOV A,SBUF ;
MOV RX_BUFF,A ;
RX_ADR: JNB SM2,IS_DATA ;SM2=0 Is OTHER BYTE
;SM2=1 Is ADDRESS BYTE
IS_ADR: CJNE A,#MY_ADR,RX_END;No: Terminate
IS_ME: CLR SM2 ;
SETB IN_RXD ;Set in Receive Flag
MOV RX_SUMB,A ;Set RX_SUMB=ADDR
MOV R2,#00H ;CLEAR RX_CNT
MOV R0,#RXD_HAD ;SET RECEIVE POINT
MOV RX_LENG,#00H ;
SJMP RX_QUIT ;正式的接收从这里开始!
IS_DATA:MOV A,RX_LENG
ADD A,#02H
RX_SUM: CJNE A,RX_CNT,RX_DATA;
IS_SUM: MOV A,RX_BUFF
CJNE A,RX_SUMB,RX_END
RX_OK: CLR REN ;暂时关闭接收
CLR IN_RXD ;清正在接收标志位
SETB OK_RXD ;到处理命令时去清
SJMP RX_END ;命令处理留主程序!
;也可留给多余中断!
RX_DATA:MOV A,RX_BUFF ;正式接收报文
MOV @R0,A ;R1=1~4
INC R0
ADD A,RX_SUMB
MOV RX_SUMB,A
SJMP RX_NEXT
RX_END: SETB SM2 ;
SJMP RX_QUIT ;
RX_NEXT:INC R2 ;准备接收下一个字节
RX_QUIT:LJMP S_QUIT
;;;;;;; TRAP ;;;;;;;;;;;;;
NOP
NOP
LJMP RESET
;====== 初始化 FSR 子程序 ========================
INI_FSR:MOV TMOD,#21H ;
MOV PCON,#00H ;SET SMOD=0
MOV XICON,#00H ;
;MOV IP,#10H ;SET PS=1
MOV TH1,#0FDH ;SMOD=0:19200 bps
MOV TL1,#0FDH ;SMOD=1:38400 bps
COMM_MODE: ;for fosc=22.1184MHz
MOV SCON,#0F0H ;0100 0000B(9 Bit Mode)
RET
;;;;;;;;;;;;;;
NOP
NOP
LJMP RESET
;====== 提示信息 ==========================================================
MSG_HELLO: DB 0DH,0AH,09H,' 欢迎使用袖珍编程器。',0DH,0AH
DB 0DH,0AH,09H,'51PRO 1.0 copyright(C) 2001-2005'
DB 0DH,0AH,09H,'WuXi Gu Jianda. --2002.5.21',0DH,0AH,24H
MSG_STAT: DB 0DH,0AH,09H,'通讯正常,编程器就绪!请选择单片机类型。',0DH,0AH,24H
MSG_BANK: DB 0DH,0AH,09H,'已经全部擦空!',0DH,0AH,24H
MSG_UNBAK: DB 0DH,0AH,09H,'抱歉,尚未擦空!',0DH,0AH,24H
MSG_ERASE: DB 0DH,0AH,09H,'全片擦除操作结束!',0DH,0AH,24H
MSG_LOCK: DB 0DH,0AH,09H,'芯片加密操作结束!',0DH,0AH,24H
MSG_TYPE: DB 0DH,0AH,09H,'芯片类型、编程电压设置结束!',0DH,0AH,24H
MSG_ISAT: DB 0DH,0AH,09H,'这是 ATMEL 公司生产的 AT89C',24H
MSG_NOAT: DB 0DH,0AH,09H,'这是其它公司生产的 AT89C',24H
MSG_UNTYP: DB 0DH,0AH,09H,'抱歉,无法获得产品型号信息...',24H
MSG_VPP: DB 0DH,0AH,09H,'编程电压(V): ',24H
MSG_SIZE: DB 0DH,0AH,09H,'芯片容量: ',0DH,0AH,24H
MSG_UNSIZ: DB 0DH,0AH,09H,'抱歉,容量不明!',0DH,0AH,24H
MSG_ERR: DB 0DH,0AH,09H,"抱歉,卡座上没有元件?还是我无法识别?",0DH,0AH,'$'
;;;;;;;;;;;;;;;;;;
NOP
NOP
LJMP RESET
NOP
NOP
;==================================================
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -