I'm trying to re-create a hardware serial port with pure software. I need a non-blocking RECEIVE port because I need to add a 3rd port to my 8723.
Most of the interrupt-driven routines I have seen have a very large processor overhead because they sample all the time and because they sample often so as to get the bit timing right.
I'm trying an approach that uses INT0. It watches for the first falling edge of the START bit, then starts a TMR4 interrupt to time the rest of the bits. Using this approach should use zero processing power when a byte isn't coming in, and not too many cycles when one is. INT0 is turned on only to detect the falling edge of the START bit. TMR4 int is turned on only when receiving bits.
The trouble is - the following code always returns 0xff whenever I send it a character. Can someone tell me what I'm doing wrong? RxD is coming through a MAX232 and is fed to PORTB.0
Code:T4CON = %00000110 ; T4 ON, /16 prescale, no postscalers INTCON = %11000000 ; Global Int enable, peripheral INT enable INTCON2 = %00000000 PIE3.3 = 0 ;Turn off Int on tmr 4 IPR3.3 =1 ; High priority for INT4 bit_cntr VAR BYTE rcv_byte VAR BYTE byteready VAR BYTE rcv_buffer VAR BYTE ;----------------------------------------------------------------------- INCLUDE "DT_INTS-18.bas" ; Base Interrupt System ASM INT_LIST macro ; IntSource, Label, Type, ResetFlag? INT_Handler INT0_INT, GetStart, ASM, no INT_Handler TMR4_INT, BitTimer, ASM, no endm INT_CREATE ; Creates the interrupt processor ENDASM Goto OverInt '---[INT - interrupt handler]--------------------------------------------------- ASM GetStart bcf T4CON,2 ; Turn off Timer 4 movlw 0x97 ; w /16 prescaler gives 156uSec dly @ 40Mhz = 1.5 bit times movwf TMR4 bsf T4CON,2 ; Turn timer 4 on bsf PIE3,3 ; turn on the Timer4 INT movlw 0x08 ; load the bit counter movwf _bit_cntr bcf INTCON,4 ; shut off the INT0 interrupt bcf INTCON,1 ; clear INT0 int flag bit INT_RETURN ENDASM ASM BitTimer bcf T4CON,2 ; Turn Timer4 off movlw 0xBF ; 104uSec / 16, 40 Mhz 1 bit time movwf TMR4 ; load it bsf T4CON,2 ; Turn it back on btfss PORTB,0 ; check status of portB.0 bcf STATUS,C ; move bit into carry btfsc PORTB,0 ; check status of portb.0 bsf STATUS,C ; move bit into carry rrcf _rcv_byte,f ; shift carry into rec'd byte decfsz _bit_cntr,f ; decrement the bit counter bra Donebit ; get out and wait for next int bra Donebyte ; got 8 bits Donebit bcf PIR3,3 ; clear the int flag bsf PIE3,3 ; start the TMR4 int again INT_RETURN Donebyte movff _rcv_byte,_rcv_buffer movff _rcv_buffer,PORTD ; this is a debug, just to see rec'd byte on LEDS bcf PIR3,3 ; clear the int flag bsf INTCON,4 ; turn on the INT0 interrupt for next byte INT_RETURN ENDASM OVERINT: TRISD = 0 PORTD = 0 TRISE = 0 INTCON.1 = 0 PIE3.3 = 0 PIR3.3 = 0 PAUSE 100 @ INT_ENABLE INT0_INT WAITT: GOTO WAITT






Bookmarks