??? 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 |