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

📄 f50x_can0_transmit.c

📁 CAN of C8051F500/F510 CAN 2.0 Bus 發送跟接收Keil C source sample code.可以用在CAN 2.x的上面喔~
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// Return Value : None
// Parameters   : None
//
// This function initializes the CAN peripheral and all of the message objects
//
// The following settings are chosen for the peripheral and message objects:
//
// CAN Bit Clock : 1 Mbps
// Auto Retransmit : Automatic Retransmission is enabled
// MsgVal        : Set to Valid based on the #define MESSAGE_OBJECTS
// Filtering     : Enabled for all valid message objects
// Message Identifier : 11-bit standard; Each message object is only used by
//                      one message ID and the ID is equal to the object number
// Direction     : All valid message objects are configured for transmit
// 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
// Transmit 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 = 0x0880 | MESSAGE_SIZE;  // Enable Transmit 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 send it.

      // Arbitration Registers
      CAN0IF1A2 = 0xA000 | (iter << 2);  // Set MsgVal to valid
                                         // Set Direction to write
                                         // 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;
}

//-----------------------------------------------------------------------------
// Supporting Subroutines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// CAN0_TransferMO
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : U8 obj_num - message object number to send data
//                             range is 0x01 - 0x20
//
// Send data using the message object passed as the parameter. The data
// is generated using the message object number as the seed.
//
//-----------------------------------------------------------------------------

void CAN0_TransferMO (U8 obj_num)
{
   // This function assumes that the message object is fully initialized
   // in CAN0_Init and so all it has to do is fill the data registers and 
   // initiate transmission

   U8 SFRPAGE_save = SFRPAGE;
   SFRPAGE  = CAN0_PAGE;               // All CAN register are on page 0x0C

   // Initialize all 8 data bytes even though they might not be sent
   // The number to send was configured earlier by setting Message Control

   CAN0IF1DA1H = obj_num;              // Initialize data registers based
   CAN0IF1DA1L = obj_num + 1;          // on message object used
   CAN0IF1DA2H = obj_num + 2;
   CAN0IF1DA2L = obj_num + 3;           
   CAN0IF1DB1H = obj_num + 4;
   CAN0IF1DB1L = obj_num + 5;
   CAN0IF1DB2H = obj_num + 6;
   CAN0IF1DB2L = obj_num + 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 Service Routines
//-----------------------------------------------------------------------------

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

INTERRUPT (CAN0_ISR, INTERRUPT_CAN0)
{
   // 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

   CAN0IF1CM = 0x0008;                 // Set Command Mask to clear pending 
                                       // interrupt for the message object


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

   if (status & TxOk)                  // If transmit completed successfully
   {
      // Set variable to indicate this message object's transfer completed
 
      // Message Object 0 reports as 0x20 in the CAN0IID register, so 
      // convert it to 0x00
      if (Interrupt_ID == 0x20) 
      {
         Interrupt_ID = 0x00; 
      }

      // Bit-shifting doesn't work with an operator greater than 15, so
      // account for it 
      if (Interrupt_ID <= 15) 
      {
	      CAN_TX_COMPLETE.U32 |= (U16) (0x01 << Interrupt_ID); 
      }
      else if (Interrupt_ID <= 0x1F)
      {
         CAN_TX_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 + -