News:

;) This forum is the property of Proton software developers

Main Menu

Interrupt driven USART RX

Started by trastikata, Nov 25, 2021, 09:46 PM

Previous topic - Next topic

trastikata

Sometimes with high baud rates by the time you verify the preamble, you are already missing bits from the second byte. For that reason whenever I have to use 115200 baud with a preamble byte, I am writing interrupt driven code instead of the built-in commands.

Here's an example how I set-up hardware interrupt driven USART reception with a preamble and predetermined maximum message length for a GPS receiver at 115200 baud.

On_Interrupt GoTo Isr
GoTo Main

Isr:
    Context Save
   
    If OERR = 1 Then                                'Clear Overrun Error bit
        CREN = 0
        CREN = 1
    EndIf

    If RC1IF = 1 Then                               'Interrupt when a byte is received - USART RX Interrupt flag is set
        TempByte = RCREG1                           'Read the USART buffer to TempByte

        If TempByte = $A Or y > 84 Then             'If the end of message "$A" is found or the message exceeds the InBuffer size of 84 bytes
            If UsartRx = 1 Then                     'If "Ready to receive" bit is set           
                UsartRx = 0                         'Clear "Ready To Receive" Bit
                UsartRxReady = 1                    'And Set "Message Received/Message Read" bit
            EndIf
        EndIf

        If UsartRx = 1 Then                         'If "Ready To Receive" Bit is set
            InBuffer[y] = TempByte                  'Place the value of the received byte in the corresponding InBuffer position
            Inc y                                   'Increment the buffer position
        EndIf

        If TempByte = 36 And UsartRxReady = 0 Then  'If the preamble 36 is found and "Message Received/Message Read" Bit is cleared
            Clear InBuffer : y = 0                  'Reset InBuffer and buffer counter
            InBuffer[y] = TempByte                  'Start refilling the InBuffer
            UsartRx = 1                             'And "Ready to receive" Bit
            Inc y                                   'Increment the buffer counter from the first position
        EndIf

        RC1IF = 0                                   'Clear the USART RX interrupt flag
    EndIf

    Context Restore
   
Main:

'Do something and check frequently enough
'If the entire message has been received
'By verifying "Message Received" Bit
While 1 = 1
    'Loop and do something else
   
    If UsartRxReady = 1 Then
        GoSub DoSomething                           'Message Received and  go doing something with it
    EndIf
Wend   

DoSomething:
    'Do something with the message
     
    UsartRxReady = 0                                'Set the "Message Received/Message Read" bit allowing the interrupt       
Return
 

Basically in the Interrupt routine I start filling a message buffer as soon as a preamble byte is detected and as soon as an "end of message" is detected or the message exceeds the buffer size, I set a flag that the message has been received.

Then in the main program I pool that bit frequently enough (depending on timings) and when I see that the message has been received I do something, then I clear the bit and release the interrupt to reset the buffer and start refilling it. 

Hope this helps