$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
文章评论(0条评论)
登录后参与讨论