How to receive multiple bytes using the hardware usart in the PIC18F2550


Closed Thread
Results 1 to 7 of 7
  1. #1
    Join Date
    Jan 2006
    Location
    Toronto
    Posts
    109

    Default How to receive multiple bytes using the hardware usart in the PIC18F2550

    Hi all,

    I am trying to setup a RF connection between a PC and a PIC using the MaxStream ZigBee modules. If i send a single byte from the PC to the PIC everything is ok but how do I send more then one?

    I am using hardware interrupts for the USART and the USART itself only has a 1 byte buffer.

    I need a way to capture 10 bytes with the PIC into a buffer array and then process it afterwards.
    Last edited by PJALM; - 3rd July 2007 at 19:57.

  2. #2
    skimask's Avatar
    skimask Guest

    Default

    Quote Originally Posted by PJALM View Post
    Hi all,

    I am trying to setup a RF connection between a PC and a PIC using the MaxStream ZigBee modules. If i send a single byte from the PC to the PIC everything is ok but how do I send more then one?

    I am using hardware interrupts for the USART and the USART itself only has a 1 byte buffer.

    I need a way to capture 10 bytes with the PIC into a buffer array and then process it afterwards.
    HSERIN uses the hardware UART, but uses it in a way that's more like the bit-banged method of SERIN. Use the STR modifier to get 10 bytes into an array.

  3. #3
    Join Date
    Jan 2006
    Location
    Toronto
    Posts
    109

    Default

    Thanks for the advise but at the time of interrupt there is only one byte to get because the buffer is only one byte in size.

    I need a way to capture the data one byte at a time and put each byte into the array as it arrives. This means I need to track which byte I am on and know when to start capturing and when to stop.

    I will put up some sample code I made to give you an idea of what I am trying to achieve.

  4. #4
    Join Date
    Jan 2006
    Location
    Toronto
    Posts
    109

    Default

    Ok here is a snippet from the code i am working on.

    Maybe this will trigger some ideas.

    Code:
    DEFINE  OSC 48
    DEFINE  LOADER_USED 1       
    DEFINE  RESET_ORG       800h           ' For Microchip USB Bootloader
    DEFINE  INTERRUPT_ORG   808h           ' For Microchip USB Bootloader
    
    
    '-------------------------------------------------------------------------------
    ' System Settings
    '-------------------------------------------------------------------------------
    ADCON1 = 15                            ' Set all I/Os to Digital
    INTCON2.7 = 1                          ' Disable PortB Pullups         
    CMCON = 7                              ' Disable Comparators
    
    My_Address           VAR BYTE
    i                    VAR BYTE
    ii                   VAR WORD
    
    i = 0
    ii = 0
    
    My_Address = 0
    '-------------------------------------------------------------------------------
    
    
    
    '-------------------------------------------------------------------------------
    ' RF Settings
    '-------------------------------------------------------------------------------
    DEFINE  HSER_BAUD       9600
    DEFINE  HSER_RCSTA      90h
    DEFINE  HSER_TXSTA      20h
    'DEFINE  HSER_SPBRG      25
    DEFINE  HSER_CLROERR    1
    
    RF_ACK               CON $01        ' Expected acknowledge char from RS-485
    RF_STX               CON $02        ' Start of Transmission Byte
    RF_ETX               CON $03        ' End of Transmission Byte
    RF_POS               CON $04
                            
    RF_To_Address        VAR BYTE
    RF_From_Address      VAR BYTE
    RF_Command           VAR BYTE
    RF_Parameter         VAR WORD
    RF_Data              VAR BYTE
    RF_Buffer            VAR BYTE[7]
    RF_Bytes_Sent        VAR BYTE
    RF_Bytes_Received    VAR BYTE
    RF_Sending_Data      VAR BIT
    RF_Receiving_Data    VAR BIT
    RF_Send              VAR BIT
    RF_ACK_Received      VAR BIT
    RF_PPP_Received      VAR BIT
    RF_POS_Received      VAR BIT
    RF_B0                VAR BYTE
    RF_B1                VAR BYTE
    
    RF_To_Address = 0
    RF_From_Address = 0
    RF_Command = 0
    RF_Parameter = 0
    RF_Send = 0
    RF_Bytes_Received = 0
    RF_Receiving_Data = 0
    RF_ACK_Received = 0
    RF_PPP_Received = 0
    RF_POS_Received = 0
    RF_B0 = 0
    RF_B1 = 0
    '-------------------------------------------------------------------------------
    
    
    
    '-------------------------------------------------------------------------------
    ' Interrupt Settings
    '-------------------------------------------------------------------------------
    INTCON.6 = 1			' Enable Peripheral Interrupts
    INTCON.7 = 1			' Enable Global Interrupt Handler
    PIE1.4 = 0              ' Disable USART Transmit Interrupt
    PIE1.5 = 1              ' Enable USART Receive Interrupt
    '-------------------------------------------------------------------------------
    
    
    PAUSE 500
    
    My_Address = 18
    
    ON INTERRUPT GOTO Main_Interrupt_Handler
    ENABLE INTERRUPT
    
    
    
    '-------------------------------------------------------------------------------
    ' Main Program Loop
    '-------------------------------------------------------------------------------
    MainLoop:
        GOSUB Get_My_Address
    
        'IF RF_Receiving_Data = 0 THEN
        '    IF RF_Command != 0 THEN
        '        IF RF_To_Address = My_Address THEN
        '            GOSUB RF_Process_Command
        '        ENDIF
        '    ENDIF
        'ENDIF
        
        PAUSE 50
        
        GOTO MainLoop
    '-------------------------------------------------------------------------------
     
    
    
    
    
    '-------------------------------------------------------------------------------
    ' Send RF data
    '-------------------------------------------------------------------------------
    RF_Send_Data:
        RF_From_Address = My_Address
    
        RF_Ack_Received = 0
        RF_PPP_Received = 0
        
        RF_Buffer(1) = RF_STX                      'Start
        RF_Buffer(2) = RF_To_Address + 4           'To Address
        RF_Buffer(3) = RF_Command                  'Command
        RF_Buffer(4) = RF_Parameter.HighByte + 4   'Parameter High Byte
        RF_Buffer(5) = RF_Parameter.lowbyte + 4    'Parameter Low Byte
        RF_Buffer(6) = RF_From_Address + 4         'From Address
        RF_Buffer(7) = RF_ETX                      'End
    
        FOR i = 1 TO 25
            PAUSE 10
        NEXT
    
        FOR i = 1 to 7
            RF_Data = RF_Buffer(i)
            HSEROUT [RF_Data]                      'Send the Data Byte
            PAUSE 25
        NEXT
        
        FOR i = 1 TO 25
            PAUSE 10
        NEXT
    
        FOR i = 1 TO 7
            RF_Buffer(i) = 0
        NEXT
    
        RF_To_Address = 0
        RF_From_Address = 0
        RF_Command = 0
        RF_Parameter = 0
        
        RETURN
    '-------------------------------------------------------------------------------
    
    
    
    '-------------------------------------------------------------------------------
    ' Interrupt Handler
    '-------------------------------------------------------------------------------
        DISABLE INTERRUPT                        ' No interrupts past this point
    Main_Interrupt_Handler:
    
        '---------------------------------------------------------------------------
        ' USART Receive Interrupt
        '---------------------------------------------------------------------------
        IF PIR1.5 = 1 THEN
            PAUSE 50
            
            HSERIN [RF_B0]
    
            SELECT CASE RF_B0
                CASE RF_STX
                    RF_Bytes_Received = 1
                    RF_Receiving_Data = 1
                    RF_Bytes_Received = 0
    
                    FOR i = 2 TO 7
                        RF_Buffer[i] = 0
                    NEXT
    
                    RF_Bytes_Received = RF_Bytes_Received + 1
                    RF_Buffer(RF_Bytes_Received) = RF_B0
                    
                CASE RF_ETX
                    RF_Bytes_Received = RS485_Bytes_Received + 1
                    RF_Buffer(RF_Bytes_Received) = RF_B0
    
                    RF_Receiving_Data = 0
                    
                    RF_To_Address = RF_Buffer(2) - 4
                    RF_Command = RF_Buffer(3) - 4
                    RF_Parameter.HighByte = RF_Buffer(4) - 4
                    RF_Parameter.LowByte = RF_Buffer(5) - 4
                    RF_From_Address = RF_Buffer(6) - 4
                    
                CASE ELSE
                    IF RF_Receiving_Data = 1 THEN
                        RF_Bytes_Received = RF_Bytes_Received + 1
                        RF_Buffer(RF_Bytes_Received) = RF_B0
                    ENDIF
            END SELECT
            PIR1.5 = 0
        ENDIF
        '---------------------------------------------------------------------------
    
    
    
        '---------------------------------------------------------------------------
        ' USB Interrupt
        '---------------------------------------------------------------------------
    	IF PIR2.5 = 1 THEN
            DEBUG 13, 10, "[ INTERRUPT ] USB Interrupt", 13, 10
            PIR2.5 = 0
        ENDIF
        '---------------------------------------------------------------------------
    
            
    IntDone:
        RESUME					' Return to main program
        ENABLE INTERRUPT
    '-------------------------------------------------------------------------------
    
    	END

  5. #5
    Join Date
    Jan 2006
    Location
    Toronto
    Posts
    109

    Default

    Has anyone had any luck with this code yet or hav any sugestions?

  6. #6
    Join Date
    Jan 2006
    Location
    Toronto
    Posts
    109

    Default

    Has anyone at all had any experience with this? I still cannot successfully receive more then 1 byte without problems. ANy help at all would be greatly apreciated.

    Thanks

  7. #7
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default

    When using ON INTERRUPT the interrupts don't get handled until the currently executing PBP statement has finished.

    At 9600 baud it only takes 1.04ms per byte. With the USARTS 2 byte buffer, the longest that any statement can take is 2.08ms. Anything taking longer will cause the buffer to overflow. Then with [DEFINE HSER_CLROERR 1] the program never even knows it lost data.

    With PAUSE 50 in the MainLoop, you could easily loose 15-20 bytes at a time.

    If you were using ASM interrupts, that wouldn't be a problem.

    HTH,
    DT

Similar Threads

  1. rs232 with hardware USART
    By Smity42 in forum mel PIC BASIC Pro
    Replies: 16
    Last Post: - 28th April 2011, 03:51
  2. How to receive stream of bytes using PIC USART
    By unifoxz in forum mel PIC BASIC Pro
    Replies: 34
    Last Post: - 20th June 2009, 10:38
  3. Benefits of hardware usart over software?
    By sccoupe in forum Serial
    Replies: 2
    Last Post: - 19th March 2009, 01:16
  4. Serin/Out for multiple bytes
    By mankan in forum General
    Replies: 1
    Last Post: - 5th June 2006, 19:58
  5. receive ASCII with usart
    By harryweb in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 9th February 2004, 08:57

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts