原创 GP32监控程序

2007-8-23 11:35 5006 9 9 分类: MCU/ 嵌入式

$INCLUDE "GP32.H"
;----------------------------------------------------------------
MAPREG1         EQU $0000
MAPREG2         EQU $FE00
;----------------------------------------------------------------
;RAM区
RAMSTART        EQU $0040


DBUFSTAddr      EQU $0040       ;(要写入FLASH的数据)的开始地址
                                ;$0041两个单元
PAGE            EQU $0042       ;下载程序的总页数
COUNT           EQU $0043       ;计数单元
VAR_COUNT       EQU $0044       ;计数单元
FlashAddress    EQU $0045       ;被擦写的FALSH地址
                                ;$0046两个单元
DATABUF         EQU $0047       ;$47-$C8为下载缓冲区,其中C7C8存放页地址
PAGEADDRBUF     EQU {DATABUF+!128}  ;C7C8存放页地址


VECTABBUF       EQU $00C9       ;00C9-00EC存放中断向量,其中EBEC 复位向量E9EA SWI向量
SWIVECBUF       EQU {VECTABBUF+!32};E9EA SWI向量
RESETVECBUF     EQU {VECTABBUF+!34};EBEC 复位向量


P_AddressInRAM  EQU $00ED       ;擦写flash子程序搬入ram的首地址,此后整个RAM区放擦写程序
;----------------------------------------------------------------
;FLASH区
U_RESET_H       EQU $FA00       ;用户程序复位向量挪入的区域,一页
U_RESET_L       EQU $FA01


MONADDR         EQU $FA80       ;监控程序开始地址
;BRK_SWI_INT    EQU $FB8D


VEC_TAB_ST      EQU $FFDC       ;中断向量起始地址
;----------------------------------------------------------------
        ORG MONADDR


        SEI                     ;禁止所有中断
        LDHX  #$023F            ;堆栈初始化放入GP32的RAM最高端
        TXS
;----------------------------------------------------------------
;初始化配置寄存器
        LDA  #%00000001      ;[初始化CONFIG2]
;                  |+---------;SCIBDSRC=1 SCI波特率使用内部总线时钟
;                  +----------;OSCSTOPENB=0 STOP模式下振荡器不工作、
        STA  CONFIG2


        LDA  #%00111101   ;[初始化CONFIG1]
;              |||||||+---------;COPD=1 禁止COP模块
;              ||||||+----------;STOP=0 禁止STOP指令
;              |||||+-----------;SSREC=1 经过32个CGMXCLK周期退出STOP模式
;              ||||+------------;LVI5OR3=1 LVI工作在5V
;              |||+-------------;LVIPWRD=1 禁止LVI模块电源
;              ||+--------------;LVIRSTD=1 允许LVI复位信号
;              |+---------------;LVISTOP=0 在stop模式下禁止LVI
;              +----------------;COPRS=0 COP溢出范围在2^18-2^4个CGMXCLK时钟周期
        STA  CONFIG1


;[PLL编程] 由外部晶阵f=32.768,产生内部总线时钟2.4576MHz
        CLR  PCTL               ;初始化PTCL
        MOV  #$01,PCTL
        MOV  #$01,PMSH      ;PLL倍频因子寄存器高位
        MOV  #$2C,PMSL          ;PLL倍频因子寄存器低位
        MOV  #$80,PMRS          ;PLL VCO范围选择寄存器
        BSET 5,PCTL
        BSET 7,PBWC
        BSET 4,PCTL
;----------------------------------------------------------------
        BSET 1,DDRA
;----------------------------------------------------------------
;串行口初始化
        LDA  #%01000000
;              |||||||+---------;PTY=0偶校验
;              ||||||+----------;PEN=0禁止奇偶校验
;              |||||+-----------;ILTY=0线路空闲类型,从起始位计数
;              ||||+------------;WAKE=0唤醒选择RXD引脚空闲时唤醒
;              |||+-------------;M=0字符长度8位
;              ||+--------------;TXINV=0反码选择,正常码输出
;              |+---------------;ENSCI=1,允许SCI
;              +----------------;LOOPS=0,非环路
        STA  SCC1


        LDA  #%00001100
;              |||||||+---------;SBK=0,禁止传送中止符
;              ||||||+----------;RWU=0,正常操作
;              |||||+-----------;D2(RE)=1,允许接收器
;              ||||+------------;D3(TE)=1,允许发送器
;              |||+-------------;ILIE=0线路空闲中断不允许
;              ||+--------------;SCRIE=0禁止接收中断查询方式收发
;              |+---------------;TCIE=0禁止发送中断查询方式收发
;              +----------------;SXTIE=0禁止发送空中断
        STA  SCC2



        LDA  #%00000010
;              |||||||+---------;0
;              ||||||+----------;1
;              |||||+-----------;0 010BD分频值为4
;              ||||+------------;0 保留位
;              |||+-------------;0
;              ||+--------------;0 00预分频为1
;              |+---------------;0 保留位
;              +----------------;0 保留位


        STA  SCBR               ;fBUS=2.4576MHz,取PD=1(即SCP1,SCP0=00)
                                ;BD=2(即SCR2,SCR1,SCR0=010)
                                ;则波特率=2457600 /(64*1*4) = 9600
;----------------------------------------------------------------
BEGIN:  LDA U_RESET_H           ;(FA00,FA01)=修改后的用户程序复位向量
        CMP #$FF                ;用户复位向量是否为空
        BNE DOWNNEW_OR_RUNOLD
        LDA U_RESET_L
        CMP #$FF
        BNE DOWNNEW_OR_RUNOLD   ;用户程序复位向量不空,转去执行用户程序
LOOP:   JSR HAND_WITH_PC        ;与PC机的握手程序,成功 C="1"
        BCC LOOP                ;C=0握手不成功继续握手
        BRA DOWNNEW_OR_BRK      ;握手成功,转去下载新用户程序或断点调试
;----------------------------------------------------------------
DOWNNEW_OR_RUNOLD:
        LDX #!50                ;用户程序复位向量不空,握手x次
LOOP1:  PSHX
        JSR HAND_WITH_PC        ;与PC机的握手程序,成功 C="1"
        PULX
        BCS DOWNNEW_OR_BRK      ;握手成功,转去下载新用户程序
        DBNZX LOOP1


        LDA U_RESET_H           ;握手不成功,转去执行用户程序
        PSHA
        PULH
        LDA U_RESET_L
        TAX
        JMP ,X


;至此只有复位可以退出程序,否则一直执行用户程序
;----------------------------------------------------------------
;握手成功
DOWNNEW_OR_BRK:
        BRCLR 5,SCS1,*          ;查询接收
        LDA SCDR
        CBEQA #$A7,DOWN_NEW_RUN ;第一字节=0xA7下载新用户程序
        CBEQA #$A8,RUN_BRK      ;第一字节=0xA8,转去断点调试
        BRA DOWNNEW_OR_BRK


DOWN_NEW_RUN:
        JSR DOWN_NEW            ;第一字节=0xA7下载新用户程序


RUNNEW: LDA U_RESET_H           ;执行用户程序
        PSHA
        PULH
        LDA U_RESET_L
        TAX
        JMP ,X
;至此只有复位可以退出程序,否则一直执行用户程序
;----------------------------------------------------------------
RUN_BRK:  
        LDA U_RESET_H           ;第一字节=0xA8断点调试;(FA00,FA01)=修改后的用户程序复位向量
        CMP #$FF
        BNE DOWITH_BRK          ;断点处理
        LDA U_RESET_L
        CMP #$FF
        BNE DOWITH_BRK          ;用户程序复位向量不空,转去断点调试


        LDHX #$0000             ;用户程序复位向量空,空片返回程序开始点
LOOP9:  LDA TAB_EMPTY,X         ;发送"空片"
        JSR SEND_BYTE           ;发送一字节
        AIX #$1
        CPHX #$5                ;5个字符
        BNE LOOP9
        JMP BEGIN               ;空片返回程序开始点


DOWITH_BRK:                     ;断点处理
        JSR AFFIRM_BRK_ADDR     ;确认断点子程序
        LDA U_RESET_H
        PSHA
        PULH
        LDA U_RESET_L
        TAX
        LDA #$80                ;断点允许,等待激活
        STA BRKSCR              ;断点控制寄存器
        CLI                     ;允许中断,主要是开放断点中断
        JMP ,X                  ;执行用户程序


FB27:   JMP BEGIN               ;这条指令实际执行不到
;----------------------------------------------------------------
AFFIRM_BRK_ADDR:                ;确认断点子程序
        BRCLR 5,SCS1,*          ;接收断点地址
        LDA SCDR
        PSHA
        PULH
        BRCLR 5,SCS1,*
        LDA SCDR
        TAX


        LDA #!10                ;连续接收从断点处10个字节
LOOP12: PSHA
        BRCLR 5,SCS1,*
        LDA SCDR
        CMP ,X                  ;与FLASH中的字节比较
        BNE ERROR               ;不等无效的断点地址
        AIX #$1
        PULA
        DBNZA LOOP12


        LDHX #$0                ;发送"成功"
LOOP10: LDA TAB_SUCCE,X
        JSR SEND_BYTE           ;发送一字节
        AIX #$1
        CPHX #5                 ;5个字符
        BNE LOOP10
        JMP SAVE_BRK


ERROR:  LDHX #$0
LOOP11: LDA TAB_ISERR,X         ;发送"错误"
        JSR SEND_BYTE           ;发送一字节
        AIX #$1
        CPHX #5
        BNE LOOP11
        JMP AFFIRM_BRK_ADDR


TAB_EMPTY:   DB 'Empty'
TAB_SUCCE:   DB 'Succe'
TAB_ISERR:   DB 'IsErr'


SAVE_BRK:                       ;接收断点并存入断点地址寄存器
        BRCLR 5,SCS1,*
        LDA SCDR
        STA BRKH
        BRCLR 5,SCS1,*
        LDA SCDR
        STA BRKL
        RTS
;----------------------------------------------------------------       
BRK_SWI_INT:
;中断后MCU自动进栈内容
;大地址
;| 1 PCL
;| 2 PCH
;| 3 X
;| 4 A
;| 5 CCR
;| 6 <-----SP
;V
;小地址
        SEI                     ;关中断
       
        LDA #$0                 ;禁止断点中断,清除断点中断标志
        STA BRKSCR
       
        PSHH
       
;堆栈内容
;大地址
;| 1 PCL
;| 2 PCH
;| 3 X
;| 4 A
;| 5 CCR
;| 6 H
;| 7 <-----SP
;V
;小地址       
        LDHX #DIS_INFO
        TXA
        STA 6,SP                ;断点地址换为DIS_INFO
        PSHH
        PULA
        STA 5,SP                ;断点地址换为DIS_INFO
        PULH               
        RTI                     ;退出中断,执行显示内容子程序想当于JMP指令
       
DIS_INFO:                       ;显示内容子程序,无返回
        PSHA       
        LDA #$A8                ;发送引导符A8
        JSR SEND_BYTE           ;发送一字节
       
        PULA                    ;A
        JSR SEND_BYTE           ;发送一字节
       
        TXA                     ;X->A
        JSR SEND_BYTE           ;发送一字节
       
        PSHH
        PULA                    ;H->A
        JSR SEND_BYTE           ;发送一字节
       
        TSX                     ;SP+1->H:X
        TXA                     ;SPL
        JSR SEND_BYTE           ;发送一字节
       
        PSHH
        PULA                    ;SPH
        JSR SEND_BYTE           ;发送一字节
       
        LDA #$0                
        INCA                    ;1
        JSR SEND_BYTE           ;发送一字节
       
        TPA                     ;CCR->A
        JSR SEND_BYTE           ;发送一字节
       
        LDHX #RAMSTART          ;发送RAM区数据
        LDA #0                  ;共512个,发两次
        JSR SEND_N_BYTE         ;发送
        LDA #0
        JSR SEND_N_BYTE
       
        LDHX #MAPREG1           ;发送各寄存器数据
        LDA #$40                ;共40H个
        JSR SEND_N_BYTE
       
        LDHX #MAPREG2           ;发送其余各寄存器数据
        LDA #$0D                ;共0DH个
        JSR SEND_N_BYTE
       
        LDA FLBPR               ;发送FLASH保护寄存器
        JSR SEND_BYTE           ;发送一字节
;?????????????????????可泄密       
        LDHX #VEC_TAB_ST        ;发送中断向量表
        LDA #!36
        JSR SEND_N_BYTE
       
LOOP13:                         ;是否下一断点调试
        BRCLR 5,SCS1,*          ;接收联络码64H
        LDA SCDR
        CMP #$64
        BNE LOOP13
       
        BRCLR 5,SCS1,*          ;接收并存储下一断点地址
        LDA SCDR
        STA BRKH
        BRCLR 5,SCS1,*
        LDA SCDR
        STA BRKL
       
        LDA U_RESET_H           ;重新从头运行用户程序
        PSHA
        PULH
        LDA U_RESET_L
        TAX
        LDA #$80                ;断点允许,等待激活
        STA BRKSCR              ;断点控制寄存器
        CLI
        JMP ,X                  ;执行用户程序
       
        RTS                     ;此句实际执行不到


SEND_N_BYTE:
        PSHA
        LDA ,X
        BRCLR 7,SCS1,*
        STA SCDR
        AIX #$1
        PULA
        DBNZA SEND_N_BYTE
        RTS
       
SEND_BYTE:
        BRCLR 7,SCS1,*
        STA SCDR
        RTS


;----------------------------------------------------------------
;----------------------------------------------------------------
;接收用户程序代码
DOWN_NEW:
        BRCLR 5,SCS1,*          ;查询接收程序的页数
        LDA SCDR
        STA PAGE                ;总页数


LOOP3:   LDHX #$0               ;接收一页数据(包括起始地址)
LOOP2:  BRCLR 5,SCS1,*          ;查询接收某页的字节和起始地址
        LDA SCDR
        STA DATABUF,X           ;从$47开始存放数据$47-$C8,(00C700C8)存放地址
        AIX #$1
        CPX #!130               ;页起始地址+128字节/页=130
        BCS LOOP2               ;C=1,X<#130


        LDA #$F4                ;FA00--FFFF区域受保护
        STA FLBPR
        LDHX PAGEADDRBUF
        STHX FlashAddress       ;擦FALSH程序的参数,被擦地址
        JSR EraseSub            ;擦FALSH程序


        LDHX #DATABUF
        STHX DBUFSTAddr
        MOV #!128,COUNT         ;43 计数单元
        LDHX PAGEADDRBUF
        STHX FlashAddress
        JSR WRITESUB            ;写FLASH子程序


        MOV #!128,COUNT         ;43 计数单元
        LDHX PAGEADDRBUF
LOOP4:  LDA ,X
        BRCLR 7,SCS1,*
        STA SCDR
        AIX #1
        DBNZ COUNT,LOOP4        ;发给pc机校验


        DBNZ PAGE,LOOP3         ;所有页是否接收完毕?


        JSR DOWITH_VECTAB       ;处理中断向量


        RTS
;----------------------------------------------------------------
;用户中断向量写进flash,注意复位向量要更改
DOWITH_VECTAB:
        LDHX #$0
LOOP5:  BRCLR 5,SCS1,*          ;接收用户程序中断向量
        LDA SCDR
        STA VECTABBUF,X         ;00C9-00EC存放中断向量
        AIX #1
        CPX #!36                ;中断向量表共18个,36字节
        BCS LOOP5


        JSR MOV_UR_VEC          ;处理用户复位向量


        LDHX #MONADDR           ;监控程序入口地址
        STHX RESETVECBUF        ;RAM中为用户复位向量,现改写


        LDHX #BRK_SWI_INT       ;软中断SWI入口地址
        STHX SWIVECBUF          ;RAM中为用户SWI向量,现改写


LOOP6:  LDA #$FF
        STA FLBPR               ;不保护FLASH区域
        LDHX #VEC_TAB_ST        ;中断向量起始地址
        STHX FlashAddress
        JSR  EraseSub           ;CA


        MOV #!36,COUNT          ;43计数单元,中断向量表共18个,36字节
        LDHX #VECTABBUF
        STHX DBUFSTAddr
        LDHX #VEC_TAB_ST        ;中断向量起始地址
        STHX FlashAddress
        JSR  WRITESUB           ;写FLASH子程序


        LDHX #!35               ;0-35共36个,从后往前校验
LOOP7:  LDA VEC_TAB_ST,X        ;校验是否写对
        CMP VECTABBUF,X
        BNE LOOP6               ;不对重写
        DBNZX LOOP7             ;原来程序如此,这样第0个未校验
;??????????????????????????????????????????????????????????????       


        MOV #!36,COUNT          ;发给pc机校验
        LDHX #VEC_TAB_ST
LOOP8:  LDA ,X
        BRCLR 7,SCS1,*
        STA SCDR
        AIX #$1
        DBNZ COUNT,LOOP8
        RTS
;----------------------------------------------------------------
;搬移用户复位向量
MOV_UR_VEC:
        LDA #$FF
        STA FLBPR               ;不保护FLASH区域
        LDHX #U_RESET_H
        STHX FlashAddress
        JSR EraseSub            ;先擦除挪入的空间fa80开始的一页


        MOV #$2,COUNT           ;43 计数单元
        LDHX #RESETVECBUF
        STHX DBUFSTAddr
        LDHX #U_RESET_H
        STHX FlashAddress
        JSR  WRITESUB           ;写用户复位向量到FA00,FA01


        RTS
;----------------------------------------------------------------
;握手联络程序,联络失败,C=0;联络成功,C=1
HAND_WITH_PC:
        LDA #$56                ;发送联络码
        BRCLR 7,SCS1,*
        STA SCDR


        LDHX #$0
WAIT_PC:
        BRSET 5,SCS1,HAVE_RECV  ;接收PC信号
        AIX #1
        CPHX #$AABB             ;在规定的时间内接收联络码
        BNE WAIT_PC
        JMP CONNECT_FAIL        ;联络失败


HAVE_RECV:
        LDA SCDR
        CMP #$38
        BNE CONNECT_FAIL        ;联络失败
        JMP CONNECT_GOOD        ;联络成功


CONNECT_FAIL:
        CLC                     ;联络失败,C=0
        JMP HAND_EXIT


CONNECT_GOOD:
        SEC                     ;联络成功,C=1
HAND_EXIT:
        RTS
;----------------------------------------------------------------
;---写Flash子程序(WriteSub)---------------------------*
;功能:将RAM区中从指定的首地址{Adrress1,Adrress1+1}   *
;      开始的COUNT个字节数据一个一个地复制到Flash中,     *
;      其首地址为FlashAddress。                       *
;       (2) 内存COUNT中=要写入的字节数                   *
;       (3) Flash中的首地址:FlashAddress。            *
;入口:(1) RAM区中的首地址{Adrress1,Adrress1+1}       *
;出口:无                                              *
;占用内部寄存器:A,HX                                 *
;占用内存:COUNT,VAR_COUNT                                      *
;说明:这段程序及其内部调用的子程序,需在执行前移入RAM *
;     区执行,被移入RAM区的起始地址为P_AddressInRAM   *
;-----------------------------------------------------*
;Write_Flash=$FD36
;VAR_COUNT=$44
;WriteSub=$FD16
;MoveToRAM1=$FD1C
;P_AddressInRAM =$00ED写flash搬移ram的首地址
;Write_Flash_EXIT =$FD7C
;FlashAddress=$0045
WriteSub:
                                ;将写FLASH程序从FLASH区移到RAM中
        LDHX #Write_Flash       ;写FLASH子程序的首地址->HX
        MOV #$0,VAR_COUNT       ;0->VAR_COUNT
MoveToRAM1:
        LDA ,X                  ;X->A
        PSHH                    ;保存写入程序在FLASH中的地址
        PSHX
        LDHX #$0000             ;清HX
        LDX VAR_COUNT           ;VAR_COUNT偏移变量->X
        STA P_AddressInRAM,X    ;(A)->RAM中相应址址
        INC VAR_COUNT           ;(VAR_COUNT)+1->VAR_COUNT
        PULX                    ;FLASH中的地址出栈
        PULH
        AIX #$1
        CPHX #Write_Flash_EXIT  ;是否到了要写入程序的末地址
        BLO  MoveToRAM1         ;否,继续移动
                                ;至此写入程序已从FLASH移到RAM中,以下执行RAM中的写入程序



;写入程序(Write_Flash),移入内存后成为P_AddressInRAM
;入口为:DBUFSTAddr,COUNT,HX
;DBUFSTAddr~DBUFSTAddr+1:要写入字节的首地址
;COUNT:要写入的字节数
;HX:被写FLASH的起始地址
;至此执行写入程序所需的参数已初始化
        LDHX  FlashAddress


        JSR  P_AddressInRAM     ;执行写入程序,写入
                                ;程序在RAM中的起始
                                ;位置P_AddressInRAM
                                ;写入结束
        RTS
;----------------------------------------------------------------
;Delay_NusB=$FD77
;COUNT=$0043
;Write_Flash_1=$FD4F
;DBUFSTAddr=$0040
Write_Flash:
        LDA  #%00000001         ;①置FLCR的PGM位=1
        STA  FLCR


        LDA  FLBPR              ;②读出Flash块保护寄存器(FLBPR)


        STA  ,X                 ;③数据写入所选块的Flash任意单元


        LDA  #!3                ;④延时Tnvs:延时10μs(GP32)
        BSR  Delay_NusB


        LDA  #%00001001         ;⑤置FLCR的HVEN位为1
        STA  FLCR


        LDA  #!3                ;⑥延时Tpgs延时10us(GP32)
        BSR  Delay_NusB


        MOV  COUNT,VAR_COUNT
Write_Flash_1:                  ;⑦向页内目标地址写入一个字节数据
        PSHH                    ;保存Flash地址
        PSHX
        LDHX  DBUFSTAddr        ;RAM地址->HX
        LDA  ,X                 ;RAM中的一个字节->A
        AIX  #!1
        STHX  DBUFSTAddr
        PULX
        PULH
        STA  ,X                 ;A->目标区第X个字节处


        LDA  #!9                ;⑧延时Tpgs延时30μs(GP32)
        BSR  Delay_NusB


        AIX  #$1
        DBNZ  VAR_COUNT,Write_Flash_1  ;重复⑦,⑧写入COUNT个字节数据,循环COUNT次 
        LDA  #$8
        STA  FLCR               ;⑨0->PGM
        LDA  #!3                ;⑩延时Tpgs,
                                ;延时10μs(GP32)
        BSR  Delay_NusB
        LDA  #$00               ;⑾ 0->HVEN
        STA  FLCR
        LDA  #!1                ;⑿ 延时Tpgs,
                                ;延时6μs(GP32)
        BSR  Delay_NusB
        RTS


;---延时子程序(Delay_SubB)----------------------------*
;功能:延时一定时间                                    *
;入口:A                                              *
;占用内部寄存器:无                                   *
;使用方法                                             *
;       LDA #!3          ; 延时10μs                  *
;       BSR Delay_NusB                                *
;备注:设总线频率为f=2.4576MHz,每个周期为τ=1/f≈0.4μs*
;     设入口A的值为A(A=1~255),使用BSR语句调用        *
;     Delay_Nus子程序,                               *
;     延时为T(μs)                                    *
;     计算公式为:                                    *
;       T=  2*0.4  + 4*0.4+A*(5*0.4)+4*0.4=4+2A       *
;         LDA #opr     BSR      循环体                *
;       RTS                                           *
;      所以A=(T-4)/2                                  *
;      T="6"μs   A="1"; T="10"μs  A="3";  T="30"μs  A="13";    *
;      T="500"μs A="248"                                 *
;      当延时超过500μs,采用循环调用                  *
;-----------------------------------------------------*
Delay_NusB:
        NOP                     ;1个周期
        NOP                     ;1个周期
        DBNZA  Delay_NusB       ;3个周期
        RTS                     ;4个周期
;Write_Flash_EXIT=$FD7C
Write_Flash_EXIT:
        NOP
;----------------------------------------------------------------
;---擦除Flash存储区的一页(GP32)子程序(EraseSub)-------*
;功能:擦除Flash存储区的一页                           *
;入口:FlashAddress(擦除Flash一页的首地址)            *
;出口:无                                              *
;占用内部寄存器:A,HX                                 *
;占用内存:VAR_COUNT,P_AddressInRAM                          *
;内部调用:Delay_NusA (延时子程序)                  *
;说明:这段程序及其内部调用的子程序,需在执行前移入RAM *
;     区执行,被移入RAM                               *
;     区的起始地址为P_AddressInRAM                    *
;-----------------------------------------------------*
;EraseSub=$EraseSub
;Erase1Page=$FD9D
;VAR_COUNT=$44
;MoveToRAM=$FD83
;P_AddressInRAM =$00ED擦除flash搬移ram的首地址
;Erase1Page_EXIT=FDD0
;FlashAddress=$0045
EraseSub:
        LDHX  #Erase1Page       ;擦除FLASH程序首地址->HX
        MOV  #$0,VAR_COUNT      ;0->VAR_COUNT


                                ;将擦除程序从FLASH移到RAM中
MoveToRAM:
        LDA  ,X                 ;X->A
        PSHH                    ;保存擦除程序在FLASH
        PSHX                    ;中的地址
        LDHX  #$0000            ;清HX  
        LDX  VAR_COUNT          ;VAR_COUNT偏移变量->X
        STA  P_AddressInRAM,X   ;(A)->RAM中相应址址
        INC  VAR_COUNT          ;(VAR_COUNT)+1->VAR_COUNT
        PULX                    ;FLASH中的地址出栈
        PULH
        AIX  #$1
        CPHX  #Erase1Page_EXIT  ;到了要擦除的末地址?
        BLO  MoveToRAM          ;否,继续移动


                                ;至此擦除程序已从FLASH移到RAM中,
                                ;下面执行RAM中的擦除程序


        LDHX  FlashAddress      ;{FlashAddress}为要擦除的Flash页首地址
        JSR  P_AddressInRAM     ;执行擦除程序
        RTS
;----------------------------------------------------------------
;Erase1Page=$FD9D
;Delay_NusA=$FDCB


Erase1Page:
        LDA  #%00000010         ;①置Flash控制寄存器(FLCR)的ERASE=1,MASS=0
        STA  FLCR


        LDA  FLBPR              ;②读出Flash块保护寄存器(FLBPR)


        LDA  #$68               ;③向被擦除的Flash页内任意地址写入任意值
        STA  ,X                 ;(注意:本程序HX是入口)


        LDA  #!3                ;④延时Tnvs:延时10μs(GP32)
        BSR  Delay_NusA


        LDA  #%00001010         ;⑤置FLCR的HVEN位为1打开电荷泵加电平到Flash阵列
        STA  FLCR


        LDA  #!248              ;⑥延时Terase:延时1ms(GP32)-Flash页擦除时间
        BSR  Delay_NusA         ;(每次500μs,2次)
        LDA  #!248
        BSR  Delay_NusA


        LDA  #%00001000         ;⑦清Erase位为0;
        STA  FLCR


        LDA  #!3                ;⑧延时Tnvh延时10μs(GP32)
        BSR  Delay_NusA


        CLRA                    ;⑨清HVEN位为0
        STA  FLCR


        LDA  #!3                ;⑩延时Trcv延时10μs(GP32)
        BSR  Delay_NusA


        RTS


;---延时子程序(Delay_SubA)----------------------------*
;功能:延时一定时间                                    *
;入口:A                                              *
;占用内部寄存器:无                                   *
;使用方法                                             *
;       LDA #!3          ; 延时10μs                  *
;       BSR Delay_NusA                                *
;备注:设总线频率为f=2.4576MHz,每个周期为τ=1/f≈0.4μs*
;     设入口A的值为A(A=1~255),使用BSR语句调用        *
;     Delay_Nus子程序,                               *
;     延时为T(μs)                                    *
;     计算公式为:                                    *
;       T=  2*0.4  + 4*0.4+A*(5*0.4)+4*0.4=4+2A       *
;         LDA #opr     BSR      循环体                *
;       RTS                                           *
;      所以A=(T-4)/2                                  *
;      T="6"μs   A="1"; T="10"μs  A="3";  T="30"μs  A="13";    *
;      T="500"μs A="248"                                 *
;      当延时超过500μs,采用循环调用                  *
;-----------------------------------------------------*
Delay_NusA:
        NOP                     ;1个周期
        NOP                     ;1个周期
        DBNZA  Delay_NusA       ;3个周期
        RTS                     ;4个周期
Erase1Page_EXIT:
        NOP
        ORG $FFFC
        DW BRK_SWI_INT
        ORG $FFFE
        DW MONADDR
        END

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
9
关闭 站长推荐上一条 /3 下一条