Search code examples
assemblypicusart

RCIF Flag Not Setting


I am trying to send data between two PIC16F690's and am having trouble. The TX pin of one of the PICs is connected to the RX pin of the other and the TX pin of that PIC is connected to an HC05 Bluetooth Transmitter. The data that is being sent to the receiving PIC must also then be displayed on a set of common cathode seven segment displays.

Currently my code works for the transmitting PIC and I have checked this using the HC05 on that PIC. The issue is that the data is only "received" a single time on the Receiving PIC and the PIC (according to the outputs) says that the data's value was 0.

This was tested sending the decimal value 7 from the one PIC to the other continuously, hence CREN was used, but the RCIF flag only gets set once.After that it remains clear and at no point was the value 7 found in RCREG.

I've been on this issue now for 3 days and its driving me crazy, any help would be greatly appreciated.

In terms of setup code for the receiving PIC:

MOVLW B'00100000' 
MOVWF TRISB ;Setup PORTB with inputs for the RCIF

BSF OPTION_REG,PS0 ;Allow for Timer0 and Pull up resistors
BCF OPTION_REG,PSA
BCF OPTION_REG,7    ;Enable Pullups


;For data sending
CLRF PIE1    
BCF    TXSTA,TX9    ;Sends 8 bits when transmitting
BSF    TXSTA,TXEN    ;Enable the transmit function
BCF    TXSTA,SYNC    ;Working in Asynchronous Mode
BSF    TXSTA,BRGH    ;Enable the high baud rate generator

MOVLW   B'11001'    ;Calculated using (FOSC/BAUD*16)-1 (Assumed FOSC was 4M)  
MOVWF   SPBRG

BCF   STATUS,RP0

BSF    RCSTA,SPEN ;Enable serial pins at RB7 and RB5
BCF    RCSTA,RX9
BCF    RCSTA,SREN  ;In UART mode, doesnt care
BSF    RCSTA,CREN ;Constant Reception

BCF    RCSTA,FERR ;Framing error bit
BCF    RCSTA,RX9D ;Disable checking for 9th bit

MOVFW   RCREG ;Clears receiving register to clear RCIF

CLRF    TXREG

BCF PIE1,TMR2IE             ;Disable Timer2
BSF PIE1,RCIE               ;Permanently enabled

BSF INTCON, T0IE ;Enable Timer Interrupt
BSF INTCON, PEIE ;Enable the peripheral interrupt  variable
BSF INTCON, GIE ;Enable the Global Interrupt variable

Then in terms of the sending data:

BANKSEL PORTB
MOVLW   B'00110000' ;30 in HEX equals 0 in ASCII
ADDWF   UNITS,W
CALL    SEND_DATA
RETURN

SEND_DATA:
TX_WAIT: 
BTFSS   PIR1,TXIF
GOTO   TX_WAIT 
MOVWF   TXREG        ;load data to be sent...

RETURN

In terms of receiving data:

GET_DATA:
MOVFW   RCREG
MOVWF   UNITS
CALL    TRANSMIT
RETURN

In terms of interrupts: INTER_PORTS: ;Interrupt Routine

BTFSC INTCON,T0IF ;If timer overflow bit set, go to timer interrupt
CALL INTER_TOVF

BTFSC   PIR1,RCIF
CALL    GET_DATA

RETFIE

The timer is for updating the seven segment displays.

I attempted to add code for clearing the OERR and FERR errors, but that didnt help, I had originally put them under the GET_DATA heading, the code was as follows:

OVF_ERROR:
BCF     RCSTA,CREN   
MOVFW    RCREG 
MOVFW    RCREG
BSF     RCSTA,CREN
RETURN

FERR_ERROR:
MOVFW    RCREG
BTFSC    RCSTA,FERR
GOTO        FERR_ERROR 
RETURN

Thank you for any guidance, this has been a headache, if I can provide any clarity on the code used, I will. The sending function on the other PIC is the same as this one, with the same BAUD rate of 9600.


Solution

  • The code fragments you have posted do not show proper use of bank selects when reading or writing the Special Function Registers in the PIC16F690.

    Incorrect bank selections appear to be the issue with your code but it is impossible to be sure without looking at the entire project. (Please do not post your complete code and ask for a review)

    To know which bank a Special Function Register is in see this page in the PIC16F690 data sheet:

    PIC16F690 SFR banks