| ??? 06/08/07 13:56 Read: times |
#140418 - weekend quiz - topic: interrupts |
They say interrupts are hard. Let's prove the opposite in this weekend's quiz.
I prepared an example, similar to the "Line Editor" we quized about the last time; but this one is interrupt based. This time, it is flawless. Or not?... Enjoy! JW PS: Those for whom this is too easy, can you please wait at least until Saturday 1200GMT to give chance for the others...
;This is an example of interrupt-driven serial reception
;The interrupt receives a byte, places it into the buffer (if there is space in it)
;DEL is not implemented here - non-printable characters are simply all discarded
; except ENTER (CR), which terminates the reception, sets RxDoneFlag
; and sets the number of received characters into the first byte of buffer (Pascal-style)
;Received characters are echoed immediately, therefore the transmission
; interrupt is ignored.
RxDoneFlag EQU 20h.0
RxBuff EQU 30h ;this is the receiver buffer
RxSize EQU 16 ;we will accept max. 16 characters
ORG 0
ljmp Reset
ORG 23h
ljmp ISR_UART
Reset: ;after reset, start here
lcall Init_UART ;initialize UART
setb es ;enable serial interrupt
setb ea ;enable interrupts globally
Main:
lcall RxString
;some processing here
sjmp Main
RxString: ;the string receiver routine
clr RxDoneFlag ;basically everything is left to the interrupt
jnb RxDoneFlag,$ ; which sets RxDoneFlag when done
ret
Init_UART: ;initialize UART
mov SCON,#50h ;set serial mode 1
mov TMOD,#22h ;both timers autoreload
mov TH1,#-13 ;2400@12MHz
setb tr1 ;start timer 1
ret
ISR_UART: ;UART interrupt
push psw ;store registers
push acc
setb RS0 ;and switch to register bank 1
jnb ri,ISR_UART_TI ;if no RI flag set, bypass the RI part
clr ri ;if RI set, we need to clear it manually
mov a,SBUF ;pick the received byte
cjne a,#13,ISR_UART_RxNotCR
setb RxDoneFlag ;if CR, set the done flag
mov a,#RxBuff ; and calculate length
clr c
xch a,r0
subb a,r0
mov @r0,a ; store it at beginning of buffer
sjmp ISR_UART_Echo ; and leave, echoing back the CR
ISR_UART_RxNotCR:
jb acc.7,ISR_UART_TI ;ignore >80h
cjne a,#20h,$+3
jc ISR_UART_TI ;ignore <20h
cjne r0,#RxBuff+RxSize,ISR_UART_Store
sjmp ISR_UART_TI ;ignore if buffer full
ISR_UART_Store:
inc r0 ;next position in buffer
mov @r0,a ;store the character
ISR_UART_Echo:
mov SBUF,a ;echo back the character
;and we are finished with Rx - fallthrough to Tx
ISR_UART_TI:
jnb ti,ISR_UART_END ;check and clear TI flag
clr ti
;we have no more Tx processing here
ISR_UART_END:
pop acc ;restore registers
pop psw
reti
end
|
| Topic | Author | Date |
| weekend quiz - topic: interrupts | 01/01/70 00:00 | |
| I spot two things wrong. | 01/01/70 00:00 | |
| Three, maybe four | 01/01/70 00:00 | |
| 3?... 4??? | 01/01/70 00:00 | |
| 3 or 4, yes | 01/01/70 00:00 | |
| Details, details, details | 01/01/70 00:00 | |
| A- | 01/01/70 00:00 | |
| Yes, I do know the trick. | 01/01/70 00:00 | |
| OK, A+, then. | 01/01/70 00:00 | |
K&R is for weenies | 01/01/70 00:00 |



