+ Reply to Thread
Page 1 of 4 123 ... LastLast
Results 1 to 10 of 37

Thread: Any success stories with CAN bus on PDS?

  1. #1
    Moderator rcurl's Avatar
    Join Date
    Mar 2002
    Location
    Birmingham, Alabama USA
    Posts
    1,344

    Default Any success stories with CAN bus on PDS?

    I am just starting a new project in which I will need to control motors, drive solenoids, read switches and pots, monitor voltages, etc. at several locations in a large piece of equipment. The number and type of devices to monitor and control will change with each machine built, so I need this to be very modular.

    I am looking at using CAN bus by connecting a MCP2515 CAN controller to a PIC, and then use CAN I/O expanders (MCP250xx) on remote node boards.

    Has anyone done anything like this with PDS? I have found a few brief threads in the forum, but there's not a lot of information there.

    Hi, its great to see you visiting our forum. Why not try Proton Compiler for FREE?

    Download the FREE version of Proton Compiler, Its called Amicus18 and its available from HERE

    Already using proton Compiler??? Get rid of these pesky messages... get LICENSED USER STATUS




    CAN is a very powerful industrial and automotive communications bus - but it also appears to be very difficult to implement. Any information or code samples would be GREATLY appreciated!

    Thanx!

    Rick


  2. If you're a Licensed user of PROTON DEVELOPMENT SUITE, apply for Licensed User Status to remove these pesky messages
     and get access to additional forum areas, Beta test downloads and more!

  3. #2
    Licensed User Alan's Avatar
    Join Date
    Apr 2002
    Location
    Blackpool uk
    Posts
    63


    Default Canbus

    Hi

    I know you can implement Canbus operation with a Can to spi interface IC. I dont know if you have looked at this kind of chip. As you say Can works in a harsh enviromrnt.

    Regards

    Alan

  4. #3
    Moderator RGV250's Avatar
    Join Date
    Aug 2005
    Location
    Kent.
    Posts
    1,711


    Default

    Hi,
    I am playing with CAN using 18F458 as these have a CAN module built in so all you need are the transceivers (DIL ones are as rare as rocking horse poo). I am only trying it in loopback mode at the moment so the chip is in itself talking to itself but it all seems to work. I think I am now at the point to build the hardware to see what happens. If you are interested I will tidy up and comment the demo and post it. I am not concerned with the full CAN spec, more for simple messages in a noisy envoirenment.

    Bobby

  5. #4
    Moderator rcurl's Avatar
    Join Date
    Mar 2002
    Location
    Birmingham, Alabama USA
    Posts
    1,344


    Default

    I'll be using an 18F4620 (which doesn't have CAN capability) driving an MCP2515 CAN controller using the SPI interface. I am trying to talk to a bunch of remote MCP25050 CAN I/O expanders. I bought one of Microchip's MCP250xx CAN development boards, and that is working fine (it has three nodes on it), but I am still not having much luck getting a PIC to talk to it. I got so desperate that I just bought a Mikroelektronika basic compiler just because it has built-in CAN libraries. I've got to work on another project for a couple of weeks before I get back to this one.

    I'd love to see any code you've got that works, 'cause I'd sure rather do this using Proton!

    By the way, both http://www.digikey.com and http://www.mouser.com have the MCP2515 transceivers in the DIL package in stock.

    -Rick

  6. #5
    Moderator RGV250's Avatar
    Join Date
    Aug 2005
    Location
    Kent.
    Posts
    1,711


    Default

    Rick,
    I chose the 18F458 as it has a CAN module built in and hence only requires the transceivers, (which the I/O expander requires as well and an oscillator) you do not have to use the SPI, just read and write to the registers. I did look
    at the I/O expanders but could not see the point as you have to configure them up so where I want more I/O I am just using another PIC. The PIC has more I/O already built in, size may be an issue for me but I will probably look at the 258 which still has 25 I/O.
    At the moment the code is in Loopback mode so all it does is write to the transmit buffers and then reads the receive buffers and sends it out to a 4 x 20 LCD, I think it works enough to commit to building a demo board which I hope to have built later on in the week.
    Hopefully it will help you out.

    Regards,
    Bobby
    Code:
    '****************************************************************
    '*  Name    : RGV_BUS_TEST_2.BAS                                *
    '*  Author  : Bobby Garrett                                     *
    '*  Notice  : Copyright (c) 2005 Bobby Garrett                  *
    '*          : All Rights Reserved                               *
    '*  Date    : 19/10/2005                                        *
    '*  Version : 1.0                                               *
    '*  Notes   :                                                   *
    '*          :                                                   *
    '****************************************************************
                                   
            Device = 18F458
            XTAL = 20
            
            'Set up PIC registers
            @CONFIG_REQ
            @__CONFIG config1h, OSCS_OFF_1 & HS_OSC_1
            @__CONFIG config2l, BOR_ON_2 & BORV_42_2 & PWRT_ON_2
            @__CONFIG config2h, WDT_OFF_2
            @__CONFIG config4l, STVR_ON_4 & LVP_OFF_4 & DEBUG_OFF_4
            
            '@CONFIG_REQ
            '@__CONFIG CONFIG1H, OSCS_OFF_1 & HS_OSC_1
            '@__CONFIG CONFIG2L, BOR_ON_2 & BORV_42_2 & PWRT_ON_2
            '@__CONFIG CONFIG2H, WDT_OFF_2 & WDTPS_128_2
            '@__CONFIG CONFIG3H, CCP2MX_ON_3
            '@__CONFIG CONFIG4L, STVR_ON_4 & LVP_OFF_4 & DEBUG_OFF_4
            
            
    
    'Set the CAN I/O pins        
            Declare CAN_Txpin = PORTB.cantx 'Set CAN Transmit pin
            Declare CAN_Rxpin = PORTB.canrx 'Set CAN Receive pin
                          		
            Dim x As Byte   'Loop counter 
            Dim Module1 As Byte
            Dim Module2 As Byte
            Dim Module3 As Byte
            Dim Module4 As Byte
            Dim Module5 As Byte
          
    GoTo INIT
     
    send: 
            Cls                      'Clear screen  For testing
            For x = 0 To 50          'For testing
            TXB0D0 = x               'For testing
           
            RXB0CON = %00100000      'Receive only valid messages with standard identifier                                
                                           
            CANCON = %01001000       'loopback mode for testing only !!!! 
                                     'Transmit buffer 0
            
            'Every count of 10 change the Tx identifier to simulate different unit
            If x <= 10 Then TXB0SIDL = %00100000 : TXB0SIDH = %00000000
            If x > 10 And x <= 20 Then TXB0SIDL = %01000000 : TXB0SIDH = %00000000
            If x > 20 And x <= 30 Then TXB0SIDL = %01100000 : TXB0SIDH = %00000000
            If x > 30 And x <= 40 Then TXB0SIDL = %10000000 : TXB0SIDH = %00000000
            If x > 40 And x <= 50 Then TXB0SIDL = %10100000 : TXB0SIDH = %00000000
                                   
            TXB0CON = %00001001      'Start transmition, priority level 1 
            
    WAIT_TX_OK: If TXB0CON.3 = 1 Then WAIT_TX_OK 'Loop until TX succesfull
                                                 '(change when working OK)
     
            CANCON = %01000000       'loopback mode For testing only !!!!
            
            'Every count of 10 change the Rx identifier to recieve message from "correct module"
            If x <= 10 Then RXB0SIDL = %00100000 : RXB0SIDH = %00000000 : Module1 = RXB0D0
            If x > 10 And x <= 20 Then RXB0SIDL = %01000000 : RXB0SIDH = %00000000 : Module2 = RXB0D0
            If x > 20 And x <= 30 Then RXB0SIDL = %01100000 : RXB0SIDH = %00000000 : Module3 = RXB0D0
            If x > 30 And x <= 40 Then RXB0SIDL = %10000000 : RXB0SIDH = %00000000 : Module4 = RXB0D0
            If x > 40 And x <= 50 Then RXB0SIDL = %10100000 : RXB0SIDH = %00000000 : Module5 = RXB0D0
         
            DelayMS 500             'For testing
           
            Print At 1,1, Dec x         'For testing
            Print At 2,1, Dec Module1   'For testing
            Print At 2,5, Dec Module2   'For testing
            Print At 2,9, Dec Module3   'For testing
            Print At 2,13, Dec Module4  'For testing
            Print At 2,17, Dec Module5  'For testing
            
            Print At 2,21, Dec TXERRCNT, " TX ERR" 'For testing
            Print At 2,31, Dec RXERRCNT, " RX ERR" 'For testing
          
            Next x                      'For testing
            GoTo send                   'For testing
    
    INIT:
            ALL_DIGITAL = True       'Set all I/O to digital
    
    'Set Diplay up
            Declare LCD_TYPE 0 
            Declare LCD_INTERFACE 4
            Declare LCD_LINES 2
            LCD_DTPIN = PORTD.4
            LCD_ENPIN = PORTD.2
            LCD_RSPIN = PORTD.3        
                   
    'Set up the CAN module               
            CANCON = %10000000       'Select config mode
            TXB0CON = 0              'Clear transmit buffer 0 control register
            TXB0DLC = %00001000      'RTR bit cleared, 8 byte data length
            RXB0DLC = %00001000      '8 byte data length
            
    'Set up the CAN module acceptance masks          
            RXM0SIDL = %00000000
            RXM0SIDH = %00000000
            
    'set up CAN hardware
            BRGCON1 = %00010011      'SJW = 1 Tq, Tq = 40/Fosc
            BRGCON2 = %11111111      'Phase seg 1 = 16 Tq, Sample 3 times
            BRGCON3 = %00000111      'Phase seg 2 = 8 Tq
            
            Set CIOCON.5             'ENDRHI  'recessive drives Tx to Vdd (required if using MCP 2551)
            
            CANCON = %01000000       'Select loopback mode For testing only !!!!
            PIR3 = 0                 'Clear interrupt register
           
            Cls                      'Clear screen
            DelayMS 100    		     ' Wait for LCD to start
            Print At 1,3,"Bobby Garrett's" 
            Print At 2,7,"RGV250"
            Print At 1,22,"  CAN BUS TEST"
            Print At 2,21,"    "
            DelayMS 2000             ' Show message for 2 seconds  
        
            GoTo send

  7. #6
    Moderator rcurl's Avatar
    Join Date
    Mar 2002
    Location
    Birmingham, Alabama USA
    Posts
    1,344


    Default

    Bobby-
    Thanks for posting your code. I'd be very interested to know how this works out once you have your hardware ready.

    My choice of chips was driven by requirements that are probably very different from yours. I must be able to change the main processor to a different type later on, and the selection of PICs that support the CAN bus directly is very limited. Also, I'll have a boatload of remote sensing boards, so cost was an important consideration. The I/O expanders are less than half the cost of the 18F458. That being said, I AM very concerned about the throughput I will be able to get using the SPI bus. I understand that it will be MUCH less than if I had used a PIC that supports CAN directly.

    Please keep me posted as your project progresses. As soon as I have something useful, I'll post it too.

    Rick

  8. #7
    Moderator RGV250's Avatar
    Join Date
    Aug 2005
    Location
    Kent.
    Posts
    1,711


    Default

    Hi Rick,
    I haven't done a lot to it recently but I thought I would post it as it is as the comms seems to be very reliable, I have had it running at 1mb/s just to see if it was stable and no problems.

    As you say in another thread it is not industry standard as I do not need it to be. I do not think it would take a lot of programming to get it that way as most of it is done in the module.
    I am not sure about basic commands being written, if you use the PIC's with the CAN module built in then most of it is done for you and it is mainly reading or writing the values in them, the hard bit I found was the configuration and the correct sequence of setting/clearing bits to get the response from the module.
    At present I have it on test with 3 nodes, the test code is the same for all 3, there are 3 jumpers on port A to select the node 1 - 8 (once again I will only need 5 (7 max)).
    The only real thing I think I will need to look at is the error handling (hopefully never needed) and a transmit on condition change. At present it does all the transmits periodically which are easier to see the test data and will be needed anyway.


    Regards,
    Bobby

    (how do you put the boxes in so the code scrolls in them rather than miles down the page?).
    Code:
    '****************************************************************
    '*  Name    : RGV CANBUS TEST                                   *
    '*  Author  : Bobby Garrett                                     *
    '*  Notice  : Copyright (c) 2005 Bobby Garrett                  *
    '*          : All Rights Reserved                               *
    '*  Date    : 22/12/2005                                        *
    '*  Version : 3 million And 1.0                                 *
    '*          :                                                   *
    '*  Notes   : CAN bus Set For 125 kb/s                          *
    '*          : Uses Philips PCA82C250 transcievers for CANBUS    *
    '*          : Display is 4x20 LCD on port D                     *
    '*          : Three jumpers on PORTA for node address           *
    '****************************************************************  
                                   
            Device = 18F448  
            XTAL = 20
            
    'Set up PIC registers
            @CONFIG_REQ
            @__CONFIG config1h, OSCS_OFF_1 & HS_OSC_1 & CP_OFF_1L
            @__CONFIG config2l, BOR_ON_2 & BORV_42_2 & PWRT_ON_2
            @__CONFIG config2h, WDT_OFF_2
            @__CONFIG config4l, STVR_ON_4 & LVP_OFF_4 & DEBUG_OFF_4
            
    '***********************************************
    '* Variable definitions                        *
    '***********************************************
    ' Some of the variables will not be used as the code is generic.
    ' EG, if this module node is set to 1 by the jumpers then NODE_1_DATA_xx
    ' variables are not used as they are for received messages and the 
    ' identifier for the TRANSMIT_DATA_xx will be 1. 
    
            Dim TRANSMIT_DATA_0 As Byte
            Dim TRANSMIT_DATA_1 As Byte
            Dim TRANSMIT_DATA_2 As Byte
            Dim TRANSMIT_DATA_3 As Byte
            Dim TRANSMIT_DATA_4 As Byte
            Dim TRANSMIT_DATA_5 As Byte
            Dim TRANSMIT_DATA_6 As Byte
            Dim TRANSMIT_DATA_7 As Byte
    
            Dim NODE_1_DATA_0 As Byte
            Dim NODE_1_DATA_1 As Byte
            Dim NODE_1_DATA_2 As Byte
            Dim NODE_1_DATA_3 As Byte
            Dim NODE_1_DATA_4 As Byte
            Dim NODE_1_DATA_5 As Byte
            Dim NODE_1_DATA_6 As Byte
            Dim NODE_1_DATA_7 As Byte
            
            Dim NODE_2_DATA_0 As Byte
            Dim NODE_2_DATA_1 As Byte
            Dim NODE_2_DATA_2 As Byte
            Dim NODE_2_DATA_3 As Byte
            Dim NODE_2_DATA_4 As Byte
            Dim NODE_2_DATA_5 As Byte
            Dim NODE_2_DATA_6 As Byte
            Dim NODE_2_DATA_7 As Byte
            
            Dim NODE_3_DATA_0 As Byte
            Dim NODE_3_DATA_1 As Byte
            Dim NODE_3_DATA_2 As Byte
            Dim NODE_3_DATA_3 As Byte
            Dim NODE_3_DATA_4 As Byte
            Dim NODE_3_DATA_5 As Byte
            Dim NODE_3_DATA_6 As Byte
            Dim NODE_3_DATA_7 As Byte
            
            Dim NODE_4_DATA_0 As Byte
            Dim NODE_4_DATA_1 As Byte
            Dim NODE_4_DATA_2 As Byte
            Dim NODE_4_DATA_3 As Byte
            Dim NODE_4_DATA_4 As Byte
            Dim NODE_4_DATA_5 As Byte
            Dim NODE_4_DATA_6 As Byte
            Dim NODE_4_DATA_7 As Byte
            
            Dim NODE_5_DATA_0 As Byte
            Dim NODE_5_DATA_1 As Byte
            Dim NODE_5_DATA_2 As Byte
            Dim NODE_5_DATA_3 As Byte
            Dim NODE_5_DATA_4 As Byte
            Dim NODE_5_DATA_5 As Byte
            Dim NODE_5_DATA_6 As Byte
            Dim NODE_5_DATA_7 As Byte
            
            Dim NODE_6_DATA_0 As Byte
            Dim NODE_6_DATA_1 As Byte
            Dim NODE_6_DATA_2 As Byte
            Dim NODE_6_DATA_3 As Byte
            Dim NODE_6_DATA_4 As Byte
            Dim NODE_6_DATA_5 As Byte
            Dim NODE_6_DATA_6 As Byte
            Dim NODE_6_DATA_7 As Byte
            
            Dim NODE_7_DATA_0 As Byte
            Dim NODE_7_DATA_1 As Byte
            Dim NODE_7_DATA_2 As Byte
            Dim NODE_7_DATA_3 As Byte
            Dim NODE_7_DATA_4 As Byte
            Dim NODE_7_DATA_5 As Byte
            Dim NODE_7_DATA_6 As Byte
            Dim NODE_7_DATA_7 As Byte
     
            Dim RX_NODE_NR As Byte    'Temp store for Identifier of received message
            Dim TX_NODE_NR As Byte    'This modules address as set by jumpers on PORTA.
            
            Dim NEW_MESSAGE As Bit    
            
            Dim TIMER1 As TMR1L.Word
    
            Symbol IPEN = RCON.7
            Symbol TMR1IP = IPR1.0   
            Symbol TMR1IF = PIR1.0  
            Symbol TMR1IE = PIE1.0  
            Symbol GIEH = INTCON.7   
            Symbol GIEL = INTCON.6       
            Symbol TMR1ON = T1CON.0
    
    GoTo INIT
    
    '***********************************************
    '* Interrupt service vector initialization     *
    '***********************************************
    ON_INTERRUPT GoTo INTERRUPT_ROUTINE 'Point to the Interrupt handler
    
    GoTo START                      'Jump over the Interrupt routine
                                      
    '****************************************************************
    '* Interrupt Service Routine                                    *
    '* Determine if it is a timed interrupt or CAN module interrupt *
    '* Also the ISR determines whether a Valid message or CAN error *
    '* interrupt has occured and then proceeds accordingly          *
    '****************************************************************
    INTERRUPT_ROUTINE:
            If PIR1.0 = 0 Then GoTo CAN_MODULE_INTERRUPT
            Clear T1CON.0           'Stop timer
             
    TIMED_TRANSMIT_ROUTINE: 'If it wasn't the CAN module it must have been the timer Interrupt
            Toggle PORTC.6  'Flash RED LED just to let me know it is doing something
            
    'This is just to generate data for testing 
    'Normally data wil be written to TRANSMIT_DATA_xx from elsewhere in the program.           
            TRANSMIT_DATA_0 = TRANSMIT_DATA_0 + 1
            If TRANSMIT_DATA_0 = 100 Then TRANSMIT_DATA_0 = 0
            TRANSMIT_DATA_1 = TRANSMIT_DATA_1 + 1
            If TRANSMIT_DATA_1 = 100 Then TRANSMIT_DATA_1 = 0
    'Down to here !!!          
      
            TXB0D0 = TRANSMIT_DATA_0'Move data into transmit buffer 0
            TXB0D1 = TRANSMIT_DATA_1
            TXB0D2 = TRANSMIT_DATA_2 
            TXB0D3 = TRANSMIT_DATA_3
            TXB0D4 = TRANSMIT_DATA_4
            TXB0D5 = TRANSMIT_DATA_5
            TXB0D6 = TRANSMIT_DATA_6
            TXB0D7 = TRANSMIT_DATA_7
    
            CANCON = %00001000      'Normal mode, transmit buffer 0
            TXERRCNT = 0            'Clear TX error counter
            TXB0CON = %00001001     'Start transmition, priority level 1 
    WAIT_TX0_OK: If TXB0CON.3 = 1 Then WAIT_TX0_OK 'Loop until TX succesfull
            CANCON = %00000000      'Select CAN normal mode after transmission
            PIR1.0 = 0              'Clear Timer 1 overflow interrupt bit
            TIMER1 = 0              'Re-set timer to zero
            Set T1CON.0             'Re-start timer
            Context Restore         'Exit ISR and re-enable interrupts             
        
    CAN_MODULE_INTERRUPT:
            If PIR3.0 = 1 Then GoTo RECEIVE_MSG
            If PIR3.5 = 1 Then GoTo CAN_ERROR
    
    '**********************************************************************
    '* CAN Msg Received Routine                                           *
    '* This routine is called when a message has been received into RXB0. *
    '* The routine reads the Low identifier Byte And Then shifts the bits *  
    '* right x 5 to get the number of the node transmitting the message.  *
    '**********************************************************************
    'It could probably be done better with indirect addressing but I only need 6 nodes !
    'It also makes the code more readable and understandable when I look at it in 6 months time.
    RECEIVE_MSG:
            Toggle PORTC.7          'Flash GREEN LED to let me know something is happening
            RX_NODE_NR = RXB0SIDL >> 5 'Shift bits right x 5 to determine which node sent
                                       'current message.
            If RX_NODE_NR = 1 Then GoTo MESSAGE_FROM_NODE_1 'go to routine for that message.
            If RX_NODE_NR = 2 Then GoTo MESSAGE_FROM_NODE_2
            If RX_NODE_NR = 3 Then GoTo MESSAGE_FROM_NODE_3
            If RX_NODE_NR = 4 Then GoTo MESSAGE_FROM_NODE_4
            If RX_NODE_NR = 5 Then GoTo MESSAGE_FROM_NODE_5
            If RX_NODE_NR = 6 Then GoTo MESSAGE_FROM_NODE_6
            If RX_NODE_NR = 7 Then GoTo MESSAGE_FROM_NODE_7
    
    MESSAGE_FROM_NODE_1:        
            NODE_1_DATA_0 = RXB0D0  'Copy data in receive buffer as it will be 
            NODE_1_DATA_1 = RXB0D1  'overwritten by Next message
            NODE_1_DATA_2 = RXB0D2       
            NODE_1_DATA_3 = RXB0D3      
            NODE_1_DATA_4 = RXB0D4       
            NODE_1_DATA_5 = RXB0D5      
            NODE_1_DATA_6 = RXB0D6       
            NODE_1_DATA_7 = RXB0D7      
            NEW_MESSAGE = 1         'Set flag to update display
            GoTo DONE
            
    MESSAGE_FROM_NODE_2: 
            NODE_2_DATA_0 = RXB0D0  'Copy data in receive buffer as it will be 
            NODE_2_DATA_1 = RXB0D1  'overwritten by Next message
            NODE_2_DATA_2 = RXB0D2       
            NODE_2_DATA_3 = RXB0D3      
            NODE_2_DATA_4 = RXB0D4       
            NODE_2_DATA_5 = RXB0D5      
            NODE_2_DATA_6 = RXB0D6       
            NODE_2_DATA_7 = RXB0D7              
            NEW_MESSAGE = 1         'Set flag to update display
            GoTo DONE
            
    MESSAGE_FROM_NODE_3:        
            NODE_3_DATA_0 = RXB0D0  'Copy data in receive buffer as it will be 
            NODE_3_DATA_1 = RXB0D1  'overwritten by Next message
            NODE_3_DATA_2 = RXB0D2       
            NODE_3_DATA_3 = RXB0D3      
            NODE_3_DATA_4 = RXB0D4       
            NODE_3_DATA_5 = RXB0D5      
            NODE_3_DATA_6 = RXB0D6       
            NODE_3_DATA_7 = RXB0D7             
            NEW_MESSAGE = 1         'Set flag to update display
            GoTo DONE
            
    MESSAGE_FROM_NODE_4:        
            NODE_4_DATA_0 = RXB0D0  'Copy data in receive buffer as it will be 
            NODE_4_DATA_1 = RXB0D1  'overwritten by Next message
            NODE_4_DATA_2 = RXB0D2       
            NODE_4_DATA_3 = RXB0D3      
            NODE_4_DATA_4 = RXB0D4       
            NODE_4_DATA_5 = RXB0D5      
            NODE_4_DATA_6 = RXB0D6       
            NODE_4_DATA_7 = RXB0D7             
            NEW_MESSAGE = 1         'Set flag to update display
            GoTo DONE
            
    MESSAGE_FROM_NODE_5:        
            NODE_5_DATA_0 = RXB0D0  'Copy data in receive buffer as it will be 
            NODE_5_DATA_1 = RXB0D1  'overwritten by Next message
            NODE_5_DATA_2 = RXB0D2       
            NODE_5_DATA_3 = RXB0D3      
            NODE_5_DATA_4 = RXB0D4       
            NODE_5_DATA_5 = RXB0D5      
            NODE_5_DATA_6 = RXB0D6       
            NODE_5_DATA_7 = RXB0D7            
            NEW_MESSAGE = 1         'Set flag to update display
            GoTo DONE
            
    MESSAGE_FROM_NODE_6:        
            NODE_6_DATA_0 = RXB0D0  'Copy data in receive buffer as it will be 
            NODE_6_DATA_1 = RXB0D1  'overwritten by Next message
            NODE_6_DATA_2 = RXB0D2       
            NODE_6_DATA_3 = RXB0D3      
            NODE_6_DATA_4 = RXB0D4       
            NODE_6_DATA_5 = RXB0D5      
            NODE_6_DATA_6 = RXB0D6       
            NODE_6_DATA_7 = RXB0D7             
            NEW_MESSAGE = 1         'Set flag to update display
            GoTo DONE
              
    MESSAGE_FROM_NODE_7:        
            NODE_7_DATA_0 = RXB0D0  'Copy data in receive buffer as it will be 
            NODE_7_DATA_1 = RXB0D1  'overwritten by Next message
            NODE_7_DATA_2 = RXB0D2       
            NODE_7_DATA_3 = RXB0D3      
            NODE_7_DATA_4 = RXB0D4       
            NODE_7_DATA_5 = RXB0D5      
            NODE_7_DATA_6 = RXB0D6       
            NODE_7_DATA_7 = RXB0D7            
            NEW_MESSAGE = 1         'Set flag to update display
            GoTo DONE 
    DONE:   
            COMSTAT = 0             'Clear CAN comminication status register
            RXB0CON = %00100000     'Set RXB0CON for next message   
            PIR3 = 0                'Clear CAN bus error interrupt bits   
            Context Restore         'Exit ISR and re-enable interrupts       
    
    '*******************************************************************
    '* CAN Error routine                                               *
    '* At present this routine only places some registers on the LCD   *
    '* turns on LED and halts program for diagnosing problem.          *
    '*******************************************************************
    CAN_ERROR:
            Cls           'Clear screen
            PORTD.1 = 1   'Turn on RED LED for CAN error
            Print At 1,1, "CAN error"
            Print At 2,1, Dec TXERRCNT
            Print At 2,11, Dec RXERRCNT
            Print At 1,21, Dec COMSTAT
            Print At 1,31, Dec PIR3 
            Stop
        
    '***********************************************
    '* Start of Main Code                          *
    '***********************************************
    START:
    'Set up priority interrupts.
            IPEN = 1                ' Enable priority interrupts.
            TMR1IP = 1              ' Set Timer1 as a high priority interrupt source
            TMR1IF = 0              ' Clear the Timer1 interrupt flag
            TMR1IE = 1              ' Enable Timer1 interrupts
            GIEH = 1                ' Set the global interrupt enable bits
    
    'Send start up message to LCD        
            Cls                               'Clear screen
            DelayMS 100    		              ' Wait for LCD to start
            Print At 1,1, "  Bobby Garrett's" 'Show start up message
            Print At 2,1, "      RGV250"
            Print At 1,21,"   CAN BUS TEST"
            Print At 2,21,"      NODE ",Dec TX_NODE_NR 'Show node number       
            DelayMS 2000                      ' Show message for 2 seconds         
            Cls                     'Clear screen
                      
    'Set up TIMER1                            
            T1CON = %10110000       'Timer1 - 1:8 prescaler and act as timer
            TIMER1 = 0              'Zero Timer
            T1CON.0 = 1             'Start Timer running
            PIR1.0 = 0              'Clear timer 1 overflow bit
            PIE1 = 1                'Enable Timer1 interrupt
    
    '***********************************************
    '* Main program LOOP                           *
    '***********************************************
    LOOP:
            COMSTAT = 0             'Clear CAN comminication status register.
            INTCON = %00000000      'Turn off interrupts
    'Normal code routines go between here
    'Probably try using "Include" here so the CAN code never needs changeing. 
            If NEW_MESSAGE = 1 Then GoSub DISPLAY 'Only write to display if new message
    'And here 
            INTCON = %11000000      'Turn interrupts back on
            GoTo LOOP
    DISPLAY:
            Print At 1,1, "1<", Dec NODE_1_DATA_0,"  "
            Print At 2,1, "1<", Dec NODE_1_DATA_1,"  "
            Print At 1,7, "2<", Dec NODE_2_DATA_0,"  "
            Print At 2,7, "2<", Dec NODE_2_DATA_1,"  "
            Print At 1,13, "3<", Dec NODE_3_DATA_0,"  "
            Print At 2,13, "3<", Dec NODE_3_DATA_1,"  "
            Print At 1,21, "4<", Dec NODE_4_DATA_0,"  "
            Print At 2,21, "4<", Dec NODE_4_DATA_1,"  "
            Print At 1,27, "5<", Dec NODE_5_DATA_0,"  "
            Print At 2,27, "5<", Dec NODE_5_DATA_1,"  "
     '   Print At 1,29, "6<", Dec NODE_6_DATA_0,"  "     'Not used due to screen size
     '   Print At 2,29, "6<", Dec NODE_6_DATA_1,"  "     'also I do not have the nodes
     '   Print At 1,31, "7<", Dec NODE_7_DATA_0,"  "     'attached at present
     '   Print At 2,31, "7<", Dec NODE_7_DATA_1,"  "
            Print At 1,33, "T>", Dec TRANSMIT_DATA_0,"  "
            Print At 2,33, "T>", Dec TRANSMIT_DATA_1,"  "
            NEW_MESSAGE = 0
            Return
    
    '******************************************************
    '* PIC Initialization                                 *
    '* Most of the CAN module registers are here Whether  *
    '* used Or Not so I don't have to type them in again. *
    '******************************************************       
    INIT:
            ALL_DIGITAL = True      'Set all I/O to digital
    'Set port direction On power up Or after reset       
            TRISA.0 = 1             'Set port direction - NODE address bit 0
            TRISA.1 = 1             'Set port direction - NODE address bit 1
            TRISA.2 = 1             'Set port direction - NODE address bit 2
            
    'Set port direction for CAN I/O        
    'This is important, Proton does not set the port direction of the CAN I/O pins !!         
            TRISB.2 = 0             'Set port direction - CANTx pin as output
            TRISB.3 = 1             'Set port direction - CANRx pin as input 
            
    'Set port direction On power up Or after reset        
            TRISC.6 = 0             'Set port direction - LED for diagnostics
            TRISC.7 = 0             'Set port direction - LED for diagnostics
            TRISD.1 = 0             'Set port direction - LED for diagnostics
            
    'Set state of port on power up or after reset
            PORTC.6 = 0             'Initialise output as off
            PORTC.7 = 0             'Initialise output as off
            PORTD.1 = 0             'Initialise output as off
     
    'Determine node address
            PORTA = 0               'Clear PORTA
            TX_NODE_NR = PORTA & %00000111 '"AND" to filter out unwanted bits 
            
    'CAN MODULE          
    'Set up the CAN module               
            CANCON = %10000000      'Select CAN config mode
            TXB0CON = 0             'Clear transmit buffer 0 control register
              
    'set up CAN hardware
            BRGCON1 = %00000011     'SJW = 1 Tq, Tq = 4/Fosc
            BRGCON2 = %11101100     'Phase seg 1 = 6 x Tq, Prop = 5 x tq, Sample 3 times
            BRGCON3 = %00000111     'Phase seg 2 = 8 x Tq
            Clear CIOCON.5          'ENDRHI  'recessive drives Tx to Vdd (required if using MCP 2551)
            
            TXB0DLC  = %00001000    'RTR bit cleared, 8 byte data length
            RXB0DLC  = %00001000    '8 byte data length
           
    'Set low identifier bits to node address set by jumpers on PORTA
    'Only low byte used
            TXB0SIDH = %00000000    'Set Identifier bits
            TX_NODE_NR = TX_NODE_NR << 5 'Shift left before AND ing
            TXB0SIDL = TX_NODE_NR & %11100000  'Set Identifier bits
            TX_NODE_NR = TX_NODE_NR >> 5 'Shift back for start up message
               
            RXM0SIDH = %00000000    'Set Receive mask 0 bits
            RXM0SIDL = %00000000    'Set Receive mask 0 bits
             
            RXM1SIDH = %00000000    'Set Receive mask 1 bits
            RXM1SIDL = %00000000    'Set Receive mask 1 bits   
            
            RXF0SIDH = %00000000    'Set Receive filter 0 bits
            RXF0SIDL = %00000000    'Set Receive filter 0 bits    
            
            RXF1SIDH = %00000000    'Set Receive filter 1 bits
            RXF1SIDL = %00000000    'Set Receive filter 1 bits    
            
            COMSTAT = 0             'Clear CAN comminication status register.
            CANCON = %00000000      'Select CAN normal mode
            RXB0CON = %00100000     'Receive only valid messages with standard identifier
            PIR3 = 0                'Clear Peripheral interrupt register 3
            PIE3 = %00100001        'Enable selected Peripheral interrupts
            
            TXERRCNT = 0            'Clear Transmit error counter
            RXERRCNT = 0            'Clear Receive error counter
            
            TXB0D0   = 0            'Clear Transmit buffer 0 bytes
            TXB0D1   = 0   
            TXB0D2   = 0   
            TXB0D3   = 0   
            TXB0D4   = 0    
            TXB0D5   = 0   
            TXB0D6   = 0   
            TXB0D7   = 0 
            
            TXB1D0   = 0            'Clear Transmit buffer 1 bytes
            TXB1D1   = 0
            TXB1D2   = 0 
            TXB1D3   = 0 
            TXB1D4   = 0 
            TXB1D5   = 0 
            TXB1D6   = 0 
            TXB1D7   = 0 
            
            TXB2D0   = 0            'Clear Transmit buffer 2 bytes
            TXB2D1   = 0
            TXB2D2   = 0 
            TXB2D3   = 0 
            TXB2D4   = 0 
            TXB2D5   = 0 
            TXB2D6   = 0
            TXB2D7   = 0
            
            RXB0D0   = 0            'Clear Receive buffer 0 bytes
            RXB0D1   = 0
            RXB0D2   = 0
            RXB0D3   = 0
            RXB0D4   = 0
            RXB0D5   = 0
            RXB0D6   = 0
            RXB0D7   = 0
            
            RXB1D0   = 0            'Clear Receive buffer 1 bytes
            RXB1D1   = 0
            RXB1D2   = 0
            RXB1D3   = 0
            RXB1D4   = 0
            RXB1D5   = 0
            RXB1D6   = 0
            RXB1D7   = 0
            
            TRANSMIT_DATA_0 = 0     'Clear Variables
            TRANSMIT_DATA_1 = 0
            TRANSMIT_DATA_2 = 0
            TRANSMIT_DATA_3 = 0
            TRANSMIT_DATA_4 = 0
            TRANSMIT_DATA_5 = 0
            TRANSMIT_DATA_6 = 0
            TRANSMIT_DATA_7 = 0        
            
            NODE_1_DATA_0 = 0       'Clear Variables
            NODE_1_DATA_1 = 0 
            NODE_1_DATA_2 = 0 
            NODE_1_DATA_3 = 0 
            NODE_1_DATA_4 = 0 
            NODE_1_DATA_5 = 0 
            NODE_1_DATA_6 = 0 
            NODE_1_DATA_7 = 0 
            
            NODE_2_DATA_0 = 0       'Clear Variables
            NODE_2_DATA_1 = 0
            NODE_2_DATA_2 = 0
            NODE_2_DATA_3 = 0
            NODE_2_DATA_4 = 0
            NODE_2_DATA_5 = 0
            NODE_2_DATA_6 = 0
            NODE_2_DATA_7 = 0
             
            NODE_3_DATA_0 = 0       'Clear Variables
            NODE_3_DATA_1 = 0
            NODE_3_DATA_2 = 0
            NODE_3_DATA_3 = 0
            NODE_3_DATA_4 = 0
            NODE_3_DATA_5 = 0
            NODE_3_DATA_6 = 0
            NODE_3_DATA_7 = 0
             
            NODE_4_DATA_0 = 0       'Clear Variables
            NODE_4_DATA_1 = 0 
            NODE_4_DATA_2 = 0 
            NODE_4_DATA_3 = 0 
            NODE_4_DATA_4 = 0 
            NODE_4_DATA_5 = 0 
            NODE_4_DATA_6 = 0 
            NODE_4_DATA_7 = 0 
            
            NODE_5_DATA_0 = 0       'Clear Variables
            NODE_5_DATA_1 = 0 
            NODE_5_DATA_2 = 0 
            NODE_5_DATA_3 = 0 
            NODE_5_DATA_4 = 0 
            NODE_5_DATA_5 = 0 
            NODE_5_DATA_6 = 0 
            NODE_5_DATA_7 = 0 
      
            NODE_6_DATA_0 = 0       'Clear Variables
            NODE_6_DATA_1 = 0 
            NODE_6_DATA_2 = 0   
            NODE_6_DATA_3 = 0  
            NODE_6_DATA_4 = 0  
            NODE_6_DATA_5 = 0 
            NODE_6_DATA_6 = 0    
            NODE_6_DATA_7 = 0   
      
            NODE_7_DATA_0 = 0       'Clear Variables
            NODE_7_DATA_1 = 0
            NODE_7_DATA_2 = 0  
            NODE_7_DATA_3 = 0  
            NODE_7_DATA_4 = 0 
            NODE_7_DATA_5 = 0
            NODE_7_DATA_6 = 0  
            NODE_7_DATA_7 = 0  
           
            RX_NODE_NR = 0
    
    'Set Diplay up
            Declare LCD_TYPE 0 
            Declare LCD_INTERFACE 4
            Declare LCD_LINES 2
            LCD_DTPIN = PORTD.4
            LCD_ENPIN = PORTD.2
            LCD_RSPIN = PORTD.3      
           
            If TX_NODE_NR > 0 And TX_NODE_NR < 8 Then GoTo START 'Check node address is set
    
    'If the program has got to here then the node address has not been read properly (1 - 7)
    'Put message on screen and Flash LED, halt program.
    
            Cls                               'Clear screen
            Print At 1,1, "NODE ERROR - ",Dec TX_NODE_NR 
    NODE_ERROR:                                                     
            Toggle PORTD.1   'Flash RED LED for Node address error 
            DelayMS 1000
            GoTo NODE_ERROR                                            
            Stop

  9. #8
    Moderator RGV250's Avatar
    Join Date
    Aug 2005
    Location
    Kent.
    Posts
    1,711


    Default

    Rick,
    If you do give it a go and want to try different speeds below are the settings needed, if you need other speeds http://www.kvaser.com/ has a good calculator, just use the MCP2510 settings and convert to binary.

    100K
    BRGCON1 = %00000011
    BRGCON2 = %10111111
    BRGCON3 = %00000111

    1M
    BRGCON1 = %00000000
    BRGCON2 = %10001001
    BRGCON3 = %00000100

    Regards,
    Bobby

  10. #9


    Default

    Hi.

    PIC18F4680 CAN Code not work.Please Help?

    CAN Message Transmitt Problem.(or ECAN Code Conversion)

    Regards.
    Thanks.
    RMUTR

  11. #10
    Moderator RGV250's Avatar
    Join Date
    Aug 2005
    Location
    Kent.
    Posts
    1,711


    Default

    Hi,
    Need a bit more to go on than that.

    Regards,
    Bobby

+ Reply to Thread
Page 1 of 4 123 ... LastLast

Similar Threads

  1. success rate
    By rverm in forum The Lounge
    Replies: 18
    Last Post: 18th February 2009, 11:53

Members who have read this thread since 18th April 2012, 21:13 : 6

Actions :  (Set Date)  (Clear Date)

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