原创 DSPIC30F4011的CAN范例

2009-12-29 09:21 2567 4 4 分类: MCU/ 嵌入式

/*************************************************************
**CAN通讯模块的控制程序
**************************************************************/
#include "includes.h"
#define FCY    16000000                // 4MPLL16    16 MHz

#define FCAN   16000000                // 16 MHz


#define BITRATE 250000        // 通讯波特率
#define NTQ    16        // Number of Tq cycles which will make the
             //CAN Bit Timing .
#define BRP_VAL   ((FCAN/(2*NTQ*BITRATE))-1) //Formulae used for C1CFG1bits.BRP


//---------------------------------------------------------------------



//数据缓冲的定义
//发送缓冲区
unsigned int OutData0[4] = {0x5251, 0x5453, 0x5655, 0x5857};           
unsigned int OutData1[2] = {0x5A59, 0x5C5B};
unsigned int OutData2[4] = {0x6261, 0x6463, 0x6665, 0x6867};           
unsigned int OutData3[2] = {0x6A69, 0x6C6B};
//接受缓冲区
unsigned int InData0[4] = {0, 0, 0, 0};
unsigned int InData1[2] = {0, 0};
unsigned int InData2[4] = {0, 0, 0, 0};
unsigned int InData3[2] = {0, 0};


/*************************************************************
**CAN通讯模块的初始化
**************************************************************/
void   CAN_init(void)
{
TRISFbits.TRISF0=1;
    TRISFbits.TRISF1=0;
    C1CTRLbits.REQOP = 0x4; //请求进入配置模式
    while (C1CTRLbits.OPMODE!=0x4){} //确认进入配置模式

   C1CTRLbits.CANCKS = 1;   // Select the CAN Master Clock . It is equal to Fcy here.
          // equal to Fcy.(Fcy=4Mhz)



C1CFG1bits.SJW=00;     //Synchronized jump width time is 1 x TQ when SJW is equal to 00



C1CFG1bits.BRP = BRP_VAL;   //((FCY/(2*NTQ*BITRATE))-1)


C1CFG2 = 0x02ed;               // SEG1PH=6Tq, SEG2PH=3Tq, PRSEG="5Tq"
                                // Sample 3 times
                                // Each bit time is 16Tq


///Interrupt Section of CAN Peripheral


C1INTF = 0;      //Reset all The CAN Interrupts
IFS1bits.C1IF = 0;     //Reset the Interrupt Flag status register
C1INTE = 0x00ff;               //Enable all CAN interrupt sources tx0 rx0
IEC1bits.C1IE = 1;     //Enable the CAN1 Interrupt


//-----------------------------------------------------------------------------------------------------------------------
       // Configure Receive registers, Filters and Masks
//-----------------------------------------------------------------------------------------------------------------------


C1RX0CON =0;
C1RX1CON = 0x0002; // Receive Buffer1 and 0 Status use fliter 2
           
// Acceptance Mask Register0SID and Register1SID associated with Recieve Buffer0
// and Receive Buffer1 for CAN1 and CAN2
C1RXM0SID = C1RXM1SID = 0x1F01;    //接收的为标准数据桢

// Acceptance Mask Register0EIDH and Register1EIDH associated with Recieve Buffer0
C1RXM0EIDH = C1RXM1EIDH = 0x0FFF;


// Acceptance Mask Register0EIDL and Register1EIDL associated with Recieve Buffer0
C1RXM0EIDL = C1RXM1EIDL = 0xFC00;



//Initializing of Acceptance Filter n Standard Identifier for CAN1


C1RXF0SID = 0x0AA8; //CAN1 Receive Acceptance Filter2 SID   
C1RXF2SID = 0x15c0;   //CAN1 Receive Acceptance Filter2 SID
C1RXF2EIDH = 0x0004;   //CAN1 Receive Acceptace Filter2 Extended Identifier high byte
C1RXF2EIDL = 0x8C00; //CAN1 Receive Acceptance Filter2 Extended identifier low byte


//Initializing of Acceptance Filter n Standard Identifier for CAN2


//-----------------------------------------------------------------------------------------------------------------------
       // Configure Transmit Registers Buffer 0 and Transmit Buffer 1
//-----------------------------------------------------------------------------------------------------------------------
C1TX0CON = 0x0003;     // High priority
C1TX0SID = 0x50A8;     // SID
C1TX0EID = 0x0000;     // EID
C1TX0DLC = 0x01C0;   //Select the Data word Length for CAN1 Transmit Buffer0 which is 8 byte

// Data Field 1,Data Field 2, Data Field 3, Data Field 4 // 8 bytes selected by DLC


C1TX0B1 = OutData0[0];
C1TX0B2 = OutData0[1];
C1TX0B3 = OutData0[2];
C1TX0B4 = OutData0[3];

C1TX1CON = 0x0002;             // High Intermediate priority
C1TX1SID = 0xA860;             // SID
C1TX1EID = 0x0000;             // EID                  
C1TX1DLC = 0x8DA0;     //Select the Data word Length for CAN1 Transmit Buffer1 which
         // is 4 byte


//Data Field 1, Data Field 2 // 4 bytes selected by DLC


C1TX1B1 = OutData1[0];
C1TX1B2 = OutData1[1];



//Change to Loopback Operation Mode from Configuration Mode


C1CTRLbits.REQOP = 0;
while(C1CTRLbits.OPMODE != 0);//Wait for CAN1 mode change from Configuration Mode to Loopback mode
}         //end main loop


//--------------------------------------------------------------------------------------------------------------------------
            //Interrupt Section for CAN1
//--------------------------------------------------------------------------------------------------------------------------
unsigned int buf="0";
unsigned int buf1[8],buf2[8];
void __attribute__((interrupt, no_auto_psv)) _C1Interrupt(void)
{
   IFS1bits.C1IF = 0;         //Clear interrupt flag
      if(C1INTFbits.TX0IF)
      {
         Uart0_Printf("C1 Interrupt Section for CAN1 TX0IF111 ");
   C1INTFbits.TX0IF = 0; //If the Interrupt is due to Transmit0 of CAN1 Clear the Interrupt


      }
      if(C1INTFbits.TX1IF)
      {
        Uart0_Printf("C1 Interrupt Section for CAN1 TX1IF 222 ");     
     C1INTFbits.TX1IF = 0;   //If the Interrupt is due to Transmit1 of CAN1 Clear the Interrupt
      }


      if(C1INTFbits.RX0IF)
      {     
      C1INTFbits.RX0IF = 0; //If the Interrupt is due to Receive0 of CAN1 Clear the Interrupt


        InData0[0] = buf1[0]= C1RX0B1;
        InData0[1] = buf1[1]=C1RX0B2; //Move the recieve data from Buffers to InData
        InData0[2] = buf1[2]=C1RX0B3;
        InData0[3] = buf1[3]=C1RX0B4;
       
        C1RX0CONbits.RXFUL=0;
    
        if ((InData0[0]==OutData0[0]) && (InData0[1]==OutData0[1]) && (InData0[2]==OutData0[2]) && (InData0[3]==OutData0[3]))
             Uart0_Printf("C1RX0 data received is same which was transmitted ");

      }


      if(C1INTFbits.RX1IF)
      {     
        C1INTFbits.RX1IF = 0; //If the Interrupt is due to Receive1 of CAN1 Clear the Interrupt
        InData1[0] =buf2[0]= C1RX1B1;   //Move the data received to Indata Registers
        InData1[1] = buf2[1]=C1RX1B2;
      // Uart0_Printf("InData1[0]= 0x%02x ",InData1[0]);
     //   Uart0_Printf("InData1[1] 0x%02x ",InData1[1]);
        C1RX1CONbits.RXFUL=0;
       
             if ((InData1[0]==OutData1[0]) && (InData1[1]==OutData1[1]))
        Uart0_Printf("C1RX1 data received is same which was transmitted ");
      }
     
      if(C1INTFbits.TXWAR)
      {     
        Uart0_Printf("C1TX is wrong TXWAR="1" !!!!!!!!!!!! ");
      }
      if(C1INTFbits.TXEP)
      {     
        Uart0_Printf("C1TX is wrong TXEP="1" !!!!!!!!!!!! ");
      }
     
      if(C1INTFbits.TXBO)
      {     
        Uart0_Printf("C1TX is wrong TXBO="1" ,CAN BUS CLOSE !!!!!!!!!!!! ");
      }
}
/**********************file    end************************************/

文章评论0条评论)

登录后参与讨论
我要评论
0
4
关闭 站长推荐上一条 /3 下一条