|
;---------------------------------------------------------------- ;用户中断向量写进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 - 作者: liu1234 |