⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iapisp.asm

📁 STC-USER-IAP-ISP-DEMO(公开发布版本)-2011-3-9
💻 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 + -