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

📄 lpc_can.c

📁 给大家提供一个在inram/exram中调试的示例,在周公的lpc2200上调试过.
💻 C
字号:
/*************************************************************************
 *         BU MMS China, Philips Semiconductor Software Support
 *         Embest info&Tech Co. Software Support
 *---------------------------------------------------------------------------
 * The software is delivered "AS IS" without warranty or condition of any
 * kind, either express, implied or statutory.  Everybody can use it as 
 * it is opened and without copyright. We will not take any law responsibility
 * for any problem produced by using this software.
 *---------------------------------------------------------------------------                                                    
 *    File name:	LPC_CAN.c                                                            
 *    Description:	Define API for CAN
 *                                                                                      
 *    History:                                                                     
 *    1. Date: 		Dec 13, 2004                                              
 *       Author:		Shawn Zhang                                                    
 *       Description: Create 
 *
 *	$Revision: 1.0 $
 **************************************************************************/

#include "LPC_CAN.h"

// Define globe variable


/*************************************************************************
 * Function Name: CAN_Init
 * Parameters:	LPC_CAN_Channel_t DevNum
 *				unsigned long BaudRate
 * Return: int 
 *             	0: sucess
 *			1: fail
 * Description: Initialize CAN
 *  
 *************************************************************************/
int CAN_Init ( LPC_CAN_Channel_t DevNum,  unsigned long BaudRate )
{
	unsigned long offset = (DevNum - 1) * CAN_ADDR_OFFSET;
	unsigned long *pSFR, BautRatePrescaler;	

	if (BaudRate > CAN_MAXSPEED)
		return 1;
	if (DevNum > CAN_MAXDEVNUM)
		return 1;

	switch(DevNum)
	{
		case CAN1:
			/* Enable RD1, bit 18~19=01 */
			PINSEL1 &= ~0xC0000;
			PINSEL1 |= ~0x40000;
			break;
		case CAN2:
			/* Enable RD2, TD2, bit 14~17=0101 */
			PINSEL1 &= ~0x3C000;
			PINSEL1 |= ~0x14000;
			break;
		case CAN3:
			/* Enable RD3, bit 10~11=10; TD3, bit 12~13=01 */
			PINSEL1 &= ~0x3C00;
			PINSEL1 |= ~0x1800;
			break;
		case CAN4:
			/* Enable RD4, TD4, bit 24~27=1111; */
			PINSEL0 |= 0xF000000L;
			break;
		default:
			return 1;
	}

	// Acceptance Filter Mode Register = filter off, receive all
	AFMR = 0x00000002L;

	pSFR = (unsigned long *) &C1MOD + offset; // Select Mode register
	*pSFR = MOD_RM; // Go into Reset mode

	pSFR = (unsigned int *) &C1IER + offset; // Select Interrupt Enable Register
	*pSFR = 0; // Disable All Interrupts

	pSFR = (unsigned int *) &C1GSR + offset; // Select Status Register
	*pSFR = 0; // Clear Status register

	BautRatePrescaler = (SYS_GetFpclk() / BaudRate) / (TSEG1_VALUE + TSEG2_VALUE + 3);

	pSFR = (unsigned int *) &C1BTR + offset; // Select BTR Register
	*pSFR = BautRatePrescaler | (TSEG1_VALUE << BTR_TSEG1_BIT) | (TSEG1_VALUE << BTR_TSEG2_BIT); // Set bit timing

	// Enter Normal Operating Mode
	pSFR = (unsigned int *) &C1MOD + offset; // Select Mode register
	*pSFR = 0; // Operating Mode 

	return 0;
}


/*************************************************************************
 * Function Name: 	CAN_SendMsg
 * Parameters:	LPC_CAN_Channel_t DevNum
 *				
 * Return: int 
 *             	0: sucess
 *			1: fail
 * Description: Send Message
 *  
 *************************************************************************/
int CAN_SendMsg ( LPC_CAN_Channel_t DevNum, LPC_CAN_MSG_t *pTransmitBuf)
{
	unsigned long offset = (DevNum - 1) * CAN_ADDR_OFFSET;
	
	if (DevNum > CAN_MAXDEVNUM)
		return 1;

unsigned int *pAddr;  
unsigned int *pCandata;
unsigned int offset;
unsigned char TXBufOffset;
  
  // Double check can_port value
  if ((can_port < 1) || (can_port > MAX_CANPORTS))
  { // Illegal value for can_port
    return 0;
  }



  pAddr = (unsigned int *) &C1SR + offset; // CANSR
  if (!(*pAddr & 0x00000004L))
  { // Transmit Channel 1 is not available
    if (!(*pAddr & 0x00000400L))
    { // Transmit Channel 2 is not available
      if (!(*pAddr & 0x00040000L))
      { // Transmit Channel 3 is not available
        return 0; // No channel available
      }
      else
      {
        TXBufOffset = 0x08;
      }
    }
    else
    {
      TXBufOffset = 0x04;
    }
  }
  else
  {
    TXBufOffset = 0x00;
  }                                                      

  // Write DLC, RTR and FF
  pAddr = (unsigned int *) &C1TFI1 + offset + TXBufOffset;
  *pAddr = pTransmitBuf->Frame & 0xC00F0000L;  
  
  // Write CAN ID
  pAddr++;
  *pAddr = pTransmitBuf->MsgID;
 
  // Write first 4 data bytes 
  pCandata = (unsigned int *) &(pTransmitBuf->DatA);
  pAddr++;
  *pAddr = *pCandata;

  // Write second 4 data bytes 
  pCandata++;
  pAddr++;
  *pAddr = *pCandata;
  
  // Write transmission request
  pAddr = (unsigned int *) &C1CMR + offset;
  if (TXBufOffset == 0x00)
  {
    *pAddr = 0x21; // Transmission Request Buf 1
  }
  else if (TXBufOffset == 0x04)
  {
    *pAddr = 0x41; // Transmission Request Buf 2
  }
  else if (TXBufOffset == 0x08)
  {
    *pAddr = 0x81; // Transmission Request Buf 3
  }
  else
  {
    return 0;
  }

  return 1;
}

⌨️ 快捷键说明

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