📄 stm32f2xx_can.c
字号:
/* Initialize the automatic bus-off management */
CAN_InitStruct->CAN_ABOM = DISABLE;
/* Initialize the automatic wake-up mode */
CAN_InitStruct->CAN_AWUM = DISABLE;
/* Initialize the no automatic retransmission */
CAN_InitStruct->CAN_NART = DISABLE;
/* Initialize the receive FIFO locked mode */
CAN_InitStruct->CAN_RFLM = DISABLE;
/* Initialize the transmit FIFO priority */
CAN_InitStruct->CAN_TXFP = DISABLE;
/* Initialize the CAN_Mode member */
CAN_InitStruct->CAN_Mode = CAN_Mode_Normal;
/* Initialize the CAN_SJW member */
CAN_InitStruct->CAN_SJW = CAN_SJW_1tq;
/* Initialize the CAN_BS1 member */
CAN_InitStruct->CAN_BS1 = CAN_BS1_4tq;
/* Initialize the CAN_BS2 member */
CAN_InitStruct->CAN_BS2 = CAN_BS2_3tq;
/* Initialize the CAN_Prescaler member */
CAN_InitStruct->CAN_Prescaler = 1;
}
/**
* @brief Select the start bank filter for slave CAN.
* @param CAN_BankNumber: Select the start slave bank filter from 1..27.
* @retval None
*/
void CAN_SlaveStartBank(uint8_t CAN_BankNumber)
{
/* Check the parameters */
assert_param(IS_CAN_BANKNUMBER(CAN_BankNumber));
/* Enter Initialisation mode for the filter */
CAN1->FMR |= FMR_FINIT;
/* Select the start slave bank */
CAN1->FMR &= (uint32_t)0xFFFFC0F1 ;
CAN1->FMR |= (uint32_t)(CAN_BankNumber)<<8;
/* Leave Initialisation mode for the filter */
CAN1->FMR &= ~FMR_FINIT;
}
/**
* @brief Enables or disables the DBG Freeze for CAN.
* @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
* @param NewState: new state of the CAN peripheral.
* This parameter can be: ENABLE (CAN reception/transmission is frozen
* during debug. Reception FIFOs can still be accessed/controlled normally)
* or DISABLE (CAN is working during debug).
* @retval None
*/
void CAN_DBGFreeze(CAN_TypeDef* CANx, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_CAN_ALL_PERIPH(CANx));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable Debug Freeze */
CANx->MCR |= MCR_DBF;
}
else
{
/* Disable Debug Freeze */
CANx->MCR &= ~MCR_DBF;
}
}
/**
* @brief Enables or disables the CAN Time TriggerOperation communication mode.
* @note DLC must be programmed as 8 in order Time Stamp (2 bytes) to be
* sent over the CAN bus.
* @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
* @param NewState: Mode new state. This parameter can be: ENABLE or DISABLE.
* When enabled, Time stamp (TIME[15:0]) value is sent in the last two
* data bytes of the 8-byte message: TIME[7:0] in data byte 6 and TIME[15:8]
* in data byte 7.
* @retval None
*/
void CAN_TTComModeCmd(CAN_TypeDef* CANx, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_CAN_ALL_PERIPH(CANx));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the TTCM mode */
CANx->MCR |= CAN_MCR_TTCM;
/* Set TGT bits */
CANx->sTxMailBox[0].TDTR |= ((uint32_t)CAN_TDT0R_TGT);
CANx->sTxMailBox[1].TDTR |= ((uint32_t)CAN_TDT1R_TGT);
CANx->sTxMailBox[2].TDTR |= ((uint32_t)CAN_TDT2R_TGT);
}
else
{
/* Disable the TTCM mode */
CANx->MCR &= (uint32_t)(~(uint32_t)CAN_MCR_TTCM);
/* Reset TGT bits */
CANx->sTxMailBox[0].TDTR &= ((uint32_t)~CAN_TDT0R_TGT);
CANx->sTxMailBox[1].TDTR &= ((uint32_t)~CAN_TDT1R_TGT);
CANx->sTxMailBox[2].TDTR &= ((uint32_t)~CAN_TDT2R_TGT);
}
}
/**
* @}
*/
/** @defgroup CAN_Group2 CAN Frames Transmission functions
* @brief CAN Frames Transmission functions
*
@verbatim
===============================================================================
CAN Frames Transmission functions
===============================================================================
This section provides functions allowing to
- Initiate and transmit a CAN frame message (if there is an empty mailbox).
- Check the transmission status of a CAN Frame
- Cancel a transmit request
@endverbatim
* @{
*/
/**
* @brief Initiates and transmits a CAN frame message.
* @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
* @param TxMessage: pointer to a structure which contains CAN Id, CAN DLC and CAN data.
* @retval The number of the mailbox that is used for transmission or
* CAN_TxStatus_NoMailBox if there is no empty mailbox.
*/
uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage)
{
uint8_t transmit_mailbox = 0;
/* Check the parameters */
assert_param(IS_CAN_ALL_PERIPH(CANx));
assert_param(IS_CAN_IDTYPE(TxMessage->IDE));
assert_param(IS_CAN_RTR(TxMessage->RTR));
assert_param(IS_CAN_DLC(TxMessage->DLC));
/* Select one empty transmit mailbox */
if ((CANx->TSR&CAN_TSR_TME0) == CAN_TSR_TME0)
{
transmit_mailbox = 0;
}
else if ((CANx->TSR&CAN_TSR_TME1) == CAN_TSR_TME1)
{
transmit_mailbox = 1;
}
else if ((CANx->TSR&CAN_TSR_TME2) == CAN_TSR_TME2)
{
transmit_mailbox = 2;
}
else
{
transmit_mailbox = CAN_TxStatus_NoMailBox;
}
if (transmit_mailbox != CAN_TxStatus_NoMailBox)
{
/* Set up the Id */
CANx->sTxMailBox[transmit_mailbox].TIR &= TMIDxR_TXRQ;
if (TxMessage->IDE == CAN_Id_Standard)
{
assert_param(IS_CAN_STDID(TxMessage->StdId));
CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage->StdId << 21) | \
TxMessage->RTR);
}
else
{
assert_param(IS_CAN_EXTID(TxMessage->ExtId));
CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage->ExtId << 3) | \
TxMessage->IDE | \
TxMessage->RTR);
}
/* Set up the DLC */
TxMessage->DLC &= (uint8_t)0x0000000F;
CANx->sTxMailBox[transmit_mailbox].TDTR &= (uint32_t)0xFFFFFFF0;
CANx->sTxMailBox[transmit_mailbox].TDTR |= TxMessage->DLC;
/* Set up the data field */
CANx->sTxMailBox[transmit_mailbox].TDLR = (((uint32_t)TxMessage->Data[3] << 24) |
((uint32_t)TxMessage->Data[2] << 16) |
((uint32_t)TxMessage->Data[1] << 8) |
((uint32_t)TxMessage->Data[0]));
CANx->sTxMailBox[transmit_mailbox].TDHR = (((uint32_t)TxMessage->Data[7] << 24) |
((uint32_t)TxMessage->Data[6] << 16) |
((uint32_t)TxMessage->Data[5] << 8) |
((uint32_t)TxMessage->Data[4]));
/* Request transmission */
CANx->sTxMailBox[transmit_mailbox].TIR |= TMIDxR_TXRQ;
}
return transmit_mailbox;
}
/**
* @brief Checks the transmission status of a CAN Frame.
* @param CANx: where x can be 1 or 2 to select the CAN peripheral.
* @param TransmitMailbox: the number of the mailbox that is used for transmission.
* @retval CAN_TxStatus_Ok if the CAN driver transmits the message,
* CAN_TxStatus_Failed in an other case.
*/
uint8_t CAN_TransmitStatus(CAN_TypeDef* CANx, uint8_t TransmitMailbox)
{
uint32_t state = 0;
/* Check the parameters */
assert_param(IS_CAN_ALL_PERIPH(CANx));
assert_param(IS_CAN_TRANSMITMAILBOX(TransmitMailbox));
switch (TransmitMailbox)
{
case (CAN_TXMAILBOX_0):
state = CANx->TSR & (CAN_TSR_RQCP0 | CAN_TSR_TXOK0 | CAN_TSR_TME0);
break;
case (CAN_TXMAILBOX_1):
state = CANx->TSR & (CAN_TSR_RQCP1 | CAN_TSR_TXOK1 | CAN_TSR_TME1);
break;
case (CAN_TXMAILBOX_2):
state = CANx->TSR & (CAN_TSR_RQCP2 | CAN_TSR_TXOK2 | CAN_TSR_TME2);
break;
default:
state = CAN_TxStatus_Failed;
break;
}
switch (state)
{
/* transmit pending */
case (0x0): state = CAN_TxStatus_Pending;
break;
/* transmit failed */
case (CAN_TSR_RQCP0 | CAN_TSR_TME0): state = CAN_TxStatus_Failed;
break;
case (CAN_TSR_RQCP1 | CAN_TSR_TME1): state = CAN_TxStatus_Failed;
break;
case (CAN_TSR_RQCP2 | CAN_TSR_TME2): state = CAN_TxStatus_Failed;
break;
/* transmit succeeded */
case (CAN_TSR_RQCP0 | CAN_TSR_TXOK0 | CAN_TSR_TME0):state = CAN_TxStatus_Ok;
break;
case (CAN_TSR_RQCP1 | CAN_TSR_TXOK1 | CAN_TSR_TME1):state = CAN_TxStatus_Ok;
break;
case (CAN_TSR_RQCP2 | CAN_TSR_TXOK2 | CAN_TSR_TME2):state = CAN_TxStatus_Ok;
break;
default: state = CAN_TxStatus_Failed;
break;
}
return (uint8_t) state;
}
/**
* @brief Cancels a transmit request.
* @param CANx: where x can be 1 or 2 to select the CAN peripheral.
* @param Mailbox: Mailbox number.
* @retval None
*/
void CAN_CancelTransmit(CAN_TypeDef* CANx, uint8_t Mailbox)
{
/* Check the parameters */
assert_param(IS_CAN_ALL_PERIPH(CANx));
assert_param(IS_CAN_TRANSMITMAILBOX(Mailbox));
/* abort transmission */
switch (Mailbox)
{
case (CAN_TXMAILBOX_0): CANx->TSR |= CAN_TSR_ABRQ0;
break;
case (CAN_TXMAILBOX_1): CANx->TSR |= CAN_TSR_ABRQ1;
break;
case (CAN_TXMAILBOX_2): CANx->TSR |= CAN_TSR_ABRQ2;
break;
default:
break;
}
}
/**
* @}
*/
/** @defgroup CAN_Group3 CAN Frames Reception functions
* @brief CAN Frames Reception functions
*
@verbatim
===============================================================================
CAN Frames Reception functions
===============================================================================
This section provides functions allowing to
- Receive a correct CAN frame
- Release a specified receive FIFO (2 FIFOs are available)
- Return the number of the pending received CAN frames
@endverbatim
* @{
*/
/**
* @brief Receives a correct CAN frame.
* @param CANx: where x can be 1 or 2 to select the CAN peripheral.
* @param FIFONumber: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1.
* @param RxMessage: pointer to a structure receive frame which contains CAN Id,
* CAN DLC, CAN data and FMI number.
* @retval None
*/
void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage)
{
/* Check the parameters */
assert_param(IS_CAN_ALL_PERIPH(CANx));
assert_param(IS_CAN_FIFO(FIFONumber));
/* Get the Id */
RxMessage->IDE = (uint8_t)0x04 & CANx->sFIFOMailBox[FIFONumber].RIR;
if (RxMessage->IDE == CAN_Id_Standard)
{
RxMessage->StdId = (uint32_t)0x000007FF & (CANx->sFIFOMailBox[FIFONumber].RIR >> 21);
}
else
{
RxMessage->ExtId = (uint32_t)0x1FFFFFFF & (CANx->sFIFOMailBox[FIFONumber].RIR >> 3);
}
RxMessage->RTR = (uint8_t)0x02 & CANx->sFIFOMailBox[FIFONumber].RIR;
/* Get the DLC */
RxMessage->DLC = (uint8_t)0x0F & CANx->sFIFOMailBox[FIFONumber].RDTR;
/* Get the FMI */
RxMessage->FMI = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDTR >> 8);
/* Get the data field */
RxMessage->Data[0] = (uint8_t)0xFF & CANx->sFIFOMailBox[FIFONumber].RDLR;
RxMessage->Data[1] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 8);
RxMessage->Data[2] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 16);
RxMessage->Data[3] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 24);
RxMessage->Data[4] = (uint8_t)0xFF & CANx->sFIFOMailBox[FIFONumber].RDHR;
RxMessage->Data[5] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 8);
RxMessage->Data[6] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 16);
RxMessage->Data[7] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 24);
/* Release the FIFO */
/* Release FIFO0 */
if (FIFONumber == CAN_FIFO0)
{
CANx->RF0R |= CAN_RF0R_RFOM0;
}
/* Release FIFO1 */
else /* FIFONumber == CAN_FIFO1 */
{
CANx->RF1R |= CAN_RF1R_RFOM1;
}
}
/**
* @brief Releases the specified receive FIFO.
* @param CANx: where x can be 1 or 2 to select the CAN peripheral.
* @param FIFONumber: FIFO to release, CAN_FIFO0 or CAN_FIFO1.
* @retval None
*/
void CAN_FIFORelease(CAN_TypeDef* CANx, uint8_t FIFONumber)
{
/* Check the parameters */
assert_param(IS_CAN_ALL_PERIPH(CANx));
assert_param(IS_CAN_FIFO(FIFONumber));
/* Release FIFO0 */
if (FIFONumber == CAN_FIFO0)
{
CANx->RF0R |= CAN_RF0R_RFOM0;
}
/* Release FIFO1 */
else /* FIFONumber == CAN_FIFO1 */
{
CANx->RF1R |= CAN_RF1R_RFOM1;
}
}
/**
* @brief Returns the number of pending received messages.
* @param CANx: where x can be 1 or 2 to select the CAN peripheral.
* @param FIFONumber: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1.
* @retval NbMessage : which is the number of pending message.
*/
uint8_t CAN_MessagePending(CAN_TypeDef* CANx, uint8_t FIFONumber)
{
uint8_t message_pending=0;
/* Check the parameters */
assert_param(IS_CAN_ALL_PERIPH(CANx));
assert_param(IS_CAN_FIFO(FIFONumber));
if (FIFONumber == CAN_FIFO0)
{
message_pending = (uint8_t)(CANx->RF0R&(uint32_t)0x03);
}
else if (FIFONumber == CAN_FIFO1)
{
message_pending = (uint8_t)(CANx->RF1R&(uint32_t)0x03);
}
else
{
message_pending = 0;
}
return message_pending;
}
/**
* @}
*/
/** @defgroup CAN_Group4 CAN Operation modes functions
* @brief CAN Operation modes functions
*
@verbatim
===============================================================================
CAN Operation modes functions
===============================================================================
This section provides functions allowing to select the CAN Operation modes
- sleep mode
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -