Jon Wilder
Active Member
I just wrote a bit bang serial routine for MIDI and was wondering if someone could look it over as this is my first time coding any sort of bit bang routine -
Any and all suggestions would be greatly appreciated.
EDIT: On an interesting note I tried simulating this in MPLAB and for some reason it will not skip the next instruction upon bit 1 of TMR0 being set at the "btfss TMR0,1" instruction. Does anyone know why this is?
Code:
#define RX PORTB,1
#define TX PORTB,2
TX_REG EQU 0x0C
RC_REG EQU 0x0D
bitcounter EQU 0x0E
;8 MHz crystal oscillator. Timer 0 set for prescaler of 1:32. TMR0 bit 0 is incremented every 16uS
;while TMR0 bit 1 is incremented every 32uS. TMR0 bit 2 is polled for baud rate of 31,250.
;Data is transmitted and received LSB first with 1 start bit and 1 stop bit.
;***********************************************************************************************************
;MIDI Transmit
;***********************************************************************************************************
TRANSMIT movlw 0x08
movwf bitcounter ;set bit counter to count 8 bits to be transmitted
TX_start btfss INTCON,T0IF ;wait for timer to reset
goto TX_start
bcf TX ;send start bit
TX_bit btfss TX_REG,0 ;see if bit 0 in TXREG is high or low
goto TX_low ;send low bit if low
goto TX_high ;send high bit if high
TX_low btfss TMR0,1 ;wait for baud
goto TX_low
bcf TX ;send low bit
goto TX_shift
TX_high btfss TMR0,1 ;wait for baud
goto TX_high
bsf TX ;send high bit
goto TX_shift
TX_shift rrf TX_REG,F ;shift bits in transmit register
decfsz bitcounter,F ;decriment bit counter, branch if 0
goto TX_bit
goto TX_stop ;proceed to send stop bit
TX_stop btfss TMR0,1 ;wait for baud
goto TX_stop
bsf TX ;send stop bit
return
;***********************************************************************************************************
;MIDI Receive
;***********************************************************************************************************
RECEIVE movlw 0x08
movwf bitcounter ;set bit counter to count 8 bits to be recieved
RX_start btfsc RX ;wait for start bit rising edge
goto RX_start
clrf TMR0 ;reset timer 0
movlw b'00000100' ;set timer 0 prescaler for 1:32
option
bitcenter btfss TMR0,0 ;wait additional 16uS for bit center
goto bitcenter
btfsc RX ;recheck start bit, return if not start bit
return
RX_bit btfss TMR0,1 ;wait for baud
goto RX_bit
btfss RX ;see if bit on RX is high or low
goto RX_low ;receive low bit if low
goto RX_high ;receive high bit if high
RX_low bcf RC_REG,7 ;set bit 7 in receive register
goto RX_shift
RX_high bsf RC_REG,7 ;clear bit 7 in receive register
goto RX_shift
RX_shift rrf RC_REG,F ;shift bits in RCREG register
decfsz bitcounter,F ;decriment bit counter, branch if 0
goto RX_bit ;receive next bit
goto RX_stop ;receive stop bit
RX_stop btfss TMR0,1 ;wait for baud
goto RX_stop
stop_w8 btfss rx ;check for stop bit
goto frame_error ;return if stop bit received
return
Any and all suggestions would be greatly appreciated.
EDIT: On an interesting note I tried simulating this in MPLAB and for some reason it will not skip the next instruction upon bit 1 of TMR0 being set at the "btfss TMR0,1" instruction. Does anyone know why this is?
Last edited: