⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 f50x_can0_receive.c

📁 CAN of C8051F500/F510 CAN 2.0 Bus 發送跟接收Keil C source sample code.可以用在CAN 2.x的上面喔~
💻 C
📖 第 1 页 / 共 2 页
字号:
//                      one message ID and the ID is equal to the object number
// Direction     : All valid message objects are configured for receive
// End of Buffer : All message objects are treated as separate buffers
//
// The following interrupts are enabled and are handled by CAN0_ISR
//
// Error Interrupts
// Status Change Interrupt
// Receive Interrupt
//
//-----------------------------------------------------------------------------

void CAN0_Init (void)
{
   U8 iter;

   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 = 0x1402;                    // Based on 24 Mhz CAN clock, set the
                                       // CAN bit rate to 1 Mbps

   //---------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

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

   // Arbitration Registers
   CAN0IF1A1 = 0x0000;                 // 11-bit ID, so lower 16-bits not used

   // Message Control Registers
   CAN0IF1MC = 0x1480 | MESSAGE_SIZE;  // Enable Receive Interrupt
                                       // Message Object is a Single Message
                                       // Message Size set by #define


   //---------Initialize unique settings for each valid message object

   for (iter = 0; iter < MESSAGE_OBJECTS; iter++)
   {
      // For example purposes, set 11-bit identifier based on the message 
      // object that is used to receive it.

      // Arbitration Registers
      CAN0IF1A2 = 0x8000 | (iter << 2);  // Set MsgVal to valid
                                         // Set Object Direction to read
                                         // Set 11-bit Identifier to iter

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

   //---------Initialize settings for unused message objects

   for (iter = MESSAGE_OBJECTS; iter < MESSAGE_OBJECTS; iter++)
   {
      // Set remaining message objects to be Ignored
      CAN0IF1A2 = 0x0000;              // Set MsgVal to 0 to Ignore
      CAN0IF1CR = iter;                // Start command request
	  
	   while (!(CAN0IF1CRH & 0x80));    // Poll on Busy bit
   }

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

   SFRPAGE = SFRPAGE_save;
}


//-----------------------------------------------------------------------------
// Interrupt Service Routines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// CAN0_ISR
//-----------------------------------------------------------------------------
//
// The ISR is triggered upon any CAN errors or upon reception of message
//
// If an error occurs, a global counter is updated
//
//-----------------------------------------------------------------------------

INTERRUPT (CAN0_ISR, INTERRUPT_CAN0)
{
   U8 iter;
   U8 carry;
   UU64 rx_data;
   UU32 new_data;

   // 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 you are working with Revision A of the F50x, the CAN0ND registers 
        have a misaligned organization that appears as a 1-bit left shift 
        from the expected alignment as described in the Bosch CAN User抯 
        Guide.

        The Bosch CAN User抯 Guide documents the bit organization for all 
        of these registers as follows:
         Register 1 (16-9 : 8-1)
         Register 2 (32-25 : 24-17)
        
        On Revision A devices, the bit organization for these four sets of 
        registers is as follows:
         Register 1 (15-8  : 7-1, 32)
         Register 2 (31-24 : 23-16)

        The following code will show how to shift the registers to match
        the alignment presented in the Bosch CAN User's Guide. You can find
        more information on this error in "C8051F50x_ErrataRevA.pdf".
      ---------------------------------------------------------------------*/
   // The CAN0ND registers tell which of the 32 message objects are new.
   // Read data from CAN registers and perform 1-bit right shift with carry
   new_data.U8[b0] = CAN0ND1L;         // With a big endian compiler, assign LSB
   new_data.U8[b1] = CAN0ND1H;
   new_data.U8[b2] = CAN0ND2L;
   new_data.U8[b3] = CAN0ND2H;         // Assign MSB
   carry = new_data.U8[b0] & 0x01;     // Store carry bit
   new_data.U32 = new_data.U32 >> 1;   // Perform 1-bit shift to realign

   if (carry) 
   { // Add carry if necessary
      new_data.U8[b3] = new_data.U8[b3] | 0x80; 
   }

   // new_data variable will now tell which message object is new.
   
   CAN0IF1CM = 0x007F;                 // Read all of message object to IF1
                                       // Clear IntPnd and newData

   CAN0IF1CR = Interrupt_ID;           // Start command request
	  
   while (!(CAN0IF1CRH & 0x80));       // Poll on Busy bit

   if (status & RxOk)                  // If transmit completed successfully
   {
       // Read all 8 data bytes to rxdata, even though they might not be valid
       rx_data.U16[0] = CAN0IF1DA1;    // First pair of bytes
       rx_data.U16[1] = CAN0IF1DA2;    // Second pair of bytes
       rx_data.U16[2] = CAN0IF1DB1;    // Third pair of bytes
       rx_data.U16[3] = CAN0IF1DB2;    // Fourth and last pair of bytes

       // Message Object 0 reports as 0x20 in the CAN0IID register, so 
       // convert it to 0x00
       if (Interrupt_ID == 0x20) 
       {
          Interrupt_ID = 0x00; 
       }

       for (iter = 0; iter < MESSAGE_SIZE; iter++)
	    {
          if (rx_data.U8[iter] != (Interrupt_ID + iter)) 
          {
             CAN_ERROR = 1; 
          } 
	    }

       // Set variable to indicate this message object's transfer completed
       // Bit-shifting doesn't work with an operator greater than 15, so
       // account for it 
       if (Interrupt_ID <= 15) 
       {
	       CAN_RX_COMPLETE.U32 |= (U16) (0x01 << Interrupt_ID); 
       }
       else if (Interrupt_ID <= 0x1F)
       {
          CAN_RX_COMPLETE.U16[MSB] |= (U16) (0x01 << (Interrupt_ID - 16)); 
       }
   }

   // If an error occured, simply update the global variable and continue
   if (status & LEC)                 
   {
       // The LEC bits identify the type of error, but those are grouped here
       if ((status & LEC) != 0x07) 
       {
          CAN_ERROR = 1; 
       }
   }

   if (status & BOff)
   {
      CAN_ERROR = 1;
   }

   if (status & EWarn)
   {
      CAN_ERROR = 1;
   }

   // Old SFRPAGE is popped off stack when ISR exits
}

//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -