慕容雪花 发表于 2024-3-4 11:09

【ST NUCLEO-U5A5ZJ-Q开发板测评】-6-FDCAN体验

<div class='showpostmsg'> 本帖最后由 慕容雪花 于 2024-3-4 12:54 编辑

<p>U5系列器件的FDCAN非常方便,可以支持CAN-FD也支持经典CAN 2.0.本次实验主要用到的工具和器件:</p>

<ul>
        <li>STM32U5A5ZJ-Q</li>
        <li>TJA1050 CAN收发器</li>
        <li>CAN LIN TOOL V5.0</li>
</ul>

<p>CAN收发引脚使用PB8和PB9:</p>

<div style="text-align: center;"></div>

<p>&nbsp;</p>

<p>TJA1050的原理图:</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>在CubeIde里面配置:</p>

<div style="text-align: center;"></div>

<p>&nbsp;</p>

<p>FDCAN时钟:64Mhz</p>

<div style="text-align: center;"></div>

<p>&nbsp;</p>

<p>CAN相关时序参数和工作模式:</p>

<div style="text-align: center;"></div>

<p>保存,自动生成代码:</p>

<pre>
<code class="language-cpp">static 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.ClockDivider = FDCAN_CLOCK_DIV1;
hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
hfdcan1.Init.AutoRetransmission = ENABLE;
hfdcan1.Init.TransmitPause = ENABLE;
hfdcan1.Init.ProtocolException = DISABLE;
hfdcan1.Init.NominalPrescaler = 16;
hfdcan1.Init.NominalSyncJumpWidth = 1;
hfdcan1.Init.NominalTimeSeg1 = 5;
hfdcan1.Init.NominalTimeSeg2 = 2;
hfdcan1.Init.DataPrescaler = 1;
hfdcan1.Init.DataSyncJumpWidth = 1;
hfdcan1.Init.DataTimeSeg1 = 1;
hfdcan1.Init.DataTimeSeg2 = 1;
hfdcan1.Init.StdFiltersNbr = 0;
hfdcan1.Init.ExtFiltersNbr = 0;
hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
if (HAL_FDCAN_Init(&amp;hfdcan1) != HAL_OK)
{
    Error_Handler();
}
/* USER CODE BEGIN FDCAN1_Init 2 */

/* USER CODE END FDCAN1_Init 2 */

}</code></pre>

<p>添加自定义的测试数据:</p>

<pre>
<code class="language-cpp">FDCAN_FilterTypeDef sFilterConfig;
FDCAN_TxHeaderTypeDef TxHeader;
FDCAN_RxHeaderTypeDef RxHeader;
uint8_t TxData0[] = {0x10, 0x32, 0x54, 0x76, 0x98, 0x00, 0x11, 0x22};
uint8_t TxData1[] = {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
uint8_t TxData2[] = {0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00};</code></pre>

<p>添加相关的过滤器:</p>

<pre>
<code class="language-cpp">void MY_FDCAN_CONFIG(void){
        /*##-1 Configure the FDCAN filters ########################################*/
        /* Configure standard ID reception filter to Rx FIFO 0 */
        sFilterConfig.IdType = FDCAN_STANDARD_ID;
        sFilterConfig.FilterIndex = 0;
        sFilterConfig.FilterType = FDCAN_FILTER_DUAL;
        sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
        sFilterConfig.FilterID1 = 0x444;
        sFilterConfig.FilterID2 = 0x555;
        if (HAL_FDCAN_ConfigFilter(&amp;hfdcan1, &amp;sFilterConfig) != HAL_OK)
        {
                Error_Handler();
        }

        /* Configure extended ID reception filter to Rx FIFO 1 */
        sFilterConfig.IdType = FDCAN_EXTENDED_ID;
        sFilterConfig.FilterIndex = 0;
        sFilterConfig.FilterType = FDCAN_FILTER_RANGE_NO_EIDM;
        sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO1;
        sFilterConfig.FilterID1 = 0x1111111;
        sFilterConfig.FilterID2 = 0x2222222;
        if (HAL_FDCAN_ConfigFilter(&amp;hfdcan1, &amp;sFilterConfig) != HAL_OK)
        {
                Error_Handler();
        }

        /* Configure global filter:
             Filter all remote frames with STD and EXT ID
             Reject non matching frames with STD ID and EXT ID */
        if (HAL_FDCAN_ConfigGlobalFilter(&amp;hfdcan1, FDCAN_REJECT, FDCAN_REJECT, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE) != HAL_OK)
        {
                Error_Handler();
        }

        /*##-2 Start FDCAN controller (continuous listening CAN bus) ##############*/
        if (HAL_FDCAN_Start(&amp;hfdcan1) != HAL_OK)
        {
                Error_Handler();
        }

        printf("\r\nBefore Add 0x444: HAL_FDCAN_GetTxFifoFreeLevel(&amp;hfdcan1) = %d", HAL_FDCAN_GetTxFifoFreeLevel(&amp;hfdcan1));

        /*##-3 Transmit messages ##################################################*/
        /* Add message to Tx FIFO */
        TxHeader.Identifier = 0x444;
        TxHeader.IdType = FDCAN_STANDARD_ID;
        TxHeader.TxFrameType = FDCAN_DATA_FRAME;
        TxHeader.DataLength = FDCAN_DLC_BYTES_8;
        TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
        TxHeader.BitRateSwitch = FDCAN_BRS_OFF;
        TxHeader.FDFormat = FDCAN_CLASSIC_CAN;
        TxHeader.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
        TxHeader.MessageMarker = 0x52;
        if (HAL_FDCAN_AddMessageToTxFifoQ(&amp;hfdcan1, &amp;TxHeader, TxData0) != HAL_OK)
        {
                Error_Handler();
        }
        printf("\r\nAfter Add 0x444: HAL_FDCAN_GetTxFifoFreeLevel(&amp;hfdcan1) = %d", HAL_FDCAN_GetTxFifoFreeLevel(&amp;hfdcan1));

        /* Add second message to Tx FIFO */
        TxHeader.Identifier = 0x1111112;
        TxHeader.IdType = FDCAN_EXTENDED_ID;
        TxHeader.TxFrameType = FDCAN_DATA_FRAME;
        TxHeader.DataLength = FDCAN_DLC_BYTES_8;
        TxHeader.ErrorStateIndicator = FDCAN_ESI_PASSIVE;
        TxHeader.BitRateSwitch = FDCAN_BRS_OFF;
        TxHeader.FDFormat = FDCAN_CLASSIC_CAN;
        TxHeader.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
        TxHeader.MessageMarker = 0xCC;
        if (HAL_FDCAN_AddMessageToTxFifoQ(&amp;hfdcan1, &amp;TxHeader, TxData1) != HAL_OK)
        {
                Error_Handler();
        }
        printf("\r\nAfter Add 0x1111112: HAL_FDCAN_GetTxFifoFreeLevel(&amp;hfdcan1) = %d", HAL_FDCAN_GetTxFifoFreeLevel(&amp;hfdcan1));

        /* Add third message to Tx FIFO */
        TxHeader.Identifier = 0x1111113;
        TxHeader.IdType = FDCAN_EXTENDED_ID;
        TxHeader.TxFrameType = FDCAN_DATA_FRAME;
        TxHeader.DataLength = FDCAN_DLC_BYTES_8;
        TxHeader.ErrorStateIndicator = FDCAN_ESI_PASSIVE;
        TxHeader.BitRateSwitch = FDCAN_BRS_OFF;
        TxHeader.FDFormat = FDCAN_CLASSIC_CAN;
        TxHeader.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
        TxHeader.MessageMarker = 0xDD;
        if (HAL_FDCAN_AddMessageToTxFifoQ(&amp;hfdcan1, &amp;TxHeader, TxData2) != HAL_OK)
        {
                Error_Handler();
        }
        printf("\r\nAfter Add 0x1111113: HAL_FDCAN_GetTxFifoFreeLevel(&amp;hfdcan1) = %d", HAL_FDCAN_GetTxFifoFreeLevel(&amp;hfdcan1));

        /* Wait transmissions complete */
        while (HAL_FDCAN_GetTxFifoFreeLevel(&amp;hfdcan1) != 3) {}

        printf("\r\n 3 CAN MSG Transmissions Complete.");

}//end of void MY_FDCAN_CONFIG(void)</code></pre>

<p>&nbsp;</p>

<p>主循环中每次呼吸灯闪烁一次,把次数打包到can msg里面发送到上位机。</p>

<pre>
<code class="language-cpp">while (1)
{
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
          static uint16_t dcycle_pulse = 0;
          static uint8_t breath_cnt = 0;
          //htim3.Init.Period = 999
          while(dcycle_pulse &lt;htim3.Init.Period){
                  __HAL_TIM_SET_COMPARE(&amp;htim3, TIM_CHANNEL_2, dcycle_pulse);
                  dcycle_pulse += 50;
                  printf("\nLight Phase, Current DutyCycle = %u", dcycle_pulse*100/htim3.Init.Period);
                  HAL_Delay(100);
          }
          while(dcycle_pulse &gt; 0){
                  __HAL_TIM_SET_COMPARE(&amp;htim3, TIM_CHANNEL_2, dcycle_pulse);
                  dcycle_pulse -= 50;
                  printf("\nDim Phase, Current DutyCycle = %u", dcycle_pulse*100/htim3.Init.Period);
                  HAL_Delay(100);
          }


          printf("\r\nBefore Add 0x555: HAL_FDCAN_GetTxFifoFreeLevel(&amp;hfdcan1) = %d", HAL_FDCAN_GetTxFifoFreeLevel(&amp;hfdcan1));

          /* Wait for available Tx Fifo */
          while (HAL_FDCAN_GetTxFifoFreeLevel(&amp;hfdcan1) == 0) {}

          TxBreathLEDCnt = breath_cnt++;
          if (HAL_FDCAN_AddMessageToTxFifoQ(&amp;hfdcan1, &amp;TxHeader, TxBreathLEDCnt) != HAL_OK)
          {
                  Error_Handler();
          }


          printf("\r\nAfter Add 0x555: HAL_FDCAN_GetTxFifoFreeLevel(&amp;hfdcan1) = %d", HAL_FDCAN_GetTxFifoFreeLevel(&amp;hfdcan1));
          printf("\r\nSTM32U5-TJA1050-USBCAN: Breath LED CAN MSG Transmissions Complete.");


}//end of while</code></pre>

<p>硬件系统:</p>

<p> &nbsp;</p>

<p>上位机数据:</p>

<p>首先收到3帧测试数据,然后呼吸灯的闪烁次数通过id为555的报文被传送过来。</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>这次体验下来感觉配置cubeide使用fdcan外设是非常方便的,后续考虑深入了解一下接收,以及中断收发等功能。</p>

<p>&nbsp;</p>

<p><span style="font-size: 16px;"><strong>参考:</strong></span></p>

<p>AN5348_STM32器件上的FDCAN外设的应用手册.pdf</p>
</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

慕容雪花 发表于 2024-3-4 11:10

<p><a href="https://community.st.com/t5/stm32-mcus-products/fdcan-on-stm32u5-and-stm32h5-serious-fifo-queue-and-id-filter/td-p/615847" target="_blank">https://community.st.com/t5/stm32-mcus-products/fdcan-on-stm32u5-and-stm32h5-serious-fifo-queue-and-id-filter/td-p/615847</a></p>

<p>&nbsp;</p>

<p>FDCAN FIFO只有3个?</p>

lugl4313820 发表于 2024-3-4 11:30

<p>这次体验下来感觉配置cubeide使用fdcan外设是非常方便的,后续考虑深入了解一下接收,以及中断收发等功能。</p>

<p>感谢分享!</p>

慕容雪花 发表于 2024-3-4 11:32

lugl4313820 发表于 2024-3-4 11:30
这次体验下来感觉配置cubeide使用fdcan外设是非常方便的,后续考虑深入了解一下接收,以及中断收发等功能。 ...

<p>感谢刘工之前分享的U5系列FDCAN使用经验,受益匪浅!</p>

lugl4313820 发表于 2024-3-4 11:50

慕容雪花 发表于 2024-3-4 11:32
感谢刘工之前分享的U5系列FDCAN使用经验,受益匪浅!

<p>你的帖子也非常精彩!比我的更内容丰富!</p>
页: [1]
查看完整版本: 【ST NUCLEO-U5A5ZJ-Q开发板测评】-6-FDCAN体验