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

📄 can.c

📁 意法半導體STR710,USB範例程式,模擬U盤
💻 C
📖 第 1 页 / 共 2 页
字号:
* Description    : Configure all the message objects as unused
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void CAN_InvalidateAllMsgObj(void)
{
	int i;
	for (i = 0; i < 32; i++)
		CAN_SetUnusedMsgObj(i);
}

/*******************************************************************************
* Function Name  : CAN_Init
* Description    : Initialize the CAN cell and set the bitrate
* Input 1        : any binary value formed from the CAN_CTL_xxx defines
* Input 2        : one of the CAN_BITRATE_xxx defines
* Output         : None
* Return         : None
*******************************************************************************/
void CAN_Init(u8 mask, int bitrate)
{
  CAN_EnterInitMode(CAN_CTL_CCE | mask);
  CAN_SetBitrate(bitrate);
  CAN_LeaveInitMode();
  CAN_LeaveTestMode();
}

/*******************************************************************************
* Function Name  : CAN_ReleaseMessage
* Description    : Release the message object
* Input 1        : message object number, from 0 to 31
* Output         : None
* Return         : None
*******************************************************************************/
void CAN_ReleaseMessage(int msgobj)
{
	int i;
    while ((i = CAN_GetFreeIF()) == -1);

	CAN->sMsgObj[i].COMM = CAN_COM_CLRINT | CAN_COM_TXRQST;
	CAN->sMsgObj[i].COMR = 1 + msgobj;
}

/*******************************************************************************
* Function Name  : CAN_SendMessage
* Description    : Start transmission of a message
* Input 1        : message object number, from 0 to 31
* Input 2        : pointer to the message structure containing data to transmit
* Output         : None
* Return         : 1 if transmission was OK, else 0
*******************************************************************************/
int CAN_SendMessage(int msgobj, canmsg* pCanMsg)
{
  while (CAN->sMsgObj[0].COMR & CAN_CRQ_BUSY);

//  if (CAN->sMsgObj[0].COMR & CAN_CRQ_BUSY)
//	return 0;	// message interface 0 not free

  CAN->SR &= ~CAN_STS_TXOK;

  // read the Arbitration and Message Control
  CAN->sMsgObj[0].COMM = CAN_COM_ARB | CAN_COM_CTRL;

  CAN->sMsgObj[0].COMR = 1 + msgobj;

  while (CAN->sMsgObj[0].COMR & CAN_CRQ_BUSY);

  // update the contents needed for transmission
  CAN->sMsgObj[0].COMM = CAN_COM_WRITE
  	                   | CAN_COM_ARB
  	                   | CAN_COM_CTRL
  	                   | CAN_COM_DATAA
  	                   | CAN_COM_DATAB;

  if ((CAN->sMsgObj[0].ARB2 & CAN_ARB_XTD) == 0)
  {
  	// standard ID
	CAN->sMsgObj[0].ARB1 = 0;
	CAN->sMsgObj[0].ARB2 = (CAN->sMsgObj[0].ARB2 & 0xE000) | STD_FIXED_ID_ARB(pCanMsg->Id);
  }
  else
  {
  	// extended ID
	CAN->sMsgObj[0].ARB1 = EXT_FIXED_ID_ARB_L(pCanMsg->Id);
	CAN->sMsgObj[0].ARB2 = (CAN->sMsgObj[0].ARB2 & 0xE000) | EXT_FIXED_ID_ARB_H(pCanMsg->Id);
  }

  CAN->sMsgObj[0].MSGC = (CAN->sMsgObj[0].MSGC & 0xFEF0) | CAN_CTL_NEWDAT | CAN_CTL_TXRQST | pCanMsg->Dlc;

  CAN->sMsgObj[0].DA1 = ((u16)pCanMsg->Data[1]<<8) | pCanMsg->Data[0];
  CAN->sMsgObj[0].DA2 = ((u16)pCanMsg->Data[3]<<8) | pCanMsg->Data[2];
  CAN->sMsgObj[0].DB1 = ((u16)pCanMsg->Data[5]<<8) | pCanMsg->Data[4];
  CAN->sMsgObj[0].DB2 = ((u16)pCanMsg->Data[7]<<8) | pCanMsg->Data[6];

  CAN->sMsgObj[0].COMR = 1 + msgobj;

  return 1;
}

/*******************************************************************************
* Function Name  : CAN_ReceiveMessage
* Description    : Get the message, if received
* Input 1        : message object number, from 0 to 31
* Input 2        : if TRUE, the message object is released when getting the data
*                  if FALSE, the message object is not released
* Input 3        : pointer to the message structure where received data is stored
* Output         : None
* Return         : 1 if reception was OK, else 0 (no message pending)
*******************************************************************************/
int CAN_ReceiveMessage(int msgobj, bool release, canmsg* pCanMsg)
{
    if (!CAN_IsMessageWaiting(msgobj))
    	return 0;

	CAN->SR &= ~CAN_STS_RXOK;

    // read the message contents
    CAN->sMsgObj[1].COMM = CAN_COM_MASK
	                     | CAN_COM_ARB
	                     | CAN_COM_CTRL
	                     | CAN_COM_CLRINT
	                     | (release ? CAN_COM_TXRQST : 0)
	                     | CAN_COM_DATAA
	                     | CAN_COM_DATAB;

	CAN->sMsgObj[1].COMR = 1 + msgobj;

	while (CAN->sMsgObj[1].COMR & CAN_CRQ_BUSY);

    if ((CAN->sMsgObj[1].ARB2 & CAN_ARB_XTD) == 0)
    {
  	  // standard ID
  	  pCanMsg->IdType = CAN_STD_ID;
      pCanMsg->Id = (CAN->sMsgObj[1].ARB2 >> 2) & 0x07FF;
    }
    else
    {
      // extended ID
  	  pCanMsg->IdType = CAN_EXT_ID;
      pCanMsg->Id = ((CAN->sMsgObj[1].ARB2 >> 2) & 0x07FF) | ((u32)CAN->sMsgObj[1].ARB1 << 11) | (((u32)CAN->sMsgObj[1].ARB2 & 0x0003) << 27);
    }

    pCanMsg->Dlc = CAN->sMsgObj[1].MSGC & 0x0F;

    pCanMsg->Data[0] = (u8) CAN->sMsgObj[1].DA1;
    pCanMsg->Data[1] = (u8)(CAN->sMsgObj[1].DA1 >> 8);
    pCanMsg->Data[2] = (u8) CAN->sMsgObj[1].DA2;
    pCanMsg->Data[3] = (u8)(CAN->sMsgObj[1].DA2 >> 8);
    pCanMsg->Data[4] = (u8) CAN->sMsgObj[1].DB1;
    pCanMsg->Data[5] = (u8)(CAN->sMsgObj[1].DB1 >> 8);
    pCanMsg->Data[6] = (u8) CAN->sMsgObj[1].DB2;
    pCanMsg->Data[7] = (u8)(CAN->sMsgObj[1].DB2 >> 8);

    return 1;
}

/*******************************************************************************
* Function Name  : CAN_WaitEndOfTx
* Description    : Wait until current transmission is finished
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void CAN_WaitEndOfTx(void)
{
	while ((CAN->SR & CAN_STS_TXOK) == 0);
	CAN->SR &= ~CAN_STS_TXOK;
}

/*******************************************************************************
* Function Name  : CAN_BasicSendMessage
* Description    : Start transmission of a message in BASIC mode
* Input 1        : pointer to the message structure containing data to transmit
* Output         : None
* Return         : 1 if transmission was OK, else 0
* Note           : CAN must be in BASIC mode
*******************************************************************************/
int CAN_BasicSendMessage(canmsg* pCanMsg)
{
	// clear NewDat bit in IF2 to detect next reception
	CAN->sMsgObj[1].MSGC &= ~CAN_CTL_NEWDAT;

	CAN->SR &= ~CAN_STS_TXOK;

	CAN->sMsgObj[0].COMM = CAN_COM_WRITE
  	                   | CAN_COM_ARB
  	                   | CAN_COM_CTRL
  	                   | CAN_COM_DATAA
  	                   | CAN_COM_DATAB;

	if (pCanMsg->IdType == CAN_STD_ID)
	{
	  	// standard ID
		CAN->sMsgObj[0].ARB1 = 0;
		CAN->sMsgObj[0].ARB2 = (CAN->sMsgObj[0].ARB2 & 0xE000) | STD_FIXED_ID_ARB(pCanMsg->Id);
	}
	else
	{
  		// extended ID
		CAN->sMsgObj[0].ARB1 = EXT_FIXED_ID_ARB_L(pCanMsg->Id);
		CAN->sMsgObj[0].ARB2 = (CAN->sMsgObj[0].ARB2 & 0xE000) | EXT_FIXED_ID_ARB_H(pCanMsg->Id);
	}

	CAN->sMsgObj[0].MSGC = (CAN->sMsgObj[0].MSGC & 0xFCF0) | pCanMsg->Dlc;

	CAN->sMsgObj[0].DA1 = ((u16)pCanMsg->Data[1]<<8) | pCanMsg->Data[0];
	CAN->sMsgObj[0].DA2 = ((u16)pCanMsg->Data[3]<<8) | pCanMsg->Data[2];
	CAN->sMsgObj[0].DB1 = ((u16)pCanMsg->Data[5]<<8) | pCanMsg->Data[4];
	CAN->sMsgObj[0].DB2 = ((u16)pCanMsg->Data[7]<<8) | pCanMsg->Data[6];

	// request transmission
	CAN->sMsgObj[0].COMR = CAN_CRQ_BUSY | (1 + 0);

	return 1;
}

/*******************************************************************************
* Function Name  : CAN_BasicReceiveMessage
* Description    : Get the message in BASIC mode, if received
* Input 1        : pointer to the message structure where received data is stored
* Output         : None
* Return         : 1 if reception was OK, else 0 (no message pending)
* Note           : CAN must be in BASIC mode
*******************************************************************************/
int CAN_BasicReceiveMessage(canmsg* pCanMsg)
{
	if ((CAN->sMsgObj[1].MSGC & CAN_CTL_NEWDAT) == 0)
		return 0;

	CAN->SR &= ~CAN_STS_RXOK;

	CAN->sMsgObj[1].COMM = CAN_COM_ARB
  	                   | CAN_COM_CTRL
  	                   | CAN_COM_DATAA
  	                   | CAN_COM_DATAB;

    if ((CAN->sMsgObj[1].ARB2 & CAN_ARB_XTD) == 0)
    {
  	  // standard ID
  	  pCanMsg->IdType = CAN_STD_ID;
      pCanMsg->Id = (CAN->sMsgObj[1].ARB2 >> 2) & 0x07FF;
    }
    else
    {
      // extended ID
  	  pCanMsg->IdType = CAN_EXT_ID;
      pCanMsg->Id = ((CAN->sMsgObj[1].ARB2 >> 2) & 0x07FF) | ((u32)CAN->sMsgObj[1].ARB1 << 11) | (((u32)CAN->sMsgObj[1].ARB2 & 0x0003) << 27);
    }

    pCanMsg->Dlc = CAN->sMsgObj[1].MSGC & 0x0F;

    pCanMsg->Data[0] = (u8) CAN->sMsgObj[1].DA1;
    pCanMsg->Data[1] = (u8)(CAN->sMsgObj[1].DA1 >> 8);
    pCanMsg->Data[2] = (u8) CAN->sMsgObj[1].DA2;
    pCanMsg->Data[3] = (u8)(CAN->sMsgObj[1].DA2 >> 8);
    pCanMsg->Data[4] = (u8) CAN->sMsgObj[1].DB1;
    pCanMsg->Data[5] = (u8)(CAN->sMsgObj[1].DB1 >> 8);
    pCanMsg->Data[6] = (u8) CAN->sMsgObj[1].DB2;
    pCanMsg->Data[7] = (u8)(CAN->sMsgObj[1].DB2 >> 8);

    return 1;
}

/******************* (C) COPYRIGHT 2003 STMicroelectronics *****END OF FILE****/

⌨️ 快捷键说明

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