16f886 UART woes :-(

Thread Starter

Torbek

Joined Apr 19, 2019
19
ok this is simple, I will have a 'packets' of 16 bytes sent over uart @9600 baud, then a gap of about 4mS will indicate the start of a new packet.

I am trying to detect said gap between packets with a small loop involving TMR0, a file that decrements, and PIR1,RCIF. For some reason, I am struggling, not to detect the gap, but actually for the pic to acknowledge within the loop, any reception of serial data at all.

So you might ask if I have set UART Rx up properly. Well, I think so. To test this, I have put the following line above my bit of looped code to ensure I have set the port up correctly:

Code:
    btfss    PIR1,RCIF    ;Any data recieved?
    goto    $-1
    movf    RCREG,w        ;TEST
    call    ERCHK ;tests for overrun and framing
So yes we do get past the point above, and if it demonstrates anything at all, it should be true that the routine below loops back to 'WaitDTA' to reset the timing loop.

Extra info, baud is correct, I am not getting frame or other error, and I moved to 20Mhz external xtal to eliminate errors but at 9600 really?

I hope this makes some sort of sense, the code is below.

Code:
    btfss    PIR1,RCIF    ;Any data recieved?
    goto    $-1
    movf    RCREG,w        ;TEST
    call    ERCHK

    call    DLY500mS

WaitDTA:
    movf    RCREG,w
    call    ERCHK
    banksel    PORTA
    bcf        PORTC,RED
    bcf        PORTC,GRN
    clrf    flgs        ;???
    movlw    d'146'        ;Confirmed 15mS (1/8x10^6)/4/256/2/60
    movwf    TMR0CNT        ;Our tmr1 count variable
    clrf    TMR0  
    bcf    INTCON,T0IF
    movf    RCREG,w
    call    ERCHK
   
    btfsc    flgs,7
    goto    Uerror
    btfsc    flgs,6
    goto    Uerror
   
    bsf        PORTC,RED
    bcf        PORTC,GRN  

TMRLP:
    btfss    INTCON,T0IF        ;every 250uS we will test TMR1, and hence check for comms
    goto    $-1
    bcf    INTCON,T0IF
    decfsz    TMR0CNT,f
    goto    TMRLP
    btfsc    PIR1,RCIF    ;Any data recieved?
    goto    WaitDTA        ;Back round to next 250uS poll

    bsf        PORTC,RED
    bsf        PORTC,GRN    ;<<< ROUTINE GETS HERE despite it breaking the 15mS timer!!!
And below you can see the data out (for this test I have removed the gaps so that there is no break in data) along with the 15mS gap highlighted, where just the red LED (D2) is illuminated, then we get to the point where the red & green LED's are illuminated (D2&3). D0 is the serial data on RC7/RX/DT pin.

You can see there are at least 3 instances of serial data that should result in the code going back to 'WaitDTA'..?

1580921279722.png

This is driving me mad and I suspect it will be something stupid!
 

JohnInTX

Joined Jun 26, 2012
4,007
btfss PIR1,RCIF ;Any data recieved?
goto $-1
movf RCREG,w ;TEST
call ERCHK

call DLY500mS

You delay 500ms after the error check. On the next character(s), during the delay, you will set OERR because you did not process additional characters coming in. After that, RCIF will never be set.

There are probably more issues but that one jumped out.

If you are going to look for a 4ms gap, I would recommend using an interrupt-driven buffer that receives characters without having to poll for them nor run the risk of missing something with your other waits on timers. Just receive the characters, stuff them into a FIFO buffer and reset a 4ms timer. On interrupt, if RCIF, you have another character to buffer. If timeout, there's your gap - signal the main routine to process the buffer full of characters.

Anytime you delay during async receive, you are asking for trouble.

Good luck!
 

MrChips

Joined Oct 2, 2009
20,859
It is better to send a unique character to indicate the start of the data frame rather than trying to detect a gap in transmission.
 

Thread Starter

Torbek

Joined Apr 19, 2019
19
btfss PIR1,RCIF ;Any data recieved?
goto $-1
movf RCREG,w ;TEST
call ERCHK

call DLY500mS

You delay 500ms after the error check. On the next character(s), during the delay, you will set OERR because you did not process additional characters coming in. After that, RCIF will never be set.

There are probably more issues but that one jumped out.

If you are going to look for a 4ms gap, I would recommend using an interrupt-driven buffer that receives characters without having to poll for them nor run the risk of missing something with your other waits on timers. Just receive the characters, stuff them into a FIFO buffer and reset a 4ms timer. On interrupt, if RCIF, you have another character to buffer. If timeout, there's your gap - signal the main routine to process the buffer full of characters.

Anytime you delay during async receive, you are asking for trouble.

Good luck!
Ah yeah did not see that. Something that MPLAB does not simulate... Now I wonder why I did not get an O/run error... I will have a play tomorrow and see what happens but I suspect you are correct.
 

Thread Starter

Torbek

Joined Apr 19, 2019
19
It is better to send a unique character to indicate the start of the data frame rather than trying to detect a gap in transmission.
Yes I have previously taken this approach however I want to relay LED's from a panel elsewhere in real-time with minimum delay. I would rather not have to compress each value into bytes. Instead, just sending 8 bits of info then inverting a second byte as a very crude check.
 

Beau Schwabe

Joined Nov 7, 2019
48
How are you sending the data? ... Could it be a Receive overrun error?

pg 159 of the datasheet:
http://ww1.microchip.com/downloads/en/devicedoc/41291f.pdf

"12.1.2.5 Receive Overrun Error
The receive FIFO buffer can hold two characters. Anoverrun error will be generated If a third character, in itsentirety, is received before the FIFO is accessed. Whenthis happens the OERR bit of the RCSTA register is set.The characters already in the FIFO buffer can be readbut no additional characters will be received until theerror is cleared. The error must be cleared by eitherclearing the CREN bit of the RCSTA register or byresetting the EUSART by clearing the SPEN bit of theRCSTA register. "
 

jpanhalt

Joined Jan 18, 2008
9,043
Have you looked into using a script to simulate USART? It will certainly simulate USART in hardware.

It's been awhile (more than 2 years) but MPLab SIM shows for the 16F886 this:
1580940056249.png
 
Last edited:
Top