📄 串口调试.asm
字号:
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;每次写入一页128(BYTE)
;要求给定写入的FLASH地址DPH1;DPL1和要写的页数.
;返回FLASH的存储首地址.在DPH1和DPL1里.第二次调用时可以不用给地址.要判断页地址.
write_flash:
setb ROM_CE ;选中FLASH
INC AUXR1
MOV DPTR,#0000H ;给定串口接收的原始数据的起始地址.
wa_05: PUSH DPH
PUSH DPL
;MOV AUXR,#03H ;禁止内部RAM和禁止ALE输出.
mov r2,#80h ;共传送100h 要写128个数据 ;DPTR=00000H;OR=FF80H
mov dptr,#5555h ;给控制命令
mov a,#0aah
movx @dptr,a
mov dptr,#2aaah
mov a,#55h
movx @dptr,a
mov dptr,#5555h
mov a,#0a0h
movx @dptr,a
POP DPL
POP DPH ;DPTR=0000H;OR=FF80H
wa_01: CLR RAM_CE ;给定外部RAM的片选信号.
;MOV AUXR,#01H ;禁止ALE输出,允许访问内部RAM.
movx a,@dptr ;
inc dptr ;0001
INC AUXR1 ;选中FLASH的数据存放地址.
setb ROM_CE
;MOV AUXR,#03H ;
movx @dptr,a
inc dptr
INC AUXR1
djnz r2,wa_01 ; 128个字节存好了没有
mov r5,#84h ;55 ;延时10ms
wa_02: mov r6,#00h ;#0A0H
djnz r6,$
djnz r5,wa_02
djnz PAGE_COUNT,wa_05
ret
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;调试处理程序
;功能:根据给定的条件完成相应的工作.
screen_debug:
LCALL SPIN ;读操作码
CJNE A,#0AAH,debug_write ;判断是读还是写,AA表读,55表写.
LCALL SPIN ;读操作对象控制字节.00=内部RAM,01=外部RAM,02=外部ROM.
IN_RAM: CJNE A,#00,OUT_RAM;判断是对内部RAM操作还是对外部操作 ;以下是读内部RAM的程序.
LCALL SPIN ;页地址
LCALL SPIN ;DPH
LCALL SPIN ;DPL
MOV R0,A
LCALL SPIN ;BYTEH
LCALL SPIN ;BYTEL
MOV R1,A
IN_R0: MOV A,@R0
MOV SBUF,A
JNB TI,$
CLR TI
INC R0
DJNZ R1,IN_R0
RET
OUT_RAM: CJNE A,#01H,OUT_ROM ;以下是读外部RAM的处理程序.
CLR RAM_CE
LCALL SPIN ;页地址
MOV ROM_A17,BIT1
MOV P4.2,BIT0
SJMP READ_OUT
OUT_ROM: CJNE A,#02H,DEBUG_RET ;以下是读FLASH的处理程序.
SETB ROM_CE
MOV AUXR,#03H
LCALL SPIN ;页地址
MOV ROM_A17,BIT1
MOV P4.2,BIT0
LCALL SPIN
MOV DPH,A
LCALL SPIN
MOV DPL,A
LCALL SPIN
INC A
MOV R1,A
LCALL SPIN
MOV R2,A
MOV A,R2
MOV R3,A
ROM_OUT1: MOVX A,@DPTR
MOV SBUF,A
JNB TI,$
CLR TI
INC DPTR
DJNZ R3,ROM_OUT1
DJNZ R1,ROM_OUT1
DEBUG_RET: RET
debug_write:
CJNE A,#55H,DEBUG_RET
CLR RAM_CE
LCALL SPIN
MOV BYTEH,A
LCALL SPIN
MOV DPH1,A
LCALL SPIN
MOV DPL1,A
LCALL SPIN
LCALL SPIN
MOV PAGE_COUNT,A
MOV R1,PAGE_COUNT
MOV DPTR,#0000H
RD_ISR0:MOV R2,#80H
RD_ISR1:LCALL SPIN
MOVX @DPTR,A
INC DPTR
DJNZ R2,RD_ISR0
DJNZ R1,RD_ISR1
MOV A,BYTEH
MOV ROM_A17,BIT1
MOV P4.2,BIT0
MOV PAGE_COUNT,#0F0H ;共写255页数据 *
LCALL WRITE_FLASH ;写0000起的一页数据 *
RET
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
READ_OUT:LCALL SPIN ;DPH
MOV DPH,A
LCALL SPIN ;DPL
MOV DPL,A
LCALL SPIN ;BYTEH
MOV R2,A
LCALL SPIN ;BYTEL
MOV BYTEL,A
OUT_R1: MOV R1,BYTEL
OUT_R0: MOVX A,@DPTR
MOV SBUF,A
JNB TI,$
CLR TI
INC DPTR
DJNZ R1,OUT_R0
MOV A,R2
JZ OUT_RET
DEC R2
CJNE R2,#00,OUT_R1
OUT_RET: RET
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;串口读数子程序(SPIN) *
;占用资源:R0 *
;返回值A<<=SBUF *
SPIN: MOV DEL0,#60H ; *
SPIN3: MOV del1,#00H ;执行256次还收不到数据马上返回. *
spin0: mov del2,#00h ; *
SPIN1: JNB RI,SPIN2 ;WEI LING ZHUAN YI *
MOV A,SBUF ; *
CLR RI ; *
RET ; *
SPIN2: NOP ; *
DJNZ del2,SPIN1 ; *
djnz del1,spin0 ; *
DJNZ DEL0,SPIN3 ; *
CLR RI
MOV SP,#07H ; *
MOV A,#00H ; *
PUSH A ; *
PUSH A ; *
LJMP MARK
RETI ; *
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
TDELAY: NOP ;延时时间有TIME的初值决定
NOP
NOP
NOP
nop
nop
nop
DJNZ time1,TDELAY
RET
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
MCU_RESPONSE_YES: NOP ;发送屏号,高度,宽度.MCU_RESPONSE_YES
MOV SBUF,#0aah
JNB TI,$
CLR TI
MOV SBUF,SCREEN_NUMBER
JNB TI,$
CLR TI
RET
;**************************************************************************************
MCU_RESPONSE_NO: NOP
RET
;**************************************************************************************
RUN_DELAY: MOV DEL1,#00H ;运行速度延时
RUN0: MOV DEL2,#00H
RUN1: NOP
DJNZ DEL2,RUN1
DJNZ DEL1,RUN0
RET
;**************************************************************************************
PAUSE_DELAY: MOV DEL1,#01H ;亮度延时
PAUSE0: MOV DEL2,#00H
PAUSE1: NOP
DJNZ DEL2,PAUSE1
DJNZ DEL1,PAUSE0
RET
;初始化子程序.
INIT:SETB ROM_CE ;选中FLASH
SETB ROM_A17 ;页信号
SETB P4.2 ;页信号
MOV HANG,#08H ;给定扫描方式.
mov r1,#05h ;有5个数据要读(屏号,屏宽2位,屏高2位)
mov r0,#SCREEN_NUMBER ;r0指向屏参数寄存器的起始地址.
MOV DPTR,#0FF80H ;数据保存在FLASH的0FF80H起的地址.既W29C020的最后一页.
movx a,@dptr ;读屏号数据.
CJNE A,#0FFH,INIT0 ;判断是否是第一次上电用该控制器.
MOV screen_number,#00H ;屏号(00H,是程序经过用户复位设置后的屏号,也是群发的屏号.)
MOV screen_KUAN_H,#00H ;为了大于256点的屏与小屏兼容.(以后改为实际宽度/8=屏宽)
MOV SCREEN_KUAN_L,#08H ;初始设置为2个中文字的宽度,一般情况下单元模块宽度的点数.
MOV screen_GAO_H,#00H ;高度 *************
MOV SCREEN_GAO_L,#10H ;16点高度,一般情况下单元模块的高度点数.
SJMP INIT1
init0: movx a,@dptr ;取数
mov @r0,a ;存数
inc dptr ;取下一个单元
inc r0 ;存加一个单元
djnz r1,init0 ;取完没有
INIT1: MOV TMOD,#20h
MOV TH1,#0eah ;F=11.059MHZ;时FD=9600
MOV TH1,#0eah ;F=65.536MHZ;计算初值公式=256-(FOSC*(2*SCMOD))/384*BPS
;MOV PCON,#80H ;双倍波特率设置
MOV IE,#90H ;中断允许控制寄存器
MOV IP,#18H ;中断优先级控制寄存器
MOV TCON,#40H ;定时器控制寄存器
MOV SCON,#50h ;串行工作方式和接收允许控制
CLR RAM_CE ;选中RAM
MOV A,#0AAH ;准备判断外部RAM的存在.
MOV DPTR,#0400H ;没有扩展外部RAM的话呢89C516RD+最大到3FFH
MOVX @DPTR,A ;存测试数据到400H里
MOVX A,@DPTR ;从400H读出测试数据
CJNE A,#0AAH,OPEN_RAM ;不相等没有扩展外部RAM,允许访问内部扩展的RAM.
MOV AUXR,#02H ;扩展了外部RAM把内部扩展的RAM禁止掉.
OPEN_RAM:MOV A,#00H
MOVX @DPTR,A
mov dptr,#0000h
MOV R1,SCREEN_GAO_L ;屏的高度(行数)
INIT2: MOV R2,SCREEN_KUAN_L ;取出的低位.
INIT3: CLR A ;开始清除缓冲区数据.
movx @dptr,a ;清除指定地址单元的数据.
inc dptr ;地址加一.
djnz R2,INIT3 ;一行清除完没有.
DJNZ R1,INIT2 ;一屏数据清完没有.
;LCALL ININ_END ;调用初始化完成提示.
MOV A,SCREEN_KUAN_L ;准备计算单行的字节数.
RR A
MOV B,HANG ;/取出扫描方式.
MUL AB ;计算单页数据的1/2
MOV ISR_BYTEH,B ;除2,因为在接收时是接收两位再换行的.所以/2
MOV ISR_BYTEL,A;存在ISR_BYTEL里,准备在接收数据的时候用.大于64个字时不能用该算法.
MOV A,SCREEN_KUAN_L ;以下是计算一屏有多少数据量的程序.结果存在BYTEH,和BYTEL里.
MOV B,SCREEN_GAO_L
MUL AB
MOV BYTEH,B
MOV BYTEL,A
RET ;初初始化完成.
db 48h
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
MARK: SETB OE ; *
LCALL RUN_DELAY
CLR OE
LCALL RUN_DELAY
SJMP MARK
RET
TEST: MOV SBUF,A
JNB TI,$
CLR TI
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -