📄 73x_can.c
字号:
if (idType == CAN_STD_ID)
{
CANx->sMsgObj[msg_if].M2R = CAN_M2R_MDIR;
CANx->sMsgObj[msg_if].A2R = CAN_A2R_MSGVAL | CAN_A2R_DIR;
}
else
{
CANx->sMsgObj[msg_if].M2R = CAN_M2R_MDIR | CAN_M2R_MXTD;
CANx->sMsgObj[msg_if].A2R = CAN_A2R_MSGVAL | CAN_A2R_DIR | CAN_A2R_XTD;
}
CANx->sMsgObj[msg_if].MCR = CAN_MCR_TXIE | CAN_MCR_EOB;
CANx->sMsgObj[msg_if].DA1R = 0;
CANx->sMsgObj[msg_if].DA2R = 0;
CANx->sMsgObj[msg_if].DB1R = 0;
CANx->sMsgObj[msg_if].DB2R = 0;
CANx->sMsgObj[msg_if].CRR = 1 + msgobj;
}
/**************************************************************************************/
/* Function Name : CAN_SetRxMsgObj */
/* Description : Configure the message object as RX */
/* Input : - CANx: where x can be 0, 1 or 2 to select the CAN peripheral */
/* - Message object number, from 0 to 31 */
/* - CAN_STD_ID or CAN_EXT_ID */
/* - low part of the identifier range used for acceptance filtering */
/* - high part of the identifier range used for acceptance filtering */
/* - TRUE for a single receive object or a FIFO receive object that */
/* is the last one of the FIFO */
/* - FALSE for a FIFO receive object that is not the last one */
/* Output : None */
/* Return : None */
/**************************************************************************************/
void CAN_SetRxMsgObj(CAN_TypeDef *CANx, u32 msgobj, u32 idType, u32 idLow, u32 idHigh, bool singleOrFifoLast)
{
u32 msg_if;
while ((msg_if = CAN_GetFreeIF(CANx)) == 2);
CANx->sMsgObj[msg_if].CMR = CAN_CMR_WRRD
| CAN_CMR_MASK
| CAN_CMR_ARB
| CAN_CMR_CONTROL
| CAN_CMR_DATAA
| CAN_CMR_DATAB;
if (idType == CAN_STD_ID)
{
CANx->sMsgObj[msg_if].M1R = 0;
CANx->sMsgObj[msg_if].M2R = STD_RANGE_ID_MSK(idLow, idHigh);
CANx->sMsgObj[msg_if].A1R = 0;
CANx->sMsgObj[msg_if].A2R = CAN_A2R_MSGVAL | STD_RANGE_ID_ARB(idLow, idHigh);
}
else
{
CANx->sMsgObj[msg_if].M1R = EXT_RANGE_ID_MSK_L(idLow, idHigh);
CANx->sMsgObj[msg_if].M2R = CAN_M2R_MXTD | EXT_RANGE_ID_MSK_H(idLow, idHigh);
CANx->sMsgObj[msg_if].A1R = EXT_RANGE_ID_ARB_L(idLow, idHigh);
CANx->sMsgObj[msg_if].A2R = CAN_A2R_MSGVAL | CAN_A2R_XTD | EXT_RANGE_ID_ARB_H(idLow, idHigh);
}
CANx->sMsgObj[msg_if].MCR = CAN_MCR_RXIE | CAN_MCR_UMASK | (singleOrFifoLast ? CAN_MCR_EOB : 0);
CANx->sMsgObj[msg_if].DA1R = 0;
CANx->sMsgObj[msg_if].DA2R = 0;
CANx->sMsgObj[msg_if].DB1R = 0;
CANx->sMsgObj[msg_if].DB2R = 0;
CANx->sMsgObj[msg_if].CRR = 1 + msgobj;
}
/*******************************************************************************/
/* Function Name : CAN_InvalidateAllMsgObj */
/* Description : Configure all the message objects as unused */
/* Input : CANx: where x can be 0, 1 or 2 to select the CAN peripheral*/
/* Output : None */
/* Return : None */
/*******************************************************************************/
void CAN_InvalidateAllMsgObj(CAN_TypeDef *CANx)
{
u32 i;
for (i = 32; i != 0; i--)
CAN_SetUnusedMsgObj(CANx, 32-i);
}
/*********************************************************************************/
/* Function Name : CAN_ReleaseMessage */
/* Description : Release the message object */
/* Input : -CANx: where x can be 0, 1 or 2 to select the CAN peripheral */
/* -Message object number, from 0 to 31 */
/* Output : None */
/* Return : None */
/*********************************************************************************/
void CAN_ReleaseMessage(CAN_TypeDef *CANx, u32 msgobj)
{
u32 i;
while ((i = CAN_GetFreeIF(CANx)) == 2);
CANx->sMsgObj[i].CMR = CAN_CMR_CLRINTPND | CAN_CMR_TXRQSTNEWDAT;
CANx->sMsgObj[i].CRR = 1 + msgobj;
}
/**********************************************************************************/
/* Function Name : CAN_SendMessage */
/* Description : Start transmission of a message */
/* Input : - CANx: where x can be 0, 1 or 2 to select the CAN peripheral */
/* - Message object number, from 0 to 31 */
/* : - Pointer to the message structure containing data to transmit*/
/* Output : None */
/* Return : 1 if transmission was OK, else 0 */
/**********************************************************************************/
u32 CAN_SendMessage(CAN_TypeDef *CANx, u32 msgobj, canmsg* pCanMsg)
{
while (CANx->sMsgObj[0].CRR & CAN_CRR_BUSY);
CANx->SR &= ~CAN_SR_TXOK;
/* read the Arbitration and Message Control*/
CANx->sMsgObj[0].CMR = CAN_CMR_ARB | CAN_CMR_CONTROL;
CANx->sMsgObj[0].CRR = 1 + msgobj;
while (CANx->sMsgObj[0].CRR & CAN_CRR_BUSY);
/* update the contents needed for transmission*/
CANx->sMsgObj[0].CMR = CAN_CMR_WRRD
| CAN_CMR_ARB
| CAN_CMR_CONTROL
| CAN_CMR_DATAA
| CAN_CMR_DATAB;
if ((CANx->sMsgObj[0].A2R & CAN_A2R_XTD) == 0)
{
/* standard ID*/
CANx->sMsgObj[0].A1R = 0;
CANx->sMsgObj[0].A2R = (CANx->sMsgObj[0].A2R & 0xE000) | STD_FIXED_ID_ARB(pCanMsg->Id);
}
else
{
/* extended ID*/
CANx->sMsgObj[0].A1R = EXT_FIXED_ID_ARB_L(pCanMsg->Id);
CANx->sMsgObj[0].A2R = (CANx->sMsgObj[0].A2R & 0xE000) | EXT_FIXED_ID_ARB_H(pCanMsg->Id);
}
CANx->sMsgObj[0].MCR = (CANx->sMsgObj[0].MCR & 0xFEF0) | CAN_MCR_NEWDAT | CAN_MCR_TXRQST | pCanMsg->Dlc;
CANx->sMsgObj[0].DA1R = ((u16)pCanMsg->Data[1]<<8) | pCanMsg->Data[0];
CANx->sMsgObj[0].DA2R = ((u16)pCanMsg->Data[3]<<8) | pCanMsg->Data[2];
CANx->sMsgObj[0].DB1R = ((u16)pCanMsg->Data[5]<<8) | pCanMsg->Data[4];
CANx->sMsgObj[0].DB2R = ((u16)pCanMsg->Data[7]<<8) | pCanMsg->Data[6];
CANx->sMsgObj[0].CRR = 1 + msgobj;
return 1;
}
/************************************************************************************/
/* Function Name : CAN_ReceiveMessage */
/* Description : Get the message, if received */
/* Input : -CANx: where x can be 0, 1 or 2 to select the CAN peripheral */
/* -Message object number, from 0 to 31 */
/* -if TRUE, the message object is released when getting the data */
/* if FALSE, the message object is not released */
/* -Pointer to the message structure where received data is stored */
/* Output : None */
/* Return : 1 if reception was OK, else 0 (no message pending) */
/************************************************************************************/
u32 CAN_ReceiveMessage(CAN_TypeDef *CANx, u32 msgobj, bool release, canmsg* pCanMsg)
{
u32 tmpId0 = 0;
u32 tmpId1 = 0;
if (!CAN_IsMessageWaiting(CANx, msgobj))
return 0;
CANx->SR &= ~CAN_SR_RXOK;
/* read the message contents*/
CANx->sMsgObj[1].CMR = CAN_CMR_MASK
| CAN_CMR_ARB
| CAN_CMR_CONTROL
| CAN_CMR_CLRINTPND
| (release ? CAN_CMR_TXRQSTNEWDAT : 0)
| CAN_CMR_DATAA
| CAN_CMR_DATAB;
CANx->sMsgObj[1].CRR = 1 + msgobj;
while (CANx->sMsgObj[1].CRR & CAN_CRR_BUSY);
if ((CANx->sMsgObj[1].A2R & CAN_A2R_XTD) == 0)
{
/* standard ID*/
pCanMsg->IdType = CAN_STD_ID;
pCanMsg->Id = (CANx->sMsgObj[1].A2R >> 2) & 0x07FF;
}
else
{
/* extended ID*/
pCanMsg->IdType = CAN_EXT_ID;
tmpId0 = ((u32)CANx->sMsgObj[1].A1R << 11);
tmpId1 = (((u32)CANx->sMsgObj[1].A2R & 0x0003) << 27);
pCanMsg->Id = ((CANx->sMsgObj[1].A2R >> 2) & 0x07FF) | tmpId0 |tmpId1 ;
}
pCanMsg->Dlc = CANx->sMsgObj[1].MCR & 0x0F;
pCanMsg->Data[0] = (u8) CANx->sMsgObj[1].DA1R;
pCanMsg->Data[1] = (u8)(CANx->sMsgObj[1].DA1R >> 8);
pCanMsg->Data[2] = (u8) CANx->sMsgObj[1].DA2R;
pCanMsg->Data[3] = (u8)(CANx->sMsgObj[1].DA2R >> 8);
pCanMsg->Data[4] = (u8) CANx->sMsgObj[1].DB1R;
pCanMsg->Data[5] = (u8)(CANx->sMsgObj[1].DB1R >> 8);
pCanMsg->Data[6] = (u8) CANx->sMsgObj[1].DB2R;
pCanMsg->Data[7] = (u8)(CANx->sMsgObj[1].DB2R >> 8);
return 1;
}
/********************************************************************************/
/* Function Name : CAN_WaitEndOfTx */
/* Description : Wait until current transmission is finished */
/* Input : CANx: where x can be 0, 1 or 2 to select the CAN peripheral */
/* Output : None */
/* Return : None */
/********************************************************************************/
void CAN_WaitEndOfTx(CAN_TypeDef *CANx)
{
while ((CANx->SR & CAN_SR_TXOK) == 0);
CANx->SR &= ~CAN_SR_TXOK;
}
/*********************************************************************************/
/* Function Name : CAN_BasicSendMessage */
/* Description : Start transmission of a message in BASIC mode */
/* Input : -CANx: where x can be 0, 1 or 2 to select the CAN peripheral */
/* -Pointer to the message structure containing data to transmit*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -