MCP2515 modülü ile pic18f252 Can Bus iletişim örnek kod

Başlatan hit85, 31 Ocak 2016, 13:59:51

hit85

Mrblar arkadaşlar.
Öncelikle hobi olarak pic ile ilgileniyorum. Başlangıç aşamasındayım diyebilirim.
LED yakıp söndürme,anolog veri ölçümü, LCD de termometre ve saat yapabiliyorum :)
MCP2515 modülüile OBDII soketinden gerekli bilgileri (motor sıcaklığı,devir, akü voltajı v.s. ) alıp 2x16 LCD ekrana yazdırmak istiyorum.
Bunun için örnek kod verebilirmisiniz?

Yardımlarınız için şimdiden teşekkür ederim.


Erol YILMAZ

Pic18f45k80 kullan derim öncelikle,
Ikisi bi arada, daha kolay

hit85

Cevabınız için teşekkürler. konu başlığındaki melzemeler  elimde mevcut.
Ayrıca; elimde bluetoothlu ELM327 de mevcut.
Bluetoothunu desoldering yapıp RX-TX bağlantısını pic ile kursam daha kolay olur mu?

http://www.protonbasic.co.uk/ 'de aşağıdaki çalışmaları buldum.
Ama başlangıç seviyesinde olduğum için tecrübeli arkadaşlardan yardım istiyorum.
TEŞEKKÜRLER


Device = 18F4680 
    XTAL = 20
    ALL_DIGITAL = TRUE
    Dim CAN_TX_BUFFER0[8] As Byte
    Dim CAN_RX_BUFFER0[8] As Byte
    
    Dim CAN_RX_ID0        As Word
    Dim CAN_RX_ID0_0      As CAN_RX_ID0.LowByte
    Dim CAN_RX_ID0_1      As CAN_RX_ID0.HighByte
    Dim CAN_RX_ID1        As Word
    Dim CAN_RX_ID1_0      As CAN_RX_ID1.LowByte
    Dim CAN_RX_ID1_1      As CAN_RX_ID1.HighByte
    Dim CAN_RX_ID2        As Word
    Dim CAN_RX_ID2_0      As CAN_RX_ID2.LowByte
    Dim CAN_RX_ID2_1      As CAN_RX_ID2.HighByte
    
    Dim CAN_TX_ID0        As Word
    Dim CAN_TX_ID0_0      As CAN_TX_ID0.LowByte
    Dim CAN_TX_ID0_1      As CAN_TX_ID0.HighByte
    Dim CAN_TX_ID1        As Word
    Dim CAN_TX_ID1_0      As CAN_TX_ID1.LowByte
    Dim CAN_TX_ID1_1      As CAN_TX_ID1.HighByte
    Dim CAN_TX_ID2        As Word
    Dim CAN_TX_ID2_0      As CAN_TX_ID2.LowByte
    Dim CAN_TX_ID2_1      As CAN_TX_ID2.HighByte
    
    Dim CAN_STATUS        As Byte
    Dim CAN_TX_BYTE0      As Byte
    Dim CAN_TX_BYTE1      As Byte
    Dim CAN_TX_BYTE2      As Byte
    Dim CAN_RX_BYTE0      As Byte
    Dim CAN_RX_BYTE1      As Byte
    Dim CAN_RX_BYTE2      As Byte
    Dim IDX               As Byte
    
    
    TRISD.0 = 0
    GoSub CAN_INIT
 
START:
    CAN_TX_ID0 = 12341:CAN_TX_BUFFER0[0]=255:CAN_TX_BYTE0 = 8:GoSub CAN_SEND_0
    PORTD.0 = 1:DelayMS 500:PORTD.0 = 0:DelayMS 500
    GoTo START
    End

CAN_INIT:               
    TRISB.2 = 0:TRISB.3 = 1
    CANCON  = %10000000
WT:    
    If CANSTAT.7 = 0 Then GoTo WT 
    
    ECANCON = %01000000
    BRGCON1 = %00000011:BRGCON2 = %11101100
    BRGCON3 = %00000111:CIOCON.5 = 0:BSEL0 = %00011100
    'B0CON = %00000001:B1CON = %00000001:B2CON = %00000001
    B3CON = %00000000:B4CON = %00000001:B5CON = %00000010
    B0DLC = CAN_TX_BYTE0:B1DLC = CAN_TX_BYTE1:B2DLC = CAN_TX_BYTE2
    B0D0 = 0:B0D1 = 0:B0D2 = 0:B0D3 = 0:B0D4 = 0:B0D5 = 0:B0D6 = 0:B0D7 = 0
    B1D0 = 0:B1D1 = 0:B1D2 = 0:B1D3 = 0:B1D4 = 0:B1D5 = 0:B1D6 = 0:B1D7 = 0
    B2D0 = 0:B2D1 = 0:B2D2 = 0:B2D3 = 0:B2D4 = 0:B2D5 = 0:B2D6 = 0:B2D7 = 0
    B3D0 = 0:B3D1 = 0:B3D2 = 0:B3D3 = 0:B3D4 = 0:B3D5 = 0:B3D6 = 0:B3D7 = 0
    B4D0 = 0:B4D1 = 0:B4D2 = 0:B4D3 = 0:B4D4 = 0:B4D5 = 0:B4D6 = 0:B4D7 = 0
    B5D0 = 0:B5D1 = 0:B5D2 = 0:B5D3 = 0:B5D4 = 0:B5D5 = 0:B5D6 = 0:B5D7 = 0
    B0EIDH = CAN_TX_ID0_1:B0EIDL = CAN_TX_ID0_0
    B1EIDH = CAN_TX_ID1_1:B1EIDL = CAN_TX_ID1_0
    B2EIDH = CAN_TX_ID2_1:B2EIDL = CAN_TX_ID2_0
    B3EIDH = CAN_RX_ID0_1:B3EIDL = CAN_RX_ID0_0
    B4EIDH = CAN_RX_ID1_1:B4EIDL = CAN_RX_ID1_0
    B5EIDH = CAN_RX_ID2_1:B5EIDL = CAN_RX_ID2_0
    B0SIDL = %00000000:B1SIDL = %00000000:B2SIDL = %00000000
    B0SIDH = %00000000:B1SIDH = %00000000:B2SIDH = %00000000
    B0SIDL.3 = 1:B1SIDL.3 = 1:B2SIDL.3 = 1
    'B3SIDL.3 = 1:B4SIDL.3 = 1:B5SIDL.3 = 1
    RXF0SIDL = %00000000:RXF0SIDH = %00000000
    RXF1SIDL = %00000000:RXF1SIDL = %00000000
    RXF2SIDL = %00000000:RXF3SIDL = %00000000
    RXF0SIDL.3 = 1:RXF1SIDL.3 = 1:RXF2SIDL.3 = 1
    RXF0EIDH = CAN_RX_ID0_1:RXF0EIDL = CAN_RX_ID0_0
    RXF1EIDH = CAN_RX_ID1_1:RXF1EIDL = CAN_RX_ID1_0
    RXF2EIDH = CAN_RX_ID2_1:RXF2EIDL = CAN_RX_ID2_0
    RXM0SIDH = %00000000:RXM0SIDL = %00000000
    RXM1SIDH = %00000000:RXM1SIDL = %00000000
    RXM0SIDL.3 = 1:RXM1SIDL.3 = 1
    RXM0EIDL = %11111111:RXM0EIDH = %11111111
    RXM1EIDL = %11111111:RXM1EIDH = %11111111
    RXFCON0 = %00000111:RXFCON1 = %00000111:SDFLC = %00000000
    RXFBCON0 = %00110010:RXFBCON1 = %00000100:MSEL0 = %11000100
    CANCON   = %00000000
    DelayMS 100
WT1:   
    
    If CANSTAT.7 = 0 And CANSTAT.6 = 0 And CANSTAT.5 = 0 Then GoTo WT2 
    GoTo WT1
WT2:    
    PORTD.0 = 1:DelayMS 500:PORTD.0 = 0:DelayMS 500
    Return

CAN_SEND_0:
    B0D0 = CAN_TX_BUFFER0[0]:B0D1 = CAN_TX_BUFFER0[1]:B0D2 = CAN_TX_BUFFER0[2]
    B0D3 = CAN_TX_BUFFER0[3]:B0D4 = CAN_TX_BUFFER0[4]:B0D5 = CAN_TX_BUFFER0[5]
    B0D6 = CAN_TX_BUFFER0[6]:B0D7 = CAN_TX_BUFFER0[7]
    B0CON = %00001000 
WAIT_TX0_OK: 
    If B0CON.3 = 1 Then GoTo WAIT_TX0_OK
    Return



'****************************************************************
'*  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