Connect with us

PIC + RS485

Discussion in 'Electronic Design' started by simon, Oct 28, 2004.

  1. simon

    simon Guest

    Hello all, can anyone point me in the right direction please?

    I need to individually address 1 - 60 nodes up to 100 metres over a 485
    connection. The nodes must be addressable, should respond to 4 commands
    and in turn, each node must be able to pass back 4 data bits back to the
    master controller.

    I can handle the hardware OK. I'm after (hopefully PIC based) public
    domain code with error checking that can do what I need. The system
    needs to run up to 9600 bits/sec. Although I could attempt to write a
    program to do the above, time is running out on this one and my
    understanding of CRC is not that good. I need code that is robust, tried
    and tested.

    Can anyone advise please?

    Cheers,
    Simon
     
  2. Bob Stephens

    Bob Stephens Guest

    Look on Microchip's website. They maintain a huge list of application notes
    and sample code - including RS485 examples.


    Bob
     
  3. Got called in to do a "*very* similar "complete communication spec" job a few
    years ago.

    Used midi! Worked wonderfully. Coz someone else had done the work for me.

    Gibbo
     
  4. Guest


    ;************************************************************************
    ; crc The 8 bit, table_driven, CRC * *
    ;*********************************** *
    ; Adapted from a 32 bit, byte-at-a-time table driven version. *
    ; *
    ; If used on a "receive" stream then Z is also returned i.e. Z == true *
    ; means that W == 0 (it's easier for the caller to test Z than test W) *
    ; *
    ; Algorithm: r = 0; *
    ; while (--len) { *
    ; r = t [ r ^ (* p++)]; *
    ; } *
    ; *
    ; Entry: msgLength // in bytes *
    ; msgBufPtr // start address *
    ; crc_table[256] *
    ; *
    ; Uses: temp *
    ; byte_counter *
    ; FSR *
    ; INDF *
    ; *
    ; Exit W == crc *
    ; Z == true | false *
    ;************************************************************************
    constant polynomial = H'41'

    Crc macro
    clrf temp
    movf msgLength,w
    movwf byte_counter
    movf msgBufPtr,w
    movwf FSR
    crc_10
    movf INDF,w ; w = next message byte
    xorwf temp,w ; w = index
    call crc_table ; w = crc_table[index]
    movwf temp ; reg = "remainder in progress"
    incf FSR,f
    decfsz byte_counter,f
    goto crc_10
    addlw D'0' ; affect Z flag
    return ; Exit, W == CRC, Z == true | false


    crc_table
    jumper
    Crc_tab polynomial
    endm

    ;************************************************************************
    ; crc_table 256 * 8 bit table for the 8 bit, table_driven, CRC * *
    ;************************************************************************
    ; This macro creates a 256 byte table required by the 8 bit table-driven*
    ; crc algorithm above. For good information about CRCs see: *
    ; ftp://ftp.rocksoft.com/papers/crc_v3.txt *
    ; *
    ; !!!This table takes twenty seconds to preprocess/compile!!! *
    ; *
    ; Algorithm:int const poly(<parameter>); *
    ; for(int i=0; i<256; ++i){ *
    ; int temp = i; *
    ; for(int b=0; b<8; ++b){ *
    ; temp <<= 1; *
    ; if(temp & 0x100) temp ^= poly *
    ; } *
    ; insert_table(i,(temp % 8)); *
    ; } *
    ; *
    ; Expects: key_value // the polynomial *
    ; *
    ; Usage: crc_tab <eight bit polynomial> *
    ;************************************************************************

    Crc_tab macro poly_value

    poly = poly_value
    bit_count = D'8'
    index = 0
    msk = H'100' ; (bit 9 of 32 bit integer)

    while (index < D'256')
    i_copy = index

    while (bit_count)
    i_copy <<= 1 ;

    if (i_copy & msk) ; test ninth bit
    i_copy ^= poly
    endif

    bit_count -= 1
    endw

    retlw i_copy % D'256'
    bit_count = 8
    index += 1
    endw
    endm
     
  5. Guest


    ;************************************************************************
    ; jumper: goto(here + offset_in_W) * *
    ;*********************************** *
    ; Computed goto (see AN556). *
    ; *
    ; Expects: W == offset *
    ; jumptable == concatenated to this macro *
    ; *
    ; Uses: temp *
    ;************************************************************************
    jumper macro
    local jumper_10
    local jumptable
    movwf temp
    movlw LOW jumper_10
    addwf temp,w
    movlw HIGH jumper_10
    btfsc STATUS,stat_C_bit
    addlw D'1'
    movwf PCLATH
    movf temp,w
    jumper_10
    addwf PCL,f
    jumptable ; jump table starts here.
    endm

    ;************************************************************************
    ; End of jumper *
    ;************************************************************************

    Whoops! this is required also

    Cheers
    Robin
     
  6. simon

    simon Guest

    Inverse of the same... brilliant! Why didn't I think of that. Nice and
    simple, that'll probably do. Thank you John for your comments.

    Kind regards,
    Simon
     
  7. simon

    simon Guest

    Thanks for the reply Robin. The code you have posted seems very concise.

    Regards,
    Simon

     
  8. john jardine

    john jardine Guest

    It's a relatively simple job. 485 data loss should be rare. 100mtrs is a
    short run at 9600baud. CRC calcs just over complicate the matter at TX and
    RX. If you must, then just calc parity on each returned byte or even better,
    get the nodes just to send the data followed by the inverse of the same.
    Biggest time waster is making sense of what the PIC is doing inside its
    bloody UART module.
    regards
    john
     
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day

-