📄 iapisp.asm
字号:
;/*------------------------------------------------------------------*/
;/* --- STC MCU International Limited -------------------------------*/
;/* --- STC IAP 系列单片机实现用户ISP 演示程序 ----------------------*/
;/* --- Mobile: (86)13922805190 -------------------------------------*/
;/* --- Fax: 86-755-82944243 ----------------------------------------*/
;/* --- Tel: 86-755-82948412 ----------------------------------------*/
;/* --- Web: www.STCMCU.com -----------------------------------------*/
;/* 如果要在程序中使用或者在文章中引用该程序,请在程序中或文章中注明 */
;/* 使用了宏晶科技的资料或程序 */
;/*------------------------------------------------------------------*/
;------------------------------------------------
;/*定义常数*/
UARTBAUD EQU 0FBH ;定义串口波特率 (256-18432000/32/115200)
;ENABLE_IAP EQU 80H ;系统工作频率<30MHz
;ENABLE_IAP EQU 81H ;系统工作频率<24MHz
;ENABLE_IAP EQU 82H ;系统工作频率<20MHz
ENABLE_IAP EQU 83H ;系统工作频率<12MHz
;ENABLE_IAP EQU 84H ;系统工作频率<6MHz
;ENABLE_IAP EQU 85H ;系统工作频率<3MHz
;ENABLE_IAP EQU 86H ;系统工作频率<2MHz
;ENABLE_IAP EQU 87H ;系统工作频率<1MHz
;------------------------------------------------
;/*定义特殊功能寄存器*/
AUXR DATA 08EH ;附件功能控制寄存器
BRT DATA 09CH ;波特率发生器
WDT_CONTR DATA 0C1H ;看门狗控制寄存器
IAP_DATA DATA 0C2H ;IAP数据寄存器
IAP_ADDRH DATA 0C3H ;IAP高地址寄存器
IAP_ADDRL DATA 0C4H ;IAP低地址寄存器
IAP_CMD DATA 0C5H ;IAP命令寄存器
IAP_TRIG DATA 0C6H ;IAP命令触发寄存器
IAP_CONTR DATA 0C7H ;IAP控制寄存器
;------------------------------------------------
;/*定义ISP模块使用的变量*/
ISPCODE EQU 0EC00H ;ISP模块入口地址(1页),同时也是外部接口地址
APENTRY EQU 0EE00H ;应用程序入口地址数据(1页)
;------------------------------------------------
ORG 0000H
LJMP ISP_ENTRY ;系统复位入口
RESET:
MOV SCON,#50H ;设置串口模式(8为可变,无校验位)
MOV AUXR,#15H ;BRT工作于1T模式,启动BRT
MOV BRT,#UARTBAUD ;设置重载值
NEXT1:
MOV R0,#16
NEXT2:
JNB RI,$ ;等待串口数据
CLR RI
MOV A,SBUF
CJNE A,#7FH,NEXT1 ;判断是否为7F
DJNZ R0,NEXT2
LJMP ISP_DOWNLOAD ;跳转到下载界面
;------------------------------------------------
;ISP功能模块
;包括上电自检模块和代码更新模块
;------------------------------------------------
ORG ISPCODE
ISP_DOWNLOAD:
CLR A
MOV PSW,A ;ISP模块使用第0组寄存器
MOV IE,A ;关闭所有中断
CLR RI ;清除串口接收标志
SETB TI ;置串口发送标志
CLR TR0
MOV SP,#5FH ;设置堆栈指针
;------------------------------------------------
MOV A,#5AH ;返回5A 55到PC,表示ISP擦除模块已准备就绪
LCALL ISP_SENDUART
MOV A,#055H
LCALL ISP_SENDUART
LCALL ISP_RECVACK ;接收应答数据
MOV IAP_ADDRL,#0 ;首先在第2页起始地址写 "LJMP ISP_ENTRY"指令
MOV IAP_ADDRH,#02H
LCALL ISP_ERASEIAP
MOV A,#02H
LCALL ISP_PROGRAMIAP ;编程用户代码复位向量代码
MOV A,#HIGH ISP_ENTRY
LCALL ISP_PROGRAMIAP ;编程用户代码复位向量代码
MOV A,#LOW ISP_ENTRY
LCALL ISP_PROGRAMIAP ;编程用户代码复位向量代码
MOV IAP_ADDRL,#0 ;用户代码地址从0开始
MOV IAP_ADDRH,#0
LCALL ISP_ERASEIAP
MOV A,#02H
LCALL ISP_PROGRAMIAP ;编程用户代码复位向量代码
MOV A,#HIGH ISP_ENTRY
LCALL ISP_PROGRAMIAP ;编程用户代码复位向量代码
MOV A,#LOW ISP_ENTRY
LCALL ISP_PROGRAMIAP ;编程用户代码复位向量代码
MOV IAP_ADDRL,#0 ;新代码缓冲区地址
MOV IAP_ADDRH,#02H
MOV R7,#117 ;擦除59K字节
ISP_ERASEAP:
LCALL ISP_ERASEIAP
INC IAP_ADDRH ;目标地址+512
INC IAP_ADDRH
DJNZ R7,ISP_ERASEAP ;判断是否擦除完成
MOV IAP_ADDRL,#LOW APENTRY ;用户代码复位入口页
MOV IAP_ADDRH,#HIGH APENTRY
LCALL ISP_ERASEIAP
MOV A,#5AH ;返回5A A5到PC,表示ISP编程模块已准备就绪
LCALL ISP_SENDUART
MOV A,#0A5H
LCALL ISP_SENDUART
LCALL ISP_RECVACK ;接收应答数据
LCALL ISP_RECVUART ;接收长度高字节
MOV R0,A
LCALL ISP_RECVUART ;接收长度低字节
MOV R1,A
CLR C ;将总长度-3
MOV A,#03H
SUBB A,R1
MOV DPL,A
CLR A
SUBB A,R0
MOV DPH,A ;总长度补码存入DPTR
LCALL ISP_RECVUART ;映射用户代码复位入口代码到映射区
LCALL ISP_PROGRAMIAP ;0000
LCALL ISP_RECVUART
LCALL ISP_PROGRAMIAP ;0001
LCALL ISP_RECVUART
LCALL ISP_PROGRAMIAP ;0002
MOV IAP_ADDRL,#03H ;用户代码起始地址
MOV IAP_ADDRH,#00H
ISP_PROGRAMNEXT:
LCALL ISP_RECVUART ;接收代码数据
LCALL ISP_PROGRAMIAP ;编程到用户代码区
INC DPTR
MOV A,DPL
ORL A,DPH
JNZ ISP_PROGRAMNEXT ;长度检测
ISP_SOFTRESET:
MOV IAP_CONTR,#20H ;软件复位系统
SJMP $
;------------------------------------------------
ISP_ENTRY:
MOV WDT_CONTR,#17H ;清看门狗
MOV IAP_CONTR,#ENABLE_IAP ;使能IAP功能
MOV IAP_ADDRL,#00H ;电压测试模块
MOV IAP_ADDRH,#0ECH ;测试地址EC00H
MOV IAP_DATA,#53H ;测试数据1
MOV IAP_CMD,#1 ;读命令
MOV IAP_TRIG,#5AH ;触发ISP命令
MOV IAP_TRIG,#0A5H
MOV A,IAP_DATA
XRL A,#53H ;测试是否可以读出数据
JZ ISP_ENTRY ;等待电压稳定
INC IAP_ADDRL ;测试地址EC01H
MOV IAP_DATA,#45H ;测试数据2
MOV IAP_CMD,#1 ;读命令
MOV IAP_TRIG,#5AH ;触发ISP命令
MOV IAP_TRIG,#0A5H
MOV A,IAP_DATA
XRL A,#45H ;测试是否可以读出数据
JZ ISP_ENTRY ;等待电压稳定
MOV SCON,#50H ;设置串口模式(8为可变,无校验位)
MOV AUXR,#15H ;BRT工作于1T模式,启动BRT
MOV BRT,#UARTBAUD ;设置重载值
MOV TMOD,#01H
SETB TR0
LCALL ISP_RECVUART ;检测是否有串口数据
JC GOTOAP
MOV R0,#16
ISP_CHECKNEXT:
LCALL ISP_RECVUART ;接收同步数据
JC GOTOAP
CJNE A,#7FH,GOTOAP ;判断是否为7F
DJNZ R0,ISP_CHECKNEXT
MOV A,#5AH ;返回5A 69到PC,表示ISP模块已准备就绪
LCALL ISP_SENDUART
MOV A,#69H
LCALL ISP_SENDUART
LCALL ISP_RECVACK ;接收应答数据
LJMP ISP_DOWNLOAD ;跳转到下载界面
GOTOAP:
CLR A ;将SFR恢复为复位值
MOV TCON,A
MOV TMOD,A
MOV TL0,A
MOV TH0,A
MOV SCON,A
MOV AUXR,A
MOV BRT,A
LJMP APENTRY ;正常运行用户程序
;------------------------------------------------
;/*接收来自于上位机的串口应答数据*/
ISP_RECVACK:
LCALL ISP_RECVUART
JC GOTOAP
XRL A,#7FH
JZ ISP_RECVACK ;跳过同步数据
CJNE A,#25H,GOTOAP ;应答数据1检测
LCALL ISP_RECVUART
JC GOTOAP
XRL A,#69H ;应答数据2检测
JNZ GOTOAP
RET
;------------------------------------------------
;/*接收1字节串口数据*/
;/*出口参数: ACC (接收到的数据)*/
;/*出口参数: C (1:超时)*/
ISP_RECVUART:
CLR A
MOV TL0,A ;初始化超时定时器
MOV TH0,A
CLR TF0
MOV WDT_CONTR,#17H ;清看门狗
ISP_RECVWAIT:
JBC TF0,ISP_RECVTIMEOUT ;超时检测
JNB RI,ISP_RECVWAIT ;等待接收完成
MOV A,SBUF ;读取串口数据
CLR RI ;清除标志
CLR C ;正确接收串口数据
RET
ISP_RECVTIMEOUT:
SETB C ;超时退出
RET
;------------------------------------------------
;/*发送1字节串口数据*/
;/*入口参数: ACC (待发送的数据)*/
ISP_SENDUART:
MOV WDT_CONTR,#17H ;清看门狗
JNB TI,ISP_SENDUART ;等待前一个数据发送完成
CLR TI ;清除标志
MOV SBUF,A ;发送当前数据
RET
;------------------------------------------------
;/*擦除IAP扇区*/
ISP_ERASEIAP:
MOV WDT_CONTR,#17H ;清看门狗
MOV IAP_CONTR,#ENABLE_IAP ;使能IAP功能
MOV IAP_CMD,#3 ;擦除命令
MOV IAP_TRIG,#5AH ;触发ISP命令
MOV IAP_TRIG,#0A5H
RET
;------------------------------------------------
;/*编程IAP字节*/
;/*入口参数: ACC (待编程的数据)*/
ISP_PROGRAMIAP:
MOV WDT_CONTR,#17H ;清看门狗
MOV IAP_CONTR,#ENABLE_IAP ;使能IAP功能
MOV IAP_CMD,#2 ;编程命令
MOV IAP_DATA,A ;将当前数据送IAP数据寄存器
MOV IAP_TRIG,#5AH ;触发ISP命令
MOV IAP_TRIG,#0A5H
MOV A,IAP_ADDRL ;IAP地址+1
ADD A,#01H
MOV IAP_ADDRL,A
MOV A,IAP_ADDRH
ADDC A,#00H
MOV IAP_ADDRH,A
RET
;------------------------------------------------
ORG APENTRY
LJMP RESET
;------------------------------------------------
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -