eric2013 发表于 2023-10-24 08:21:50

STM32F4 HAL库的三个发送邮箱处理方法




框图:



HAL库的处理,库本身做的处理:

/**
* @briefAdd a message to the first free Tx mailbox and activate the
*         corresponding transmission request.
* @paramhcan pointer to a CAN_HandleTypeDef structure that contains
*         the configuration information for the specified CAN.
* @parampHeader pointer to a CAN_TxHeaderTypeDef structure.
* @paramaData array containing the payload of the Tx frame.
* @parampTxMailbox pointer to a variable where the function will return
*         the TxMailbox used to store the Tx message.
*         This parameter can be a value of @arg CAN_Tx_Mailboxes.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_CAN_AddTxMessage(CAN_HandleTypeDef *hcan, CAN_TxHeaderTypeDef *pHeader, uint8_t aData[], uint32_t *pTxMailbox)
{
uint32_t transmitmailbox;
HAL_CAN_StateTypeDef state = hcan->State;
uint32_t tsr = READ_REG(hcan->Instance->TSR);

/* Check the parameters */
assert_param(IS_CAN_IDTYPE(pHeader->IDE));
assert_param(IS_CAN_RTR(pHeader->RTR));
assert_param(IS_CAN_DLC(pHeader->DLC));
if (pHeader->IDE == CAN_ID_STD)
{
    assert_param(IS_CAN_STDID(pHeader->StdId));
}
else
{
    assert_param(IS_CAN_EXTID(pHeader->ExtId));
}
assert_param(IS_FUNCTIONAL_STATE(pHeader->TransmitGlobalTime));

if ((state == HAL_CAN_STATE_READY) ||
      (state == HAL_CAN_STATE_LISTENING))
{
    /* Check that all the Tx mailboxes are not full */
    if (((tsr & CAN_TSR_TME0) != 0U) ||
      ((tsr & CAN_TSR_TME1) != 0U) ||
      ((tsr & CAN_TSR_TME2) != 0U))
    {
      /* Select an empty transmit mailbox */
      transmitmailbox = (tsr & CAN_TSR_CODE) >> CAN_TSR_CODE_Pos;

      /* Check transmit mailbox value */
      if (transmitmailbox > 2U)
      {
      /* Update error code */
      hcan->ErrorCode |= HAL_CAN_ERROR_INTERNAL;

      return HAL_ERROR;
      }

      /* Store the Tx mailbox */
      *pTxMailbox = (uint32_t)1 << transmitmailbox;

      /* Set up the Id */
      if (pHeader->IDE == CAN_ID_STD)
      {
      hcan->Instance->sTxMailBox.TIR = ((pHeader->StdId << CAN_TI0R_STID_Pos) |
                                                         pHeader->RTR);
      }
      else
      {
      hcan->Instance->sTxMailBox.TIR = ((pHeader->ExtId << CAN_TI0R_EXID_Pos) |
                                                         pHeader->IDE |
                                                         pHeader->RTR);
      }

      /* Set up the DLC */
      hcan->Instance->sTxMailBox.TDTR = (pHeader->DLC);

      /* Set up the Transmit Global Time mode */
      if (pHeader->TransmitGlobalTime == ENABLE)
      {
      SET_BIT(hcan->Instance->sTxMailBox.TDTR, CAN_TDT0R_TGT);
      }

      /* Set up the data field */
      WRITE_REG(hcan->Instance->sTxMailBox.TDHR,
                ((uint32_t)aData << CAN_TDH0R_DATA7_Pos) |
                ((uint32_t)aData << CAN_TDH0R_DATA6_Pos) |
                ((uint32_t)aData << CAN_TDH0R_DATA5_Pos) |
                ((uint32_t)aData << CAN_TDH0R_DATA4_Pos));
      WRITE_REG(hcan->Instance->sTxMailBox.TDLR,
                ((uint32_t)aData << CAN_TDL0R_DATA3_Pos) |
                ((uint32_t)aData << CAN_TDL0R_DATA2_Pos) |
                ((uint32_t)aData << CAN_TDL0R_DATA1_Pos) |
                ((uint32_t)aData << CAN_TDL0R_DATA0_Pos));

      /* Request transmission */
      SET_BIT(hcan->Instance->sTxMailBox.TIR, CAN_TI0R_TXRQ);

      /* Return function status */
      return HAL_OK;
    }
    else
    {
      /* Update error code */
      hcan->ErrorCode |= HAL_CAN_ERROR_PARAM;

      return HAL_ERROR;
    }
}
else
{
    /* Update error code */
    hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;

    return HAL_ERROR;
}
}

Y1ng 发表于 2024-1-14 19:26:38

这一段代码怎么用?

eric2013 发表于 2024-1-15 01:39:00

Y1ng 发表于 2024-1-14 19:26
这一段代码怎么用?

直接调用就行,HAL库的这个API自动从里面选择选择可用的发送邮箱了。

基于STM32F429的HAL版双CAN通信案例(2023-10-24)
https://www.armbbs.cn/forum.php?mod=viewthread&tid=121523&fromuid=58
(出处: 硬汉嵌入式论坛)
页: [1]
查看完整版本: STM32F4 HAL库的三个发送邮箱处理方法