;********************************************************* ;功能描述:P89C51RD2 IAP(擦除4K块,擦除8K/16K块,编程N字节) ;********************************************************* PGM_MTP EQU 0FFF0H ;公共接口 AUXR1 EQU 0A2H ADDR_L EQU 30H ;被编程数据的低8 位地址 ADDR_RAM_OUT EQU 41H ;显示读出的Flash EPROM数据 DATA_TEMP EQU 42H ;被编程数据 DATA_BUFF EQU 43H ;被编程数据 DATA_NUMBYT EQU 44H ;被编程数据的字节数 ORG 0000H AJMP START ORG 30H START: LCALL Clear16Byte ;给内部RAM中30H-3FH单元赋值 MOV DPTR,#8000H ;擦除BLOCK3 LCALL Erase4KBytes LCALL Verification4KBytes MOV ADDR_RAM_OUT,#30H ;从30H开始显示BLOCK3前8个字节 MOV DPTR,#8000H LCALL Display8Bytes MOV DPTR,#0C000H ;擦除BLOCK4 LCALL Erase8K_16KBytes LCALL Veri8K_16KBytes MOV ADDR_RAM_OUT,#38H ;从38H开始显示BLOCK4前8个字节 LCALL Display8Bytes MOV DPTR,#8000H ;从Flash中8000H开始写入 MOV DATA_NUMBYT,#8 ; 编程N个字节数据 LCALL WriteNBytes MOV DPTR,#8000H ;从8000H开始校验 MOV DATA_NUMBYT,#8 ; 校验N个字节数据 LCALL VeriNBytes MOV ADDR_RAM_OUT,#30H ;从30H开始显示 MOV DPTR,#8000H LCALL Display8Bytes NOP NOP AJMP $ Clear16Byte: CLR A MOV 30H,A MOV 31H,A MOV 32H,A MOV 33H,A MOV 34H,A MOV 35H,A MOV 36H,A MOV 37H,A MOV 38H,A MOV 39H,A MOV 3AH,A MOV 3BH,A MOV 3CH,A MOV 3DH,A MOV 3EH,A MOV 3FH,A RET Erase4KBytes: ORL AUXR1,#20H ;AUXR1 的位ENBOOT=1 寻址到固件 MOV R0,#11 ;晶振为11.O592M 取11 MOV R1,#0CH ;R1=0CH 块擦除4K LCALL PGM_MTP ;调用无返回参数 ANL AUXR1,#0DFH ;AUXR1 的位ENBOOT=0,防止IAP误触发 RET Erase8K_16KBytes: ORL AUXR1,#20H ;AUXR1 的位ENBOOT=1 寻址到固件 MOV R0,#11 ;晶振为11.O592M 取11 MOV R1,#01H ;R1=01H 块擦除8K/16K LCALL PGM_MTP ;调用无返回参数 ANL AUXR1,#0DFH ;AUXR1 的位ENBOOT=0,防止IAP误触发 RET ;字节编程 WriteByte: ;PUSH IE ; 关闭中断 ;CLR EA ORL AUXR1,#20H ;AUXR1 的位ENBOOT=1 寻址到固件 MOV R0,#11 ;晶振为11.O592M 取11 MOV R1,#02H ;R1=02H 字节编程功能 MOV A,DATA_BUFF ;被编程数据 LCALL PGM_MTP ;调用返回参数ACC=0 调用成功非0 调用失败 ;ANL AUXR1,#0DFH ;AUXR1 的位ENBOOT=0,防止IAP误触发 ;MOV DPTR,#0FFFFH ;送地址高字节单元为FF,防止误操作 ;MOV ADDR_L,#0FFH ;送地址低字节单元为FF,防止误操作 ;POP IE RET ;读闪存字节内容 ReadByte: ORL AUXR1,#20H ;AUXR1 的位ENBOOT=1 寻址到固件 MOV R0,#11 ;晶振为11.O592M 取11 MOV R1,#03H ;R1=03H 读闪存字节内容 LCALL PGM_MTP ;调用返回参数ACC 中为读出字节内容 ANL AUXR1,#0DFH ;AUXR1 的位ENBOOT=0,防止IAP误触发 RET ; Display8Bytes: MOV R5,#8 BytesRead: LCALL ReadByte MOV R0,ADDR_RAM_OUT MOV @R0,A INC DPTR INC ADDR_RAM_OUT DJNZ R5,BytesRead RET ;校验4K字节 Verification4KBytes: MOV R4,#16 MOV R5,#0 VeriBytesRead: LCALL ReadByte CJNE A,#0FFH,VeriError INC DPTR DJNZ R5,VeriBytesRead DJNZ R4,VeriBytesRead MOV A,#0 AJMP VeriEnd veriError: MOV A,#01 VeriEnd: RET ;校验8K/16K字节 Veri8K_16KBytes: MOV A,DPH CJNE A,#00, VeriBlock1 AJMP Veri8KBytes VeriBlock1: CJNE A,#20, Veri16KBytes AJMP Veri8KBytes Veri8KBytes: MOV R4,#32 MOV R5,#0 AJMP VeriBytesRead1 Veri16KBytes: MOV R4,#16 MOV R5,#0 VeriBytesRead1: LCALL ReadByte CJNE A,#0FFH,VeriError1 INC DPTR DJNZ R5,VeriBytesRead1 DJNZ R4,VeriBytesRead1 MOV A,#0 AJMP VeriEnd1 veriError1: MOV A,#01 VeriEnd1: RET WriteNBytes: MOV R5,DATA_NUMBYT MOV DATA_NUMBYT,#0 BytesWrite: MOV A,DATA_NUMBYT ;取被编程数据的个数 INC AUXR1 ;此时DPS为1,DPTR1有效 MOV DPTR,#WriteDataTAB MOVC A,@A+DPTR MOV DATA_BUFF,A ;送被编程数据送 INC DATA_NUMBYT INC AUXR1 ;此时DPS为0,DPTR0有效 LCALL WriteByte INC DPTR DJNZ R5,BytesWrite RET VeriNBytes: MOV R5,DATA_NUMBYT MOV DATA_NUMBYT,#0 BytesWrite1: MOV A,DATA_NUMBYT ;取被编程数据的个数 INC AUXR1 ;此时DPS为1,DPTR1有效 MOV DPTR,#WriteDataTAB MOVC A,@A+DPTR MOV DATA_BUFF,A ;送被编程数据送 INC DATA_NUMBYT INC AUXR1 ;此时DPS为0,DPTR0有效 LCALL ReadByte CJNE A,DATA_BUFF, veriError2 INC DPTR DJNZ R5,BytesWrite1 MOV A,#0 AJMP VeriEnd2 veriError2: MOV A,#01 VeriEnd2: RET WriteDataTAB: DB 0A1H,0B2H,0C3H,0D4H,0E5H,0F6H,07H,08H,20H,24H END