📄 drvcan.c
字号:
u8Tseg1 = 2;
u8Tseg2 = 3;
u32value = DrvSYS_GetHCLKFreq()/1000;
if(u32kbps*8 < (u32value/2))
u32Bpr = DrvSYS_GetHCLKFreq()/(u32kbps*1000) / (u8Tseg1 + u8Tseg2 + 3) -1;
else
{
u8Tseg1 = 2;
u8Tseg2 = 1;
u32Bpr = DrvSYS_GetHCLKFreq()/(u32kbps*1000) / (u8Tseg1 + u8Tseg2 + 3) -1;
}
CAN->BTIME.TSEG1 = u8Tseg1;
CAN->BTIME.TSEG2 = u8Tseg2;
CAN->BTIME.BRP = u32Bpr & 0x3F ;
CAN->u32BRPE = (u32Bpr >> 6) & 0x0F;
/* Check the result is OK */
if ((u32kbps < (DrvCAN_GetCANBitRate()*95/100)) || (u32kbps > (DrvCAN_GetCANBitRate()*105/100)))
{
DEBUG_PRINTF("\nCurrent CAN bitrate = %d\n",DrvCAN_GetCANBitRate());
return E_DRVCAN_ERR_BITRATE;
}
DrvCAN_LeaveInitMode();
return E_SUCCESS;
}
/*---------------------------------------------------------------------------------------------------------*/
/* Function: DrvCAN_SetTiming */
/* */
/* Parameter: */
/* -u8Tseg1: specifies Time Segment before the sample point. */
/* This parameter must be a number between 1 and 16. */
/* -u8Tseg2: Time Segment after the sample point. This parameter */
/* must be a number between 1 and 8. */
/* -u8Sjw: Synchronisation Jump Width. This parameter must be */
/* a number between 1 and 4. */
/* -u32Brp: Baud Rate Prescaler. This parameter must be a number */
/* between 1 and 1024. */
/* Returns: */
/* None */
/* Description: */
/* Setups the CAN timing with specific parameters */
/* Note: */
/* Shown CAN bit-rate calculation equation as below: */
/* */
/* Fin */
/* Bit-Rate (kbps) = ______________________________________ */
/* (u32Brp + 1) x (u8Tseg1 + u8Tseg1 +3) */
/* */
/* where: Fin : System clock freq. (Hz) */
/* u32Brp: the baud rate prescale .You can set brp bit field of BTIME register */
/* BRPE bit feild in BRPE reigster */
/* u8Tseg1: Time Segment before the sample point. */
/* You can set tseg1 bit field of BTIME register */
/* u8Tseg2: Time Segment ater the sample point. */
/* You can set tseg2 bit field of BTIME register */
/* u32Brp: The baud rate prescale. */
/* It is composed of BRP in CAN_BTIME register and BRPE */
/* in CAN_BRPE register. */
/* Example: */
/* Assume System clock (Fin) = 16MHz, and set u32Brp=1,u8Tseg1=2,u8Tseg2=3 */
/* */
/* According above equations: */
/* 16000000 */
/* CAN bit-rate = _________________________ = 1MHz */
/* (1 + 1) x ( 2 + 3 + 3) */
/* */
/*---------------------------------------------------------------------------------------------------------*/
void DrvCAN_SetTiming(uint8_t u8Tseg2, uint8_t u8Tseg1, uint8_t u8Sjw, uint32_t u32Brp)
{
CAN->BTIME.TSEG1 = u8Tseg1;
CAN->BTIME.TSEG2 = u8Tseg2;
CAN->BTIME.SJW = u8Sjw;
CAN->BTIME.BRP = u32Brp & 0x3F ;
CAN->u32BRPE = (u32Brp >> 6) & 0x0F;
}
/*---------------------------------------------------------------------------------------------------------*/
/* Function: DrvCAN_ResetMsgObj */
/* */
/* Parameter: */
/* u8MsgObj: specifies the Message object number, from 0 to 31. */
/* Returns: */
/* - E_SUCCESS: SUCCESS */
/* - E_DRVCAN_NO_USEFUL_INTERFACE: No useful interface */
/* Description: */
/* Configures the target message object as default */
/*---------------------------------------------------------------------------------------------------------*/
int32_t DrvCAN_ResetMsgObj(uint8_t u8MsgObj)
{
uint8_t u8MsgIfNum=0;
if ((u8MsgIfNum = GetFreeIF()) == 2)
{
return E_DRVCAN_NO_USEFUL_INTERFACE;
}
CAN->sMsgObj[u8MsgIfNum].u32CMASK = 0xF3; /*CAN_CMASK_WRRD| CAN_CMASK_MASK | CAN_CMASK_ARB
| CAN_CMASK_CONTROL | CAN_CMASK_DATAA | CAN_CMASK_DATAB; */
CAN->sMsgObj[u8MsgIfNum].u32MASK1 = 0;
CAN->sMsgObj[u8MsgIfNum].u32MASK2 = 0;
CAN->sMsgObj[u8MsgIfNum].u32ARB1 = 0;
CAN->sMsgObj[u8MsgIfNum].u32ARB2 = 0;
CAN->sMsgObj[u8MsgIfNum].u32MCON = 0;
CAN->sMsgObj[u8MsgIfNum].u32DAT_A1 = 0;
CAN->sMsgObj[u8MsgIfNum].u32DAT_A2 = 0;
CAN->sMsgObj[u8MsgIfNum].u32DAT_B1 = 0;
CAN->sMsgObj[u8MsgIfNum].u32DAT_B2 = 0;
CAN->sMsgObj[u8MsgIfNum].u32CREQ = 1 + u8MsgObj;
return E_SUCCESS;
}
/*---------------------------------------------------------------------------------------------------------*/
/* Function: DrvCAN_ResetAllMsgObj */
/* */
/* Parameter: */
/* None */
/* Returns: */
/* None */
/* Description: */
/* Configures all of the message objects as default. */
/*---------------------------------------------------------------------------------------------------------*/
void DrvCAN_ResetAllMsgObj(void)
{
uint32_t i=0;
for (i = 0; i < 32; i++)
DrvCAN_ResetMsgObj(i);
}
/*---------------------------------------------------------------------------------------------------------*/
/* Function: DrvCAN_SetTxMsgObj */
/* */
/* Parameter: */
/* - u8MsgObj: specifies the Message object number, from 0 to 31. */
/* - pCanMsg: pointer to the message structure where received data is copied. */
/* Returns: */
/* - E_SUCCESS: SUCCESS */
/* - E_DRVCAN_NO_USEFUL_INTERFACE :No useful interface */
/* Description: */
/* The function is used to configure a transmit object . */
/*---------------------------------------------------------------------------------------------------------*/
int32_t DrvCAN_SetTxMsgObj(uint8_t u8MsgObj, STR_CANMSG_T* pCanMsg)
{
uint8_t u8MsgIfNum=0;
if ((u8MsgIfNum = GetFreeIF()) == 2) /* Check Free Interface for configure */
{
return E_DRVCAN_NO_USEFUL_INTERFACE;
}
/* update the contents needed for transmission*/
CAN->sMsgObj[u8MsgIfNum].u32CMASK = 0xF3; /*CAN_CMASK_WRRD| CAN_CMASK_MASK | CAN_CMASK_ARB
| CAN_CMASK_CONTROL | CAN_CMASK_DATAA | CAN_CMASK_DATAB; */
if (pCanMsg->IdType == CAN_STD_ID)
{
/* standard ID*/
CAN->sMsgObj[u8MsgIfNum].u32ARB1 = 0;
CAN->sMsgObj[u8MsgIfNum].u32ARB2 = (((pCanMsg->Id)&0x7FF)<<2) | CAN_ARB2_DIR | CAN_ARB2_MSGVAL;
}
else
{
/* extended ID*/
CAN->sMsgObj[u8MsgIfNum].u32ARB1 = (pCanMsg->Id)&0xFFFF;
CAN->sMsgObj[u8MsgIfNum].u32ARB2 = ((pCanMsg->Id)&0x1FF0000)>>16 | CAN_ARB2_DIR | CAN_ARB2_XTD | CAN_ARB2_MSGVAL;
}
CAN->sMsgObj[u8MsgIfNum].ARB2.DIR =pCanMsg->FrameType?1:0;
CAN->sMsgObj[u8MsgIfNum].u32DAT_A1 = ((uint16_t)pCanMsg->Data[1]<<8) | pCanMsg->Data[0];
CAN->sMsgObj[u8MsgIfNum].u32DAT_A2 = ((uint16_t)pCanMsg->Data[3]<<8) | pCanMsg->Data[2];
CAN->sMsgObj[u8MsgIfNum].u32DAT_B1 = ((uint16_t)pCanMsg->Data[5]<<8) | pCanMsg->Data[4];
CAN->sMsgObj[u8MsgIfNum].u32DAT_B2 = ((uint16_t)pCanMsg->Data[7]<<8) | pCanMsg->Data[6];
CAN->sMsgObj[u8MsgIfNum].u32MCON = CAN_MCON_NEWDAT | pCanMsg->DLC |CAN_MCON_TXIE | CAN_MCON_EOB;
CAN->sMsgObj[u8MsgIfNum].u32CREQ = 1 + u8MsgObj;
return E_SUCCESS;
}
/*---------------------------------------------------------------------------------------------------------*/
/* Function: DrvCAN_SetMsgObjMask */
/* */
/* Parameter: */
/* - u8MsgObj: specifies the Message object number, from 0 to 31. */
/* - MaskMsg: specifies the mask structure as message object */
/* The structure is including */
/* - u8Xtd ( Mask IDE bit) */
/* - u8Dir ( Mask Direction) */
/* - u32Id ( Mask ID bit) */
/* - u8IdType ( Mask ID Type) */
/* Set '0' means DON'T CARE , disable accpetance filter */
/* */
/* Returns: */
/* - E_SUCCESS: SUCCESS */
/* - E_DRVCAN_NO_USEFUL_INTERFACE: No useful interface */
/* Description: */
/* Configures Mask as the message object */
/*---------------------------------------------------------------------------------------------------------*/
int32_t DrvCAN_SetMsgObjMask(uint8_t u8MsgObj,STR_CANMASK_T* MaskMsg)
{
uint8_t u8MsgIfNum=0;
if ((u8MsgIfNum = GetFreeIF()) == 2) /* Check Free Interface for configure */
{
return E_DRVCAN_NO_USEFUL_INTERFACE;
}
if (MaskMsg->u8IdType == CAN_STD_ID) /* standard ID*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -