Here ya go ...
The 9-bit issue was due to flags not being cleared first before enabling.
I've changed it to put the bit periods in PR4 instead of TMR4, this eliminates the latencies without having to reload the timer.
Since I was using an 18F4520 (no TMR4), I made it so you can use any of the 8-bit timers that count up to PR?, TMR2, 4 or 6.
I've also changed several other things, so look carefully if you're trying to pick them out.
My debug method was sending the received byte out the USART, instead of PORTD.
Code:
DEFINE OSC 40
DEFINE RX_TMR 4 ; can be 2, 4 or 6
DEFINE TMR_INT TMR4_INT ; int must match timer selection
;RCSTA = $90 ' Enable serial port & continuous receive
;TXSTA = $20 ' Enable transmit, BRGH = 0
;SPBRG = 64 ' 9600 Baud @ 40MHz, 0.16%
bit_cntr VAR BYTE BANK0
rcv_byte VAR BYTE BANK0
byteready VAR BYTE BANK0
rcv_buffer VAR BYTE BANK0
;-----------------------------------------------------------------------
INCLUDE "DT_INTS-18.bas" ; Base Interrupt System
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT0_INT, GetStart, ASM, yes
INT_Handler TMR_INT, BitTimer, ASM, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
Goto OverInt
'---[INT - interrupt handler]---------------------------------------------------
ASM
#define TMR_VAL TMR#v(RX_TMR)
#define TMR_CON T#v(RX_TMR)CON
#define TMR_PR PR#v(RX_TMR)
ENDASM
ASM
GetStart
movlw 0x02 ; T? OFF, /16 prescale, no postscalers
movwf TMR_CON
movlw 0x61 ; 156uSec dly @ 40Mhz = 1.5 bit times
movwf TMR_PR
clrf TMR_VAL
bsf TMR_CON,2 ; Turn timer on
INT_ENABLE TMR_INT ; turn on the Timer INT
movlw 0x08 ; load the bit counter
movwf _bit_cntr
INT_DISABLE INT0_INT ; shut off the INT0 interrupt
INT_RETURN
ENDASM
ASM
BitTimer
movlw 0x41 ; load PR2 for 1 bit period
movwf TMR_PR
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
INT_RETURN
Donebyte
movff _rcv_byte,_rcv_buffer
;TXwait
; btfss PIR1, TXIF
; bra TXwait
; movff _rcv_buffer, TXREG
movff _rcv_buffer,PORTD ; this is a debug, just to see rec'd byte on LEDS
bcf TMR_CON,2
INT_DISABLE TMR_INT
INT_CLEAR INT0_INT
INT_ENABLE INT0_INT ; turn on the INT0 interrupt for next byte
INT_RETURN
ENDASM
OVERINT:
TRISD = 0
PORTD = 0
TRISE = 0
INTCON2.6 = 0 ; int0 on falling edge
PAUSE 100
@ INT_CLEAR INT0_INT
@ INT_ENABLE INT0_INT
WAITT:
GOTO WAITT
HTH,
Bookmarks