?? serialbuf.bas
字號:
'------------------------------------------------------
' SERIALBUF.BAS
' (c) 2001 MCS Electronics
' This program shows how to implement a serial input
' buffer
'------------------------------------------------------
'we use conditional compilation for the optional spi int
Const Spi = 1
'first we tell the compiler about our routines
$serialoutput = Sendchar
$serialinput = Recchar
'now we need some variables to store the input and some pointers
'buf() is an array that holds the data
'wpos is a pointer that points to the last position written
'rpos is a pointer that points to the last read position
'rcount is a byte that stores the number of bytes waiting in the buffer
Dim Buf(10) As Iram Byte , Wpos As Iram Byte , Rpos As Iram Byte , Rcount As Iram Byte
'now we specify the ISR
On Serial Isr_ser Nosave
'we must enable it
Enable Serial
'and enable the global interrupt bit
Enable Interrupts
'since by default the compiler will generate mov scon,#82 to enable TI,
'we override it so TI is not enabled
mov scon,#80
'This is our actual program
'we need a byte to store a value
Dim A As Byte
'we print some text to show that we can print
Print "Hello"
Print "world"
'here we ask for the number
Do
Input "Number " , A
'here we print the entered number
Print A
Loop Until A = 0
End
'we use some asm
$asm
Sendchar:
' we could disable the serial interrupts here but it would mean
' that no receive interrupt could occur too
Mov sbuf, a ; write the data
Jnb scon.1, *+0 ; wait until it is ready
Clr scon.1
; Disable Ti
Ret
' That Was Easy
Recchar:
mov a,{rcount} ; get the number of bytes waiting in the buffer
jz recchar ; when zero try again
push h'00 ; now we must save the used registers
push psw
mov r0,#{buf} ; load the address of the buffer
mov a,{rpos} ; load the last read position
add a,r0 ; add it
mov r0,a ; put back in r0
mov a,@r0 ; get it out of the buffer
inc {rpos} ; increase the read pointer
dec {rcount} ; 1 char less waiting
push acc ; save the byte we retrieved from the buffer
mov a,{rpos} ; get the read pos
cjne a,#10, recchar_exit ; is it past the size of the buffer
mov {rpos},#0 ; reset it to the begin
Recchar_exit:
pop acc ; restore byte
pop psw ; restore registers
pop h'00
ret ; return
$end Asm
'this is the ISR that gets fired when TI or RI gets set
Isr_ser:
push acc
push h'00 ; save used registers
push psw
jnb scon.0, .isr_tx ; was RI causing the interrupt?
mov a,{wpos} ; get write position
mov r0,#{buf} ; load address of buffer
add a,r0 ; add it
mov r0,a ; back to r0
mov @r0,sbuf ; store the char in the buffer
inc {wpos} ; increase write pointer
inc {rcount} ; and we have one char more waiting
clr scon.0 ; clear RI
mov a ,{wpos} ;get the write pointer
cjne a,#10,.isr_exit ;is it past the size?
Mov {wpos},#0 ; reset it
sjmp .isr_exit ;exit
Isr_tx:
' TI Caused The Int But It Gets Reset In The Sendchar Routine
'optional for the 8252 that has a shared SPI interrupt you can add the following code
#if Spi
mov a,spsr ; get status register
jnb acc.7, .isr_exit ; it was not the SPI that caused the int
mov spsr,#255 ; to clear the int flag spif and wcol must be set
mov a,spdr ; by reading the data register the int gets cleared
'now we can store the data this is not implemented
'note that acc gets popped so acc will be destroyed
#endif
Isr_exit:
pop psw ; restore regs
pop h'00
pop acc
Return
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -