现在的位置: 首页 > 综合 > 正文

CAN总线

2018年02月01日 ⁄ 综合 ⁄ 共 5160字 ⁄ 字号 评论关闭

#include "Head.h"

U8 Send_data[8];
U8 Receive_data[8];

void CAN0_Init()
{
    U8 i;
U8 SFRPAGE_save = SFRPAGE;
    SFRPAGE  = CAN0_PAGE;               // All CAN register are on page 0x0C
CAN0CN |= 0x01;                     // Start Intialization mode
    //---------Initialize general CAN peripheral settings
    CAN0CN |= 0x4E;                     // Enable Status, Error, 
                                        // Module Interrupts
                                        // Enable access to bit timing register
// See the CAN Bit Timing Spreadsheet for how to calculate this value
    CAN0BT = 0x1C02;                    // Based on 24 Mhz CAN clock, set the
                                        // CAN bit rate to 500 Kbps - 1C02
//---------Initialize settings common to all message objects

   // Command Mask Register
   CAN0IF1CM = 0x00F0;                 // Write Operation
                                       // Transfer ID Mask, MDir, MXtd
                                       // Transfer ID, Dir, Xtd, MsgVal
                                       // Transfer Control Bits
                                       // Don't set TxRqst or transfer data
   CAN0IF2CM = 0x00F0;

   // Mask Registers
   CAN0IF1M1 = 0xffff;                 // Mask Bits 15-0 not used for filtering
   CAN0IF1M2 = 0xffff;                 // Ignore Extended Identifier for 
                                       // filtering
                                       // Used Direction bit for filtering
                                       // Use ID bits 28-18 for filtering

   CAN0IF2M1 = 0xffff;
   CAN0IF2M2 = 0xffff;
                                                                                                                               ;
   //IF1用于发送,源地址为0x01,目的地址为0x0a
   //IF2用于接收,源地址为0x0a,目的地址为0x01
   for(i = 0; i < 9; i ++)
   {  
     switch(i){
 case 0:
        // Arbitration Registers
             CAN0IF1A1 = 0x0003 | (0<<10); //无折分,消息类型:0x00           
CAN0IF1MC = 0x0880 | 0;
 break;
 case 1:
        // Arbitration Registers
             CAN0IF1A1 = 0x0003 | (1<<10); //无折分,消息类型:0x01           
CAN0IF1MC = 0x0880 | 1;
 break;
 case 2:
// Arbitration Registers
             CAN0IF1A1 = 0x0003 | (2<<10); //无折分,消息类型: 0x02   //设置                
CAN0IF1MC = 0x0880 | 3;
 break;
 case 3:
// Arbitration Registers
             CAN0IF1A1 = 0x0003 | (2<<10); //无折分,消息类型: 0x02   //查询               
CAN0IF1MC = 0x0880 | 1;
 break;
 case 4:
// Arbitration Registers
             CAN0IF1A1 = 0x0003 | (3<<10); //无折分,消息类型: 0x03查询               
CAN0IF1MC = 0x0880 | 1;
 break;
 case 5:
// Arbitration Registers
             CAN0IF1A1 = 0x0002 | (3<<10); //首帧,消息类型: 0x03       
  CAN0IF1MC = 0x0880 | 8;
 break;
 case 6:
// Arbitration Registers      
             CAN0IF1A1 = 0x0000 | (3<<10); //中间帧,消息类型: 0x03                
CAN0IF1MC = 0x0880 | 8;
 break;
 case 7:
// Arbitration Registers
             CAN0IF1A1 = 0x0001 | (3<<10); //尾帧,消息类型: 0x03               
             CAN0IF1MC = 0x0880 | 8;
 break;
 case 8:
        // Arbitration Registers
             CAN0IF1A1 = 0x0003 | (4<<10); //无折分,消息类型: 0x04 ,查询     
        CAN0IF1MC = 0x0880 | 0;
 break;
 default:
 break;

}
CAN0IF1A2 = 0xe0a8;
CAN0IF1CR = i;
while (CAN0IF1CRH & 0x80) {}
//CAN0IF2A2 = 0xc0a8;
    }
   //接收
   for(i = 9; i < 15; i ++)
   {
switch(i){
 case 9:
        CAN0IF2A1 = 0x0003 | (1<<10);  //无折分,消息类型:0x01 
CAN0IF2MC = 0x1480 | 1;
 break;
 case 10:
        CAN0IF2A1 = 0x0003 | (2<<10);  //无折分,消息类型:0x02 
CAN0IF2MC = 0x1480 | 3;
 break;
 case 11:
        CAN0IF2A1 = 0x0002 | (3<<10); //首帧,消息类型: 0x03 
CAN0IF2MC = 0x1480 | 8;
 break;
 case 12:
        CAN0IF2A1 = 0x0000 | (3<<10); //中间帧,消息类型: 0x03
CAN0IF2MC = 0x1480 | 8;
 break;
 case 13:
        CAN0IF2A1 = 0x0001 | (3<<10); //尾帧,消息类型: 0x03
CAN0IF2MC = 0x1480 | 8;
 break;
 case 14:
        CAN0IF2A1 = 0x0003 | (4<<10);  //无折分,消息类型: 0x04
CAN0IF2MC = 0x1480 | 5;
 break;
 default:
 break;
}
    CAN0IF2A2 = 0xc504;
CAN0IF2CR = i;
while (CAN0IF2CRH & 0x80) {}
   }

//---------Initialize settings for unused message objects
   for (i = 15; i < 32; i ++)
   {
      // Set remaining message objects to be Ignored
      CAN0IF1A2 = 0x0000;              // Set MsgVal to 0 to Ignore
      CAN0IF1CR = i;                // Start command request
 while (CAN0IF1CRH & 0x80) {}     // Poll on Busy bit

 CAN0IF2A2 = 0x0000;              // Set MsgVal to 0 to Ignore
      CAN0IF2CR = i;                // Start command request
 while (CAN0IF2CRH & 0x80) {}     // Poll on Busy bit  
   }

CAN0CN &= ~0x41;             // Return to Normal Mode and disable
                                 // access to bit timing register
    SFRPAGE = SFRPAGE_save;
}

void CAN0_TransferMO (U8 obj_num)
{
    U8 SFRPAGE_save = SFRPAGE;
    SFRPAGE  = CAN0_PAGE; 

CAN0IF1DA1L = Send_data[0];           
    CAN0IF1DA1H = Send_data[1];          
    CAN0IF1DA2L = Send_data[2];
    CAN0IF1DA2H = Send_data[3];           
    CAN0IF1DB1L = Send_data[4];
    CAN0IF1DB1H = Send_data[5];
    CAN0IF1DB2L = Send_data[6];
    CAN0IF1DB2H = Send_data[7];

CAN0IF1CM = 0x0087;                // Set Direction to Write
                                       // Write TxRqst, all 8 data bytes

    CAN0IF1CR = obj_num;               // Start command request
 
    while (CAN0IF1CRH & 0x80) {}       // Poll on Busy bit    
}

INTERRUPT (CAN0_ISR, INTERRUPT_CAN0)
{
   U8 SFRPAGE_save = SFRPAGE;
   // SFRPAGE is set to CAN0_Page automatically when ISR starts
   U8 status = CAN0STAT;               // Read status, which clears the Status
                                       // Interrupt bit pending in CAN0IID
   
   U8 Interrupt_ID = CAN0IID;          // Read which message object caused
                                  // the interrupt
   if (status & TxOk)                  // If transmit completed successfully
   {
 CAN0IF1CM = 0x0008;
 CAN0IF1CR = Interrupt_ID;
 while (CAN0IF1CRH & 0x80) {}
      if (Interrupt_ID == 0x20) Interrupt_ID = 0x00; 
   }
  if (status & RxOk)                  // If transmit completed successfully
   {
      //SFRPAGE = ACTIVE_PAGE;
      //LED = 0;
 //Data_Init(Receive_data,8);
      //SFRPAGE  = SFRPAGE_save;
      CAN0IF2CM = 0x007F; 
      CAN0IF2CR = Interrupt_ID;  
 while (CAN0IF1CRH & 0x80) {}   // Poll on Busy bit                                                                                                                            
 CAN0IF2CR = Interrupt_ID;
 Receive_data[0] =  CAN0IF2DA1L;
 Receive_data[1] =  CAN0IF2DA1H;
 Receive_data[2] =  CAN0IF2DA2L;
 Receive_data[3] =  CAN0IF2DA2H;
 Receive_data[4] =  CAN0IF2DB1L;
 Receive_data[5] =  CAN0IF2DB1H;
 Receive_data[6] =  CAN0IF2DB2L;
 Receive_data[7] =  CAN0IF2DB1H;
 if (Interrupt_ID == 0x20) Interrupt_ID = 0x00; 
 make_data(Interrupt_ID);  
   }  
}

【上篇】
【下篇】

抱歉!评论已关闭.