我正在尝试用8051机器语言创建一个程序,它允许我以16字节块的形式将数据从ROM发送到PC,以便它可以同时执行其他工作。在这段代码中,我期待屏幕上显示以下输出:
Central station Debug Mode
Testing 115200bps speed mode with 16 byte chunks
12345678901234567890123456789012345678901234567890123456789012345678901234567890
80x25 screen?
uC to Linux screen test
Working? Yes? Maybe? No?
Test 100% wireless. 115200bps speed
TEST IS NOW FINISHED!
TX TEST OVER WAITING FOR RECEPTION!
然而,我得到的远不止于此。我实际收到的输出(根据Linux中的screen命令)如下:
OITPECER ROF
!H
我查看该文本,它让我认为它处理了最后16个字节,同时跳过了其余的开头字节。
我得到的微控制器和我正在测试的PC都在原始模式下设置为115200 bps,具有8个数据位,没有奇偶校验和1个停止位,并且在测试期间两个设备的电源保持连接所以我不能责怪缺乏权力。
我可以对此代码做些什么来改进它,以便所有文本都可以正确输出?
TXBUFS equ 30h
RXBUFS equ 40h
TXOP bit 7Dh
RXOP bit 7Ch
org 0h
ljmp main
org 23h ;serial INT
push PSW
setb RS0 ;all serial functions use bank 1.
jbc RI,rxdf
jbc TI,txdf
exitint:
clr RS0
pop PSW
reti
main:
mov SP,#52h
lcall serialinit
ljmp startdebug
;Serial port receive function
;Receiver controls R1 value unless we want to reset local buffer
rxdf:
cjne R1,#RXBUFS+17,noerx
clr RXOP
ajmp exitint
noerx:
mov @R1,SBUF
inc R1
ajmp exitint
;Serial port transmit function
txdf:
cjne R0,#TXBUFS+17,noetx
clr TXOP
ajmp exitint
noetx:
mov SBUF,@R0
inc R0
ajmp exitint
;enable receive
startrx:
setb RS0
mov R1,#RXBUFS
setb RXOP
clr RS0
ret
;Reset receiver stack
resetget:
setb RS0
mov R0,#RXBUFS+17
clr RS0
ret
;Get byte as A from receiver stack.
getrx:
setb RS0
dec R0
mov A,@R0
clr RS0
ret
;Reset our stack pointer (to zero bytes on transmitter stack)
resetadd:
setb RS0
mov R0,#TXBUFS+17
clr RS0
ret
;Add byte from A onto our transmitter stack. C=1 if end of stack reached
addtx:
setb RS0
dec R0
mov @R0,A
cjne R0,#TXBUFS,notxendp
setb C
inc R0
clr RS0
ret
notxendp:
clr C
clr RS0
ret
;send data
starttx:
setb TXOP ;set transmit busy flag
setb RS0
mov SBUF,@R0 ;send 1st byte right away to trigger interrupt later
inc R0
clr RS0
ret
;serial init
serialinit:
mov TH1,#0FFh ;speed=115kbps
mov TL1,TH1
mov PCON,#80h
mov SCON,#50h
mov TMOD,#22h ;auto reload for timers
setb RS0
mov R0,#TXBUFS+17 ;setup our pointers.
mov R1,#RXBUFS
clr RS0
setb TR1
setb ES
setb EA ;enable interrupts
ret
startdebug:
mov DPTR,#mmenu ;load text
lcall dprint ;and print it (not working correctly)
sjmp $
;print what's in ROM
dprint:
lcall resetadd ;reset transmitter pointer
dprint2:
clr A
movc A,@A+DPTR
inc DPTR
jz dexitp ;exit function if character from local ROM is 0h
lcall addtx ;send byte to transmitter
jnc nostall
;at this point, we made buffer full so do 16-byte transmission
lcall starttx
;and stall until all 16 bytes are transmitted
txst:
nop
jb TXOP,txst
;reset transmitter pointer again for next 16 bytes
lcall resetadd
nostall:
sjmp dprint2
dexitp:
;do one more round of transmission for remaining characters in transmit buffer
lcall starttx
;and stall again
txst2:
nop
jb TXOP,txst2
;and reset
lcall resetadd
ret
mmenu:
db 'Central station Debug Mode',0Dh,0Ah,0Dh,0Ah
db 'Testing 115200bps speed mode with 16 byte chunks',0Dh,0Ah
db '12345678901234567890123456789012345678901234567890123456789012345678901234567890',0Dh,0Ah
db '80x25 screen?',0Dh,0Ah
db 'uC to Linux screen test',0Dh,0Ah
db 'Working? Yes? Maybe? No?',0Dh,0Ah
db 'Test 100% wireless. 115200bps speed',0Dh,0Ah,0Dh,0Ah
db 'TEST IS NOW FINISHED!',0Dh,0Ah
db 'TX TEST OVER WAITING FOR RECEPTION!',0Dh,0Ah,00h