CAN BUS DESING. Three CAN BUS nodes created with pic18f458.

08/10/2013 11:34

Hi again.

Here i have created a CAN BUS desing. It has three nodes. Each node has a microcontroller pic18f485 and a MCP2551 transciver. The first node (master), makes two differents tasks.On one hand, it sends a request to the second node. The second node gets the cabin´s temperature value, by means of it module A/D converter. When this node detects the request, it sends the temperature´s value to the CAN BUS.

On the other hand, the first node sends the temperature received from the second node two, to the third node.

The third node, gets the temperature´s value from the CAN BUS and displays it on a two lines lcd.

The parameters´ configuration of the CAN BUS is the following:

The whole circuit is:

 

I have modified the can_set_baud function in 18xxx8.c library in order to choose the CAN BUS speed (125, 250 or 500 Mbps) by means of putting directly the values of the control register from MIcrochip bit timming calculator. The new function is defined as It is shown below.

void can_set_baud(void) {
  #ifdef Set_125K_Baud {
     BRGCON1 = 0x03;
     BRGCON2 = 0xBA;      // para usar CAN a 125 KBps
     BRGCON3 = 0x07;      //con reloj a 20 MHz
  }

  #endif
 
  #ifdef Set_250K_Baud {
     BRGCON1 = 0x01;
     BRGCON2 = 0xBA;      //para usar CAN a 250 KBps
     BRGCON3 = 0x07;      //con reloj a 20 MHz
  }
  #endif

 
  #ifdef Set_500K_Baud {
     BRGCON1 = 0x00;
     BRGCON2 = 0xBA;      //para usar CAN a 500 KBps
     BRGCON3 = 0x07;      //con reloj a 20 MHz
  }
  #endif
}


And finally here are the code for each node:

NODE1:

#include <18F458.h>  //Código para el nondo A (Maestro)
#FUSES NOWDT, HS               
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#define CAN_DO_DEBUG TRUE
#define Set_125K_Baud TRUE  // Velocidad del bus 125kbps para ck 20Mhz,
#include <can-18xxx8.c>     // funcion set_baud
int16 ms;
#int_timer2
void isr_timer2(void)
    {
    ms++;
    }
 
#define PET_TEMP_B      0x201  //Petición a nodo B de temperatura
#define ENV_TEMP_C      0x202  //Envío de datos a nodo c para visualizar
void main() {
  struct rx_stat rxstat;
  int32 rx_id;
  int Buffer[3];
  int rx_len;
 
  setup_timer_2(T2_DIV_BY_4,79,16); //causará interrupción cada ms clock=20MHZ
 
  can_init();
 
  enable_interrupts(INT_TIMER2);
  enable_interrupts(GLOBAL);
 
  while(TRUE)
  {
     if ( can_tbe() && (ms > 2000))   //cada 2 seg y si el buffer está vacío
     {
        ms=0;
        can_putd(PET_TEMP_B,0,1,1,1,1);
     }
 
     if ( can_kbhit() )  //si hay algo en el buffer de recepción
          if(can_getd(rx_id, &buffer[0], rx_len, rxstat))
               if (rx_id == PET_TEMP_B)
               {
               can_putd(ENV_TEMP_C,&buffer[0],1,1,1,0);   
               }
    }
        
}

 

NODE 2:

#include <18F458.h>  //Código para el nondo B que toma la temperatura
#device adc=10
#FUSES NOWDT, HS    //y la envía por el bus cuando hay una petición
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#define CAN_DO_DEBUG TRUE
#define Set_125K_Baud TRUE  // Velocidad del bus 125kbps para ck 20Mhz,
#include <can-18xxx8.c>
 
float v,temp;
#define PET_TEMP_B      0x201  //Petición a nodo B de temperatura
void main() {
 
  struct rx_stat rxstat;
  int32 rx_id;
  int Buffer[3];
  int rx_len;
 int16 t;
 setup_adc_ports(AN0);
 setup_adc(ADC_CLOCK_INTERNAL);
 can_init();
  while(TRUE)
  {
   set_adc_channel(0);
   delay_us(20);
 
   t=read_adc();
   v=(5.0*t)/1024.0;
   temp=(v*5100)/2;
          
     if ( can_kbhit() )  //si hay algo en el buffer de recepción
          if(can_getd(rx_id, &buffer[0], rx_len, rxstat))
               if (rx_id == PET_TEMP_B)
               {
               can_putd(PET_TEMP_B,&temp,1,1,1,0);   
               }
    }
        
}


NODE 3:

#include <18F458.h>  //Código para el nondo C que muestra la temperatura en lcd
#FUSES NOWDT, HS    //si hay una petición
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#define CAN_DO_DEBUG TRUE
#define Set_125K_Baud TRUE  // Velocidad del bus 125kbps para ck 20Mhz,
#include <can-18xxx8.c>
#include <LCD.C>
#define ENV_TEMP_C      0x202  //Envío de datos a nodo c para visualizar
void main() {
 lcd_init();
  struct rx_stat rxstat;
  int32 rx_id;
  int Buffer[3];
  int rx_len;
 can_init();
 
  while(TRUE)
  {          
     if ( can_kbhit() )  //si hay algo en el buffer de recepción
          if(can_getd(rx_id, &buffer[0], rx_len, rxstat))
               if (rx_id == ENV_TEMP_C)
               {
               printf(lcd_putc,"\fTEMP= %04.2dkg",buffer[0]);            
               }

       }       
}