📄 用sst单片机做自己的isp下载程序.a51
字号:
C51编程:用SST单片机做自己的ISP下载程序!!(1) [www*szks*net] 2005-3-9 13:41:09
用SST单片机做自己的ISP在线下载程序!!下面是源代码,结合VB或VC编程PC端的下载窗
口,就是自己的ISP!
;************************************************************************
;* SST FlashFlex51系列单片机在线下载程序示例 *
;* (对应SST89E58RD2单片机 - 器件代码: E2h) *
;* (11.0592MHz的外部晶振/38.4Kbps波特率)
*
;*
*
;* NOTE:
*
;* 1. 在软件中,程序设内部看门狗的时间为50ms, 发送一个询问命令(F7h)给主 *
;* PC,等待PC来的握手命令(05h和55h)直到WDT溢出. 探测到握手命令后软件 *
;* 发出器件ID和软件版本号给主PC, 在两秒的时间内等待PC的伪IAP命令. *
;* 2. WDT溢出后程序将运行在0000H的用户程序.
*
;* 3. 在主PC, 用户可以发出运行用户代码命令(62h和62h)停止下载模式和运行 *
;* 用户程序. *
;* 4. 软件支持12MHz晶振时38.4Kbps串口波特率.
*
;* 5. 本程序是放在块1存储器内,所以需要把FLASH进行重映射,使单片机在复 *
;* 位后从块1启动,详细请参考SST单片机的器件资料. *
;* 6. 软件使用了下面的资源: *
;* 寄存器R0-R6; 内部RAM 08h-0Fh; 看门狗(WDT); A, B, DPTR, SFCF寄存器.*
;* 7. 只需要把SST单片机的串口通过232电平转换连到PC的串口. *
;*
*
;* 联系方式: 深圳科赛电子
*
;* 电话: (0755)83014227
*
;* website:www.szks.net
*
;* email: szks@szks.net
*
;************************************************************************
;************************************************************************
;* *
;* 8052系列特殊功能寄存器地址
*
;* *
;************************************************************************
T2CON DATA 0C8H
RCAP2L DATA 0CAH
RCAP2H DATA 0CBH
TL2 DATA 0CCH
TH2 DATA 0CDH
;************************************************************************
;* *
;* SST 51 MCU SST89E52RD2/54RD2/58RD2特殊功能寄存器地址
*
;* *
;************************************************************************
SFCF DATA 0B1H ; Flash配置位
SFCM DATA 0B2H ; Flash指令位
SFAL DATA 0B3H ; Flash地址低位
SFAH DATA 0B4H ; Flash地址高位
SFDT DATA 0B5H ; Flash数据位
SFST DATA 0B6H ; Flash状态位
WDTC DATA 0C0H ; 看门狗定时器控制
WDTD DATA 86H ; 看门狗定时器数据/重装
;************************************************************************
;* *
;* SST 51 MCU SST89E52RD2/54RD2/58RD2 IAP命令
*
;* *
;************************************************************************
SFCM_SE EQU 0BH ; 扇区擦除(Sector Erase)命令
SFCM_PB EQU 0EH ; 字节编程(Program byte)命令
SFCM_VB EQU 0CH ; 字节校验(Verify byte)命令
;************************************************************************
;* *
;* 定义变量
*
;* *
;************************************************************************
CMD EQU R2 ; PC命令
PCDATA EQU R3 ; PC数据
ADRHI EQU R4 ; 开始地址高位
ADRLO EQU R5 ; 开始地址低位
COUNT EQU R6 ; 字节数或大小
STR1 DATA 08h ; 内部RAM 08h - 0Bh用来存STRG
STR2 DATA 09h
STR3 DATA 0Ah
STR4 DATA 0Bh
;************************************************************************
;* 定义常量
*
;************************************************************************
SST89E52RD_ID EQU 9Dh ; SST89E52RD2的器件代码
SST89E54RD_ID EQU 9Fh ; SST89E54RD2的器件代码
SST89E58RD_ID EQU 9Bh ; SST89E58RD2的器件代码
FW_Ver EQU 11h ; 软件版本1.1
;************************************************************************
;* 复位和中断矢量(在块1 FLASH的扇区0) *
;************************************************************************
org 0E000h ; 影射后的复位矢量
ljmp start ; 跳到开始执行的代码
org 0E003h ; 外部中断0矢量
org 0E00Bh ; 定时器0溢出矢量
org 0E013h ; 外部中断1矢量
org 0E01Bh ; 定时器1溢出矢量
org 0E023h ; 串行I/O中断矢量
org 0E02Bh ; 定时器2溢出矢量
;************************************************************************
;* 运行下载代码或用户代码?
*
;************************************************************************
;* 下载程序开始后检查WDTC.2 (看门狗定时器复位标记),如果WDTC.2 = 0跳到 *
;* poweron程序;如果WDTC.2 = 1,把STR1-STR4与字符串"POWR"或"USER"做比较 *
;* 当WDT超时溢出,程序做下面动作:
*
;* 1. 如果WDT是在下载程序终止的,则清WDT复位标记. *
;* 2. 跳到resetval恢复SFR的初始值.
*
;************************************************************************
org 0E040h
start: mov a, SFCF ; 如果重映射,跳到chkwdtc
anl a, #00000011b
jz chkwdtc
mov STR1, #"R" ; 重映射没有设,置"RMAP"标志
mov STR2, #"M"
mov STR3, #"A"
mov STR4, #"P"
mov WDTD, #-2 ; 等10ms(典型值)后复位MCU
mov WDTC, #0fh ;
sjmp $ ; 软件陷阱
chkwdtc:jnb WDTC.2, poweron ; 上电复位后做初始化
mov a, STR1
cjne a, #'P', others
mov a, STR2
cjne a, #'O', others
mov a, STR3
cjne a, #'W', others
mov a, STR4
cjne a, #'R', others
orl WDTC, #00000100b ; 清除复位标记(WDTS, 就是WDTC.2 )
ljmp resetval ; 如果标记是"POWR",跳到resetval
others: mov a, STR1
cjne a, #'U', rmap
mov a, STR2
cjne a, #'S', rmap
mov a, STR3
cjne a, #'E', rmap
mov a, STR4
cjne a, #'R', rmap
; 如果flag="USER"和WDTC.2=1,跳到resetval
ljmp resetval ; 但不要清除WDT复位标记(WDTS) !!
rmap: mov a, STR1
cjne a, #'R', user
mov a, STR2
cjne a, #'M', user
mov a, STR3
cjne a, #'A', user
mov a, STR4
cjne a, #'P', user
orl WDTC, #00000100b ; 清复位标记
sjmp poweron
user: mov STR1, #'U' ; 设置标记"USER"
mov STR2, #'S'
mov STR3, #'E'
mov STR4, #'R'
sjmp init
用SST单片机做自己的ISP下载程序!!(2) [www*szks*net] 2005-3-9 13:43:33
;************************************************************************
;* 下载程序初始化程序
*
;************************************************************************
;* 1. 初始化SFR, 建立串口连接和开动WDT. *
;* 2. MCU发送询问命令(F7h)给主PC,等待PC来的握手命令,报告状态. *
;* 3. MCU发送命令F7h给PC,等待命令60h,再报告器件ID和软件版本. *
;* 4. 软件继续在循环程序运行: MCU发送命令F7h给PC,等待PC来的伪IAP指令. *
;* 5. 要退出循环程序,可以做复位或PC发一个运行用户代码命令(62h)给. *
;************************************************************************
poweron: ; 设"POWR"标记
mov STR1, #'P'
mov STR2, #'O'
mov STR3, #'W'
mov STR4, #'R'
init: clr a ; 清除A
mov PSW, a ; 清除程序状态字
mov IE, a ; 清除中断使能位
mov SP, #0Bh ; 0Ch到0Fh做为Stack!
anl SFCF, #10111111b ; IAPEN=0
mov SFDT, #0 ;
mov SFAH, #0abh ; 指向片外FLASH
mov SFAL, #0cdh
mov RCAP2H, #high(-9) ; 11.0592MHz晶振, 38.4Kbps
mov RCAP2L, #low(-9) ; 11.0592MHz晶振, 38.4Kbps
mov T2CON, #00110100b ; Timer2作为波特率发生器
mov SCON, #01010010b ; 模式1, 8位UART, 无奇偶, REN=1, TI=1
mov WDTD, #-5 ; 5 x 7.7ms=38ms(最小), 50ms(典型)
mov WDTC, #00001111b
;************************************************************************
;* 循环程序loop
*
;************************************************************************
;* MCU发一个询问命令(F7h),告诉主PC已经准备好接收伪IAP指令 *
;************************************************************************
loop: mov a, #0F7h ; 把询问命令(0F7H )存在ACC
jnb TI, $ ; 等到最后字节发送完
mov SBUF, a ; 发询问命令到串口
clr TI ;
mov B, #0 ; 无效的IAP命令
waitpc: jnb RI, waitpc ; 等输入字节准备好
mov a, SBUF ; 把接收到的数传给ACC
clr RI ; 准备接收下一个字节
mov CMD, a ; 复制ACC到CMD
setb WDTC.1 ; 刷新看门狗定时器!
;************************************************************************
;* 握手程序(伪IAP命令: 05h和55h)
*
;************************************************************************
;* 1. 检查握手命令顺序(05h和55h)和向主PC报告状态 *
;* 2. 如果检查到非法命令,继续执行BSL循环程序
*
;************************************************************************
cjne a, #05h, cmd60 ; 如果cmd不等于05h,跳到cmd60
setb WDTC.1 ; 刷新看门狗定时器!
lcall INBYTE ; 从串口读一个数
cjne a, #55h, loop ; 如果数据非法,继续循环程序
mov a, SFCF ; 读SFCF的BSEL(bit0)状态
anl a, #00000001b ; 把SECD(bit 7,6,5)和BSEL(bit0)合成一个
orl a, SFST ; 数送给主PC
lcall OUTBYTE ; 把状态数送到串口
clr WDTC.0 ; 停止WDT,准备做合法命令
mov WDTD, #-200 ; 看门狗定时器改为2秒
mov WDTC, #00001111b ; 使能复位reset, 清标志, 刷新和启动WDT
sjmp loop ; 继续BSL循环程序
;************************************************************************
;* 报告芯片ID和软件ID程序(伪IAP命令: 60h) *
;************************************************************************
;* 主PC要MCU报告芯片ID和软件ID:
*
;* 1. 发送器件代码: SST89E52RD2是9Dh,SST89E54RD2是9Fh,SST89E58RD2是9Bh*
;* 2. 发送软件版本号: 软件v1.1则是11h
*
;************************************************************************
cmd60: cjne a, #60h, cmd62
setb WDTC.1
mov a, #SST89E58RD_ID
lcall OUTBYTE
mov a, #FW_Ver
lcall OUTBYTE
sjmp loop
;************************************************************************
;* 运行用户程序(伪IAP CMD: 62h和62h)
*
;************************************************************************
;* 主PC发送这个命令来运行用户代码:
*
;* 1. MCU要接收两个连续的数: 62h和62h.
*
;* 2. 调到重置值程序resetval,把SFR恢复成初始值,然后 *
;************************************************************************
cmd62: cjne a, #62h, nop_cmd ; 如果不是62h则跳到nop_cmd
lcall INBYTE ; 从串口在读一个数
cjne a, #62h, loop ; 如果第二个数不是62h,那不是合法的顺序
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -