?? 用sst單片機(jī)做自己的isp下載程序.a51
字號:
C51編程:用SST單片機(jī)做自己的ISP下載程序!!(1) [www*szks*net] 2005-3-9 13:41:09
用SST單片機(jī)做自己的ISP在線下載程序??!下面是源代碼,結(jié)合VB或VC編程PC端的下載窗
口,就是自己的ISP!
;************************************************************************
;* SST FlashFlex51系列單片機(jī)在線下載程序示例 *
;* (對應(yīng)SST89E58RD2單片機(jī) - 器件代碼: E2h) *
;* (11.0592MHz的外部晶振/38.4Kbps波特率)
*
;*
*
;* NOTE:
*
;* 1. 在軟件中,程序設(shè)內(nèi)部看門狗的時(shí)間為50ms, 發(fā)送一個(gè)詢問命令(F7h)給主 *
;* PC,等待PC來的握手命令(05h和55h)直到WDT溢出. 探測到握手命令后軟件 *
;* 發(fā)出器件ID和軟件版本號給主PC, 在兩秒的時(shí)間內(nèi)等待PC的偽IAP命令. *
;* 2. WDT溢出后程序?qū)⑦\(yùn)行在0000H的用戶程序.
*
;* 3. 在主PC, 用戶可以發(fā)出運(yùn)行用戶代碼命令(62h和62h)停止下載模式和運(yùn)行 *
;* 用戶程序. *
;* 4. 軟件支持12MHz晶振時(shí)38.4Kbps串口波特率.
*
;* 5. 本程序是放在塊1存儲器內(nèi),所以需要把FLASH進(jìn)行重映射,使單片機(jī)在復(fù) *
;* 位后從塊1啟動(dòng),詳細(xì)請參考SST單片機(jī)的器件資料. *
;* 6. 軟件使用了下面的資源: *
;* 寄存器R0-R6; 內(nèi)部RAM 08h-0Fh; 看門狗(WDT); A, B, DPTR, SFCF寄存器.*
;* 7. 只需要把SST單片機(jī)的串口通過232電平轉(zhuǎn)換連到PC的串口. *
;*
*
;* 聯(lián)系方式: 深圳科賽電子
*
;* 電話: (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數(shù)據(jù)位
SFST DATA 0B6H ; Flash狀態(tài)位
WDTC DATA 0C0H ; 看門狗定時(shí)器控制
WDTD DATA 86H ; 看門狗定時(shí)器數(shù)據(jù)/重裝
;************************************************************************
;* *
;* SST 51 MCU SST89E52RD2/54RD2/58RD2 IAP命令
*
;* *
;************************************************************************
SFCM_SE EQU 0BH ; 扇區(qū)擦除(Sector Erase)命令
SFCM_PB EQU 0EH ; 字節(jié)編程(Program byte)命令
SFCM_VB EQU 0CH ; 字節(jié)校驗(yàn)(Verify byte)命令
;************************************************************************
;* *
;* 定義變量
*
;* *
;************************************************************************
CMD EQU R2 ; PC命令
PCDATA EQU R3 ; PC數(shù)據(jù)
ADRHI EQU R4 ; 開始地址高位
ADRLO EQU R5 ; 開始地址低位
COUNT EQU R6 ; 字節(jié)數(shù)或大小
STR1 DATA 08h ; 內(nèi)部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
;************************************************************************
;* 復(fù)位和中斷矢量(在塊1 FLASH的扇區(qū)0) *
;************************************************************************
org 0E000h ; 影射后的復(fù)位矢量
ljmp start ; 跳到開始執(zhí)行的代碼
org 0E003h ; 外部中斷0矢量
org 0E00Bh ; 定時(shí)器0溢出矢量
org 0E013h ; 外部中斷1矢量
org 0E01Bh ; 定時(shí)器1溢出矢量
org 0E023h ; 串行I/O中斷矢量
org 0E02Bh ; 定時(shí)器2溢出矢量
;************************************************************************
;* 運(yùn)行下載代碼或用戶代碼?
*
;************************************************************************
;* 下載程序開始后檢查WDTC.2 (看門狗定時(shí)器復(fù)位標(biāo)記),如果WDTC.2 = 0跳到 *
;* poweron程序;如果WDTC.2 = 1,把STR1-STR4與字符串"POWR"或"USER"做比較 *
;* 當(dāng)WDT超時(shí)溢出,程序做下面動(dòng)作:
*
;* 1. 如果WDT是在下載程序終止的,則清WDT復(fù)位標(biāo)記. *
;* 2. 跳到resetval恢復(fù)SFR的初始值.
*
;************************************************************************
org 0E040h
start: mov a, SFCF ; 如果重映射,跳到chkwdtc
anl a, #00000011b
jz chkwdtc
mov STR1, #"R" ; 重映射沒有設(shè),置"RMAP"標(biāo)志
mov STR2, #"M"
mov STR3, #"A"
mov STR4, #"P"
mov WDTD, #-2 ; 等10ms(典型值)后復(fù)位MCU
mov WDTC, #0fh ;
sjmp $ ; 軟件陷阱
chkwdtc:jnb WDTC.2, poweron ; 上電復(fù)位后做初始化
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 ; 清除復(fù)位標(biāo)記(WDTS, 就是WDTC.2 )
ljmp resetval ; 如果標(biāo)記是"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復(fù)位標(biāo)記(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 ; 清復(fù)位標(biāo)記
sjmp poweron
user: mov STR1, #'U' ; 設(shè)置標(biāo)記"USER"
mov STR2, #'S'
mov STR3, #'E'
mov STR4, #'R'
sjmp init
用SST單片機(jī)做自己的ISP下載程序?。。?) [www*szks*net] 2005-3-9 13:43:33
;************************************************************************
;* 下載程序初始化程序
*
;************************************************************************
;* 1. 初始化SFR, 建立串口連接和開動(dòng)WDT. *
;* 2. MCU發(fā)送詢問命令(F7h)給主PC,等待PC來的握手命令,報(bào)告狀態(tài). *
;* 3. MCU發(fā)送命令F7h給PC,等待命令60h,再報(bào)告器件ID和軟件版本. *
;* 4. 軟件繼續(xù)在循環(huán)程序運(yùn)行: MCU發(fā)送命令F7h給PC,等待PC來的偽IAP指令. *
;* 5. 要退出循環(huán)程序,可以做復(fù)位或PC發(fā)一個(gè)運(yùn)行用戶代碼命令(62h)給. *
;************************************************************************
poweron: ; 設(shè)"POWR"標(biāo)記
mov STR1, #'P'
mov STR2, #'O'
mov STR3, #'W'
mov STR4, #'R'
init: clr a ; 清除A
mov PSW, a ; 清除程序狀態(tài)字
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作為波特率發(fā)生器
mov SCON, #01010010b ; 模式1, 8位UART, 無奇偶, REN=1, TI=1
mov WDTD, #-5 ; 5 x 7.7ms=38ms(最小), 50ms(典型)
mov WDTC, #00001111b
;************************************************************************
;* 循環(huán)程序loop
*
;************************************************************************
;* MCU發(fā)一個(gè)詢問命令(F7h),告訴主PC已經(jīng)準(zhǔn)備好接收偽IAP指令 *
;************************************************************************
loop: mov a, #0F7h ; 把詢問命令(0F7H )存在ACC
jnb TI, $ ; 等到最后字節(jié)發(fā)送完
mov SBUF, a ; 發(fā)詢問命令到串口
clr TI ;
mov B, #0 ; 無效的IAP命令
waitpc: jnb RI, waitpc ; 等輸入字節(jié)準(zhǔn)備好
mov a, SBUF ; 把接收到的數(shù)傳給ACC
clr RI ; 準(zhǔn)備接收下一個(gè)字節(jié)
mov CMD, a ; 復(fù)制ACC到CMD
setb WDTC.1 ; 刷新看門狗定時(shí)器!
;************************************************************************
;* 握手程序(偽IAP命令: 05h和55h)
*
;************************************************************************
;* 1. 檢查握手命令順序(05h和55h)和向主PC報(bào)告狀態(tài) *
;* 2. 如果檢查到非法命令,繼續(xù)執(zhí)行BSL循環(huán)程序
*
;************************************************************************
cjne a, #05h, cmd60 ; 如果cmd不等于05h,跳到cmd60
setb WDTC.1 ; 刷新看門狗定時(shí)器!
lcall INBYTE ; 從串口讀一個(gè)數(shù)
cjne a, #55h, loop ; 如果數(shù)據(jù)非法,繼續(xù)循環(huán)程序
mov a, SFCF ; 讀SFCF的BSEL(bit0)狀態(tài)
anl a, #00000001b ; 把SECD(bit 7,6,5)和BSEL(bit0)合成一個(gè)
orl a, SFST ; 數(shù)送給主PC
lcall OUTBYTE ; 把狀態(tài)數(shù)送到串口
clr WDTC.0 ; 停止WDT,準(zhǔn)備做合法命令
mov WDTD, #-200 ; 看門狗定時(shí)器改為2秒
mov WDTC, #00001111b ; 使能復(fù)位reset, 清標(biāo)志, 刷新和啟動(dòng)WDT
sjmp loop ; 繼續(xù)BSL循環(huán)程序
;************************************************************************
;* 報(bào)告芯片ID和軟件ID程序(偽IAP命令: 60h) *
;************************************************************************
;* 主PC要MCU報(bào)告芯片ID和軟件ID:
*
;* 1. 發(fā)送器件代碼: SST89E52RD2是9Dh,SST89E54RD2是9Fh,SST89E58RD2是9Bh*
;* 2. 發(fā)送軟件版本號: 軟件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
;************************************************************************
;* 運(yùn)行用戶程序(偽IAP CMD: 62h和62h)
*
;************************************************************************
;* 主PC發(fā)送這個(gè)命令來運(yùn)行用戶代碼:
*
;* 1. MCU要接收兩個(gè)連續(xù)的數(shù): 62h和62h.
*
;* 2. 調(diào)到重置值程序resetval,把SFR恢復(fù)成初始值,然后 *
;************************************************************************
cmd62: cjne a, #62h, nop_cmd ; 如果不是62h則跳到nop_cmd
lcall INBYTE ; 從串口在讀一個(gè)數(shù)
cjne a, #62h, loop ; 如果第二個(gè)數(shù)不是62h,那不是合法的順序
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -