STM32H723ZGT6 CAN1 CAN2 send and receive

Note: Discuss each other, if there is any reference, please do not use it for profit.

1. Connected to the document, this document only focuses on CAN

2. Stm32CubeMX configuration

2. Code

Note: Discuss each other, if there is any reference, please do not use it for profit.

/* Includes -------------------------------------------- ----------------------*/
#include "fdcan.h"

/* USER CODE BEGIN 0 */
#include <stdio.h>
#include <string.h>
FDCAN_TxHeaderTypeDef fdcan_TxHeader;
/* USER CODE END 0 */

FDCAN_HandleTypeDef hfdcan1;
FDCAN_HandleTypeDef hfdcan2;

/* FDCAN1 init function */
void MX_FDCAN1_Init(void)
{

  /* USER CODE BEGIN FDCAN1_Init 0 */

  /* USER CODE END FDCAN1_Init 0 */

  /* USER CODE BEGIN FDCAN1_Init 1 */

  /* USER CODE END FDCAN1_Init 1 */
  hfdcan1.Instance = FDCAN1;
  hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
  hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
  hfdcan1.Init.AutoRetransmission = DISABLE;
  hfdcan1.Init.TransmitPause = DISABLE;
  hfdcan1.Init.ProtocolException = DISABLE;
  hfdcan1.Init.NominalPrescaler = 1;
  hfdcan1.Init.NominalSyncJumpWidth = 1;
  hfdcan1.Init.NominalTimeSeg1 = 15;
  hfdcan1.Init.NominalTimeSeg2 = 4;
  hfdcan1.Init.DataPrescaler = 1;
  hfdcan1.Init.DataSyncJumpWidth = 1;
  hfdcan1.Init.DataTimeSeg1 = 0xF;
  hfdcan1.Init.DataTimeSeg2 = 0x4;
  hfdcan1.Init.MessageRAMOffset = 0;
  hfdcan1.Init.StdFiltersNbr = 1;
  hfdcan1.Init.ExtFiltersNbr = 0;
  hfdcan1.Init.RxFifo0ElmtsNbr = 32;
  hfdcan1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
  hfdcan1.Init.RxFifo1ElmtsNbr = 0;
  hfdcan1.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
  hfdcan1.Init.RxBuffersNbr = 0;
  hfdcan1.Init.RxBufferSize = FDCAN_DATA_BYTES_8;
  hfdcan1.Init.TxEventsNbr = 0;
  hfdcan1.Init.TxBuffersNbr = 0;
  hfdcan1.Init.TxFifoQueueElmtsNbr = 6;
  hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
  hfdcan1.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
  if (HAL_FDCAN_Init( & hfdcan1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN FDCAN1_Init 2 */
printf("%lx\r\
",SRAMCAN_BASE);
printf("%x\r\
",hfdcan1.msgRam.EndAddress);
FDCAN1_RX_Filter_Init();
HAL_FDCAN_Start( &hfdcan1);
\t
  /* USER CODE END FDCAN1_Init 2 */

}
/* FDCAN2 init function */
void MX_FDCAN2_Init(void)
{

  /* USER CODE BEGIN FDCAN2_Init 0 */

  /* USER CODE END FDCAN2_Init 0 */

  /* USER CODE BEGIN FDCAN2_Init 1 */

  /* USER CODE END FDCAN2_Init 1 */
  hfdcan2.Instance = FDCAN2;
  hfdcan2.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
  hfdcan2.Init.Mode = FDCAN_MODE_NORMAL;
  hfdcan2.Init.AutoRetransmission = DISABLE;
  hfdcan2.Init.TransmitPause = DISABLE;
  hfdcan2.Init.ProtocolException = DISABLE;
  hfdcan2.Init.NominalPrescaler = 1;
  hfdcan2.Init.NominalSyncJumpWidth = 1;
  hfdcan2.Init.NominalTimeSeg1 = 15;
  hfdcan2.Init.NominalTimeSeg2 = 4;
  hfdcan2.Init.DataPrescaler = 1;
  hfdcan2.Init.DataSyncJumpWidth = 1;
  hfdcan2.Init.DataTimeSeg1 = 15;
  hfdcan2.Init.DataTimeSeg2 = 4;
  hfdcan2.Init.MessageRAMOffset = 0x406;
  hfdcan2.Init.StdFiltersNbr = 1;
  hfdcan2.Init.ExtFiltersNbr = 0;
  hfdcan2.Init.RxFifo0ElmtsNbr = 0;
  hfdcan2.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
  hfdcan2.Init.RxFifo1ElmtsNbr = 32;
  hfdcan2.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
  hfdcan2.Init.RxBuffersNbr = 0;
  hfdcan2.Init.RxBufferSize = FDCAN_DATA_BYTES_8;
  hfdcan2.Init.TxEventsNbr = 0;
  hfdcan2.Init.TxBuffersNbr = 0;
  hfdcan2.Init.TxFifoQueueElmtsNbr = 6;
  hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
  hfdcan2.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
  if (HAL_FDCAN_Init( & hfdcan2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN FDCAN2_Init 2 */
FDCAN2_RX_Filter_Init();
HAL_FDCAN_Start( &hfdcan2);
\t
  /* USER CODE END FDCAN2_Init 2 */

}

static uint32_t HAL_RCC_FDCAN_CLK_ENABLED=0;

void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef* fdcanHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(fdcanHandle->Instance==FDCAN1)
  {
  /* USER CODE BEGIN FDCAN1_MspInit 0 */

  /* USER CODE END FDCAN1_MspInit 0 */
    /* FDCAN1 clock enable */
    HAL_RCC_FDCAN_CLK_ENABLED++;
    if(HAL_RCC_FDCAN_CLK_ENABLED==1){
      __HAL_RCC_FDCAN_CLK_ENABLE();
    }

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**FDCAN1 GPIO Configuration
    PA11 ------> FDCAN1_RX
    PA12 ------> FDCAN1_TX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN1;
    HAL_GPIO_Init(GPIOA, & GPIO_InitStruct);

    /* FDCAN1 interrupt Init */
    HAL_NVIC_SetPriority(FDCAN1_IT0_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn);
  /* USER CODE BEGIN FDCAN1_MspInit 1 */

  /* USER CODE END FDCAN1_MspInit 1 */
  }
  else if(fdcanHandle->Instance==FDCAN2)
  {
  /* USER CODE BEGIN FDCAN2_MspInit 0 */

  /* USER CODE END FDCAN2_MspInit 0 */
    /* FDCAN2 clock enable */
    HAL_RCC_FDCAN_CLK_ENABLED++;
    if(HAL_RCC_FDCAN_CLK_ENABLED==1){
      __HAL_RCC_FDCAN_CLK_ENABLE();
    }

    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**FDCAN2 GPIO Configuration
    PB12 ------> FDCAN2_RX
    PB6 ------> FDCAN2_TX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct. Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN2;
    HAL_GPIO_Init(GPIOB, & GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN2;
    HAL_GPIO_Init(GPIOB, & GPIO_InitStruct);

    /* FDCAN2 interrupt Init */
    HAL_NVIC_SetPriority(FDCAN2_IT0_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(FDCAN2_IT0_IRQn);
  /* USER CODE BEGIN FDCAN2_MspInit 1 */

  /* USER CODE END FDCAN2_MspInit 1 */
  }
}

void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef* fdcanHandle)
{

  if(fdcanHandle->Instance==FDCAN1)
  {
  /* USER CODE BEGIN FDCAN1_MspDeInit 0 */

  /* USER CODE END FDCAN1_MspDeInit 0 */
    /* Peripheral clock disable */
    HAL_RCC_FDCAN_CLK_ENABLED--;
    if(HAL_RCC_FDCAN_CLK_ENABLED==0){
      __HAL_RCC_FDCAN_CLK_DISABLE();
    }

    /**FDCAN1 GPIO Configuration
    PA11 ------> FDCAN1_RX
    PA12 ------> FDCAN1_TX
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);

    /* FDCAN1 interrupt Deinit */
    HAL_NVIC_DisableIRQ(FDCAN1_IT0_IRQn);
  /* USER CODE BEGIN FDCAN1_MspDeInit 1 */

  /* USER CODE END FDCAN1_MspDeInit 1 */
  }
  else if(fdcanHandle->Instance==FDCAN2)
  {
  /* USER CODE BEGIN FDCAN2_MspDeInit 0 */

  /* USER CODE END FDCAN2_MspDeInit 0 */
    /* Peripheral clock disable */
    HAL_RCC_FDCAN_CLK_ENABLED--;
    if(HAL_RCC_FDCAN_CLK_ENABLED==0){
      __HAL_RCC_FDCAN_CLK_DISABLE();
    }

    /**FDCAN2 GPIO Configuration
    PB12 ------> FDCAN2_RX
    PB6 ------> FDCAN2_TX
    */
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_12|GPIO_PIN_6);

    /* FDCAN2 interrupt Deinit */
    HAL_NVIC_DisableIRQ(FDCAN2_IT0_IRQn);
  /* USER CODE BEGIN FDCAN2_MspDeInit 1 */

  /* USER CODE END FDCAN2_MspDeInit 1 */
  }
}

/* USER CODE BEGIN 1 */

/**
  * Function: Set and initialize filter 0 for use by FDCAN1
  * Input parameters: void
  * Return value: void
  */
void FDCAN1_RX_Filter_Init(void)
{
FDCAN_FilterTypeDef hfdcan1_RX_Filter; /* FDCAN1 filter 0 object handle */
   
hfdcan1_RX_Filter.IdType = FDCAN_STANDARD_ID; /* only receive standard frame ID */
   hfdcan1_RX_Filter.FilterIndex = 0; /* filter index 0 */
   hfdcan1_RX_Filter.FilterType = FDCAN_FILTER_MASK; /* filter type */
   hfdcan1_RX_Filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; /* filter is associated to RXFIFO0 */
   hfdcan1_RX_Filter.FilterID1 = 0x111; /* filter ID1: 0x00 */
   hfdcan1_RX_Filter.FilterID2 = 0x7FF; /* filter ID2: 0x00 */
   HAL_FDCAN_ConfigFilter( & amp;hfdcan1, & amp;hfdcan1_RX_Filter); /* Check if the filter is created successfully */
   /* HAL_FDCAN_ConfigGlobalFilter()
    * Parameter 2: Set the standard frame ID. When the received message ID does not match the filter, choose to reject it (if it does not match, you can choose to put it into FIFO0 or FIFO1).
    * Parameter 3: Set the extended frame ID. When the received message ID does not match the filter, choose to reject it.
    * Parameter 4: Set whether to reject the remote standard frame, ENABLE means to refuse to receive.
    * Parameter 5: Set whether to reject the remote extension frame, ENABLE means to refuse to receive.
    */
   HAL_FDCAN_ConfigGlobalFilter( & amp;hfdcan1,FDCAN_REJECT,FDCAN_REJECT,DISABLE,ENABLE); /* Set FDCAN1 filter 0 global configuration */
HAL_FDCAN_ActivateNotification( &hfdcan1,FDCAN_IT_RX_FIFO0_NEW_MESSAGE,0);
}

/**
  * Function function: set and initialize filter 1 for use by FDCAN2
  * Input parameters: void
  * Return value: void
  */
void FDCAN2_RX_Filter_Init(void)
{
FDCAN_FilterTypeDef hfdcan2_RX_Filter; /* FDCAN2 filter 0 object handle */
   
hfdcan2_RX_Filter.IdType = FDCAN_STANDARD_ID; /* only receive standard frame ID */
   hfdcan2_RX_Filter.FilterIndex = 0; /* filter index 0 */
   hfdcan2_RX_Filter.FilterType = FDCAN_FILTER_MASK; /* filter type (the ID range allowed to receive messages is FilterID1 to FilterID2 */
   hfdcan2_RX_Filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO1; /* filter is associated to RXFIFO1 */
   hfdcan2_RX_Filter.FilterID1 = 0x111; /* Filter ID1: 0x00 */
   hfdcan2_RX_Filter.FilterID2 = 0x7FF; /* Filter ID2: 0x00 */
   HAL_FDCAN_ConfigFilter( & amp;hfdcan2, & amp;hfdcan2_RX_Filter); /* Check if the filter is created successfully */

   /* HAL_FDCAN_ConfigGlobalFilter()
    * Parameter 2: Set the standard frame ID. When the received message ID does not match the filter, choose to reject it (if it does not match, you can choose to put it into FIFO0 or FIFO1).
    * Parameter 3: Set the extended frame ID. When the received message ID does not match the filter, choose to reject it.
    * Parameter 4: Set whether to reject the remote standard frame, ENABLE means to refuse to receive.
    * Parameter 5: Set whether to reject the remote extension frame, ENABLE means to refuse to receive.
    */
   HAL_FDCAN_ConfigGlobalFilter( & amp;hfdcan2,FDCAN_REJECT,FDCAN_REJECT,DISABLE,ENABLE); /* Set FDCAN1 filter 1 global configuration */
HAL_FDCAN_ActivateNotification( &hfdcan2,FDCAN_IT_RX_FIFO1_NEW_MESSAGE,0);
}

/**
  * Function function: FDCAN2 start
  * Input parameter: uint8_t canordernumber CAN1 is 1 CAN2 is 2
  * Input parameters: uint8_t sendcanid canid of sending data
* Input parameters: uint8_t* msg Array of sent data
* Input parameters: uint32_t len length of sent data
  * Return value: uint8_t returns data 1 on success, returns data 0 on failure
  * illustrate:     
  */
uint8_t FDCAN_Send_Msg(uint8_t canordernumber, uint32_t sendcanid, uint8_t* msg, uint32_t len)
{
static uint8_t msgdata[10]={0};
memcpy(msgdata,msg,len);
    fdcan_TxHeader.Identifier=sendcanid; //32-bit ID
    fdcan_TxHeader.IdType=FDCAN_STANDARD_ID; //Standard ID
    fdcan_TxHeader.TxFrameType=FDCAN_DATA_FRAME; //data frame
    fdcan_TxHeader.DataLength=FDCAN_DLC_BYTES_8; //data length
    fdcan_TxHeader.ErrorStateIndicator=FDCAN_ESI_ACTIVE;
    fdcan_TxHeader.BitRateSwitch=FDCAN_BRS_OFF; //Turn off rate switching
    fdcan_TxHeader.FDFormat=FDCAN_CLASSIC_CAN; //Traditional CAN mode
    fdcan_TxHeader.TxEventFifoControl=FDCAN_NO_TX_EVENTS; //No send event
    fdcan_TxHeader.MessageMarker=0;
    
if(canordernumber==1)
{
if(HAL_FDCAN_AddMessageToTxFifoQ( & amp;hfdcan1, & amp;fdcan_TxHeader,msgdata)!=HAL_OK) return 1;//send
}
else if(canordernumber==2)
{
if(HAL_FDCAN_AddMessageToTxFifoQ( & amp;hfdcan2, & amp;fdcan_TxHeader,msgdata)!=HAL_OK) return 1;//send
}
    return 0;
}

/**
  * Function: FIFO0 receive interrupt callback function
  * Input parameters: RxFifo0ITs: return flag bit
  * Return value: void
  * illustrate:
  * 1. FDCAN1 uses RXFIFO0
  */
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
uint8_t i=0;
    uint8_t rxdata[8];
FDCAN_RxHeaderTypeDef FDCAN1_RxHeader;
    if((RxFifo0ITs & amp;FDCAN_IT_RX_FIFO0_NEW_MESSAGE)!=RESET) //FIFO0 new data interrupt
    {
        //Extract the data received in FIFO0
        HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, & FDCAN1_RxHeader, rxdata);
        printf("id:%#x\r\
",FDCAN1_RxHeader.Identifier);
        printf("len:%d\r\
",FDCAN1_RxHeader.DataLength>>16);
        for(i=0;i<8;i ++ )
        printf("rxdata[%d]:%d\r\
",i,rxdata[i]);
\t\t\t
FDCAN_Send_Msg(1, FDCAN1_RxHeader.Identifier, rxdata, 8);
    }
}


/**
  * Function: FIFO1 receiving interrupt callback function
  * Input parameters: RxFifo0ITs: return flag bit
  * Return value: void
  * illustrate:
  * 1. FDCAN2 uses RXFIFO1
  */
void HAL_FDCAN_RxFifo1Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo1ITs)
{
uint8_t i=0;
    uint8_t rxdata[8];
FDCAN_RxHeaderTypeDef FDCAN2_RxHeader;
    if((RxFifo1ITs & amp;FDCAN_IT_RX_FIFO1_NEW_MESSAGE)!=RESET) //FIFO1 new data interrupt
    {
        //Extract the data received in FIFO0
        HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO1, & amp; FDCAN2_RxHeader, rxdata);
        printf("id:%#x\r\
",FDCAN2_RxHeader.Identifier);
        printf("len:%d\r\
",FDCAN2_RxHeader.DataLength>>16);
        for(i=0;i<8;i ++ )
        printf("rxdata[%d]:%d\r\
",i,rxdata[i]);
FDCAN_Send_Msg(2, FDCAN2_RxHeader.Identifier, rxdata, 8);
    }
}



/* USER CODE END 1 */