📄 用sst单片机做自己的isp下载程序.a51
字号:
jnb TI,$ ; 等到最后字节发送完成
ljmp resetval ; 跳到resetval程序和运行用户代码
;************************************************************************
;* 到其它伪IAP命令程序
*
;************************************************************************
nop_cmd:cjne a, #61h, cmd2
setb WDTC.1 ; 刷新看门狗定时器!
ljmp loop ; CMD 61H = NOP cmd
cmd2: cjne a, #SFCM_SE, cmd3
lcall byte3
mov SFDT, #55h
lcall sector_e ; 扇区擦除
ljmp loop
cmd3: cjne a, #SFCM_PB, cmd4
lcall byte3
lcall program_b ; 编程字节
ljmp loop
cmd4: cjne a, #SFCM_VB, wrongcmd
lcall byte3
lcall verify_b ; 校验字节
ljmp loop
wrongcmd:
ljmp loop ; 跳到BSL循环程序loop
nop
nop
nop
sjmp $ ;
;************************************************************************
byte3: lcall INBYTE ; 从PC读3个字节
mov ADRHI, a ; 1) 输入地址高位
mov DPH, a
lcall INBYTE ; 2) 输入地址底位
mov ADRLO, a
mov DPL, a
lcall INBYTE ; 3) 输入数值
mov COUNT, a
mov r0, #0
ret
;************************************************************************
nop
nop
nop
sjmp $ ;
;************************************************************************
;* 串口通讯子程序
*
;************************************************************************
OUTBYTE: ; 从串口发送一个字节
jnb TI, $ ; 等最后的字节发送完成
mov SBUF, a ; 把数据存入SBUF
clr TI ;
setb WDTC.1 ; 刷新看门狗定时器!
ret
;========================================================================
nop
nop
nop
sjmp $ ; 软件陷阱
;========================================================================
INBYTE: ; 从串口接收一个字节
jnb RI,$ ; 等上一个字节接收完成
mov a, SBUF ; 把接收到的数据放到ACC
clr RI ; 准备接收下一个字节
setb WDTC.1 ; 刷新看门狗定时器!
ret
;========================================================================
nop
nop
nop
sjmp $ ; 软件陷阱
;========================================================================
用SST单片机做自己的ISP下载程序!!(3) [www*szks*net] 2005-3-9 13:44:29
;************************************************************************
; 扇区擦除程序(IAP CMD: 0Bh)
*
; 输入项: (1) 开始地址: R4 = 地址高位, R5 = 地址低位 *
; (2) 扇区数 (R6)
*
; 返回: ACC *
; 使用的寄存器:
ACC,B,R0,R1,R2,R3,R4,R5,R6 *
; 这个程序擦除给定的扇区,从提供的开始地址。程序返回一个值给PC, *
; 表示操作成功(ACC.2 = 0)或失败(ACC.2 = 1) *
;************************************************************************
sector_e:
mov B, #SFCM_SE
mov a, CMD
cjne a, #SFCM_SE, error1
mov a, SFDT
cjne a, #55h, error2
nxtsctr:mov a, ADRHI
clr c
subb a, #0e0h
jnc error3
orl SFCF, #040h ; IAP使能
mov SFAH, ADRHI ; 存入地址高位
mov SFAL, ADRLO ; 存入地址低位
mov SFCM, B ; 发出扇区擦除命令
mov CMD, #04h ;
lcall done? ; 等扇区擦除完成
jb acc.2, exit2 ; 如果发生溢时就终止
djnz COUNT, newaddr
exit2: lcall OUTBYTE
anl SFCF, #10111111b ; IAPEN=0
mov SFDT, #0 ;
mov SFAH, #0abh ; 指向片外存储器
mov SFAL, #0cdh
mov B, #0 ; 非法IAP命令
ret
error1: mov a, #0C1h ; cmd不是合法扇区擦除命令(0Bh)
sjmp exit2
error2: mov a, #0C2h ; SFDT不合法的55h
sjmp exit2
error3: mov a, #0C3h ; 扇区地址指向块1
sjmp exit2
newaddr:mov a, ADRLO
add a, #128 ; 块0扇区大小是128字节
mov ADRLO, a ; 下一个扇区的低位地址
mov a, ADRHI
addc a, #0
mov ADRHI, a ; 下一个扇区的高位地址
sjmp nxtsctr
;========================================================================
nop
nop
nop
sjmp $ ; 软件陷阱
;========================================================================
;************************************************************************
; 编程字节(IAP CMD: 0Eh)
*
; 输入项: (1) 开始地址: DPH = 地址高位, DPL = 地址低位 *
; (2) 字节数(在R6) *
; 返回值: 无
*
; 使用的寄存器: ACC,B,R0,R1,R2,R3,R6,DPTR
*
; 程序接收开始地址和字节数,然后写入选定的地址 *
;************************************************************************
program_b:
mov B, #SFCM_PB
mov a, DPH
clr c
subb a, #0e0h
jnc exit3
lcall INBYTE ; 从串口接收一位
orl SFCF, #040h ; IAP使能
mov SFAH, DPH ; 放入准备写的地址
mov SFAL, DPL
mov SFDT, A ; 放入数据
mov SFCM, B ; 发出字节编程命令
mov CMD, #04h ; done?中屏蔽Flash_Busy位
lcall done? ; 等待命令完成
anl SFCF, #0BFh ; 禁止IAP
inc DPTR ; 地址指向下一个要写的地址
djnz COUNT, program_b ; 重复写,直到所有数据写完
exit3: anl SFCF, #10111111b ; IAPEN=0
mov SFDT, #0 ;
mov SFAH, #0abh ; 指向片外存储器
mov SFAL, #0cdh
mov B, #0 ; 非法IAP命令
ret
;========================================================================
nop
nop
nop
sjmp $ ; 软件陷阱
;========================================================================
;************************************************************************
; 字节校验程序(IAP CMD: 0Ch) *
; 输入项: (1) 开始地址: DPH = 地址高位, DPL = 地址低位
*
; (2) 扇区长度(在R6)
*
; 返回: ACC和SFDT存有最后读的数据
*
; 使用的寄存器: ACC,DPTR,R6 *
; 程序从要求的位置读数据,然后把数据传回PC.
*
;************************************************************************
verify_b:
mov a, DPH ; 块1的程序不能用IAP访问自己
clr c
subb a, #0e0h
jc block0
clr a
movc a, @a+dptr ; 用movc来读块1的内容
sjmp tellpc
block0: orl SFCF, #040h ; IAP使能
mov SFAH, DPH ; 存入高位地址
mov SFAL, DPL ; 存入低位地址
mov SFCM, #SFCM_VB ; 发出字节校对命令
nop
nop
nop
mov a, SFDT
tellpc: lcall OUTBYTE ; 数据发送到PC
inc DPTR ; 指向下一个数据地址
djnz COUNT, verify_b ; 读下一个字节,直到计数为零
anl SFCF, #00111111b ; 禁止IAP
mov SFDT, #0 ;
mov SFAH, #0abh ; 指向片外存储器
mov SFAL, #0cdh
mov B, #0 ; 非法IAP命令
ret
;========================================================================
nop
nop
nop
sjmp $ ; 软件陷阱
;========================================================================
;************************************************************************
;* 检查SFST.2位可以确定IAP操作是否完成
*
;************************************************************************
done?: mov a, SFST
jb acc.2, done? ; 等FLASH操作完成.
ret
;========================================================================
nop
nop
nop
sjmp $ ; 软件陷阱
;========================================================================
;************************************************************************
;* 重新置值程序
*
;************************************************************************
;* 1. 恢复SFR的初始值.
*
;* 2. 执行在块0 0000H地址的用户代码
*
;************************************************************************
resetval:
CLR A
MOV B, A
MOV PSW, A
MOV SP, #07H
MOV DPTR, #0
MOV IE, #40H
MOV IP, A
MOV PCON, A
ANL SFST, #11100000B
MOV SFCM, A
MOV SFDT, A
MOV SFAL, A
MOV SFAH, A
MOV RCAP2L, A
MOV RCAP2H, A
MOV TL2, A
MOV TH2, A
MOV T2CON,A
MOV SCON, A
MOV TCON, A
MOV TMOD, A
MOV TL0, A
MOV TH0, A
MOV TL1, A
MOV TH1, A
mov STR1, #'D' ; 破坏SRAM中08h,09h,0Ah,0Bh的数据
mov STR2, #'O'
mov STR3, #'N'
mov STR4, #'E'
anl SFCF, #10111100b ; VIS=1, IAPEN=0, REMAP=0KB
ljmp 0000h ; 执行在块0 0000H地址的用户代码
;=====================================================================
nop
nop
nop
sjmp $
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -