硬汉嵌入式论坛

 找回密码
 立即注册
查看: 268|回复: 9
收起左侧

[CAN/FDCAN] fdcan 相關FDCAN_REMOTE_FRAME問題

[复制链接]

13

主题

32

回帖

71

积分

初级会员

积分
71
发表于 2024-5-14 14:53:06 | 显示全部楼层 |阅读模式


我有兩個疑問
我現在stm32g4 的fdcan
想用跟esc溝通, 我需要發 Remote Frame, 想取得esc資訊
1. 我用一般can, (hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;),所以我可以不管hfdcan1.Init.Data相關參數???
初始化是設定

        hfdcan1.Instance = FDCAN1;
        hfdcan1.Init.ClockDivider = FDCAN_CLOCK_DIV1;
        hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
        hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
        hfdcan1.Init.AutoRetransmission = DISABLE;
        hfdcan1.Init.TransmitPause = DISABLE;
        hfdcan1.Init.ProtocolException = DISABLE;
        //baud rate pclk1(apb11)/Prescale/(1+TimeSeg1+TimeSeg2)= 170M/17/(1+14+5)=0.5Mbit/s
        //(1+TimeSeg1)/(1+TimeSeg1+TimeSeg2)= (1+14)/(1+14+5) =75%
        hfdcan1.Init.NominalPrescaler = 17;
        hfdcan1.Init.NominalSyncJumpWidth = 5;
        hfdcan1.Init.NominalTimeSeg1 = 14;
        hfdcan1.Init.NominalTimeSeg2 = 5;
        hfdcan1.Init.DataPrescaler = 1;
        hfdcan1.Init.DataSyncJumpWidth = 1;
        hfdcan1.Init.DataTimeSeg1 = 1;
        hfdcan1.Init.DataTimeSeg2 = 1;
        hfdcan1.Init.StdFiltersNbr = 2;
        hfdcan1.Init.ExtFiltersNbr = 2;
        hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;

2.
傳的封包設定

                                FDCAN_TxHeaderTypeDef fdcan_TxHeader={0};
                                fdcan_TxHeader.Identifier = 0x205; //ex:0x205參考kde 請求temperture
                                fdcan_TxHeader.IdType = FDCAN_EXTENDED_ID;
                                fdcan_TxHeader.TxFrameType = FDCAN_REMOTE_FRAME;//FDCAN_REMOTE_FRAME:遙控幀, FDCAN_DATA_FRAME:數據幀
                                fdcan_TxHeader.DataLength = FDCAN_DLC_BYTES_0;;
                                fdcan_TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
                                fdcan_TxHeader.BitRateSwitch = FDCAN_BRS_OFF;
                                fdcan_TxHeader.FDFormat = FDCAN_CLASSIC_CAN;
                                fdcan_TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
                                fdcan_TxHeader.MessageMarker = 0;

FDCAN_REMOTE_FRAME沒有資料, datalength是給0??
但我又看到說fdcan不支持 Remote Frame
那fdcan還能發FDCAN_REMOTE_FRAME

希望有人能解惑
感謝
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107643
QQ
发表于 2024-5-14 16:09:13 | 显示全部楼层
1、对,经典CAN不用配置数据段
2、支持,经典CAN模式可以发远程帧

CANFD的经典模式的遥控帧发送和接收测试

278.jpg
回复

使用道具 举报

13

主题

32

回帖

71

积分

初级会员

积分
71
 楼主| 发表于 2024-5-14 17:04:13 | 显示全部楼层
感謝回復

我想繼續請問這是我傳的封包內容
                                FDCAN_TxHeaderTypeDef fdcan_TxHeader={0};
                                fdcan_TxHeader.Identifier = 0x00000205; //ex:0x205參考kde 請求temperture
                                fdcan_TxHeader.IdType = FDCAN_EXTENDED_ID;
                                fdcan_TxHeader.TxFrameType = FDCAN_DATA_FRAME;//FDCAN_REMOTE_FRAME:遙控幀, FDCAN_DATA_FRAME:數據幀
                                fdcan_TxHeader.DataLength = FDCAN_DLC_BYTES_8;
                                fdcan_TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
                                fdcan_TxHeader.BitRateSwitch = FDCAN_BRS_OFF;//FDCAN_BRS_ON;
                                fdcan_TxHeader.FDFormat = FDCAN_CLASSIC_CAN;//FDCAN_FD_CAN;
                                fdcan_TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
                                fdcan_TxHeader.MessageMarker = 0;

                    //HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1,&fdcan_TxHeader,fdcan_transmit_txq_element.buf[0]);
                                if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1,&fdcan_TxHeader,tx_data) != HAL_OK)
                                {
                                        db_printf(DB_ALWAYS, "fdcan tram no\n");
                                }else
                                {
                                        db_printf(DB_ALWAYS, "fdcan tram\n");
                                }
設計大概一秒傳一次, 並且有一直印出fdcan tram,
我用邏輯分析看low和high線沒看到到訊號(沒高低起伏)
請問HAL_FDCAN_AddMessageToTxFifoQ有pass表示封包依次發送??但抓不到訊號
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107643
QQ
发表于 2024-5-15 09:39:27 | 显示全部楼层
iriss 发表于 2024-5-14 17:04
感謝回復

我想繼續請問這是我傳的封包內容

对于TxFIFO,是否真的发送完成,比如开启了发送空中断,你要以这个是否空中断为准。

否则就要看下CAN的错误状态标志位了,看下什么地方出错了。
回复

使用道具 举报

13

主题

32

回帖

71

积分

初级会员

积分
71
 楼主| 发表于 2024-5-15 11:43:05 | 显示全部楼层
感謝回覆
如圖, 我看邏輯分析的cam_L 看到拉低後拉高, 後續就沒變化

我加入发送空中断, 好像沒回到中斷, 可以麻煩幫我看一下程式, 程式如下
static void MX_FDCAN1_Init(void) {
        /* USER CODE BEGIN FDCAN1_Init 0 */
        hfdcan1.Instance = FDCAN1;
        hfdcan1.Init.ClockDivider = FDCAN_CLOCK_DIV1;
        hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
        hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
        hfdcan1.Init.AutoRetransmission = DISABLE;
        hfdcan1.Init.TransmitPause = DISABLE;
        hfdcan1.Init.ProtocolException = DISABLE;
        //baud rate pclk1(apb11)/Prescale/(1+TimeSeg1+TimeSeg2)= 170M/17/(1+14+5)=0.5Mbit/s
        //(1+TimeSeg1)/(1+TimeSeg1+TimeSeg2)= (1+14)/(1+14+5) =75%
        //baud rate pclk1(apb11)/Prescale/(1+TimeSeg1+TimeSeg2)= 170M/17/(1+7+2)=1.0Mbit/s
        //(1+TimeSeg1)/(1+TimeSeg1+TimeSeg2)= (1+7)/(1+7+2) =80%
        //baud rate pclk1(apb11)/Prescale/(1+TimeSeg1+TimeSeg2)= 170M/17/(1+34+15)=0.2Mbit/s
        //(1+TimeSeg1)/(1+TimeSeg1+TimeSeg2)= (1+34)/(1+34+10) =70%
        hfdcan1.Init.NominalPrescaler = 17;
        hfdcan1.Init.NominalSyncJumpWidth = 15;
        hfdcan1.Init.NominalTimeSeg1 = 34;
        hfdcan1.Init.NominalTimeSeg2 = 15;
        hfdcan1.Init.DataPrescaler = 1;
        hfdcan1.Init.DataSyncJumpWidth = 1;
        hfdcan1.Init.DataTimeSeg1 = 1;
        hfdcan1.Init.DataTimeSeg2 = 1;
        hfdcan1.Init.StdFiltersNbr = 2;
        hfdcan1.Init.ExtFiltersNbr = 2;
        hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
        if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK) {
                Error_Handler();
        }
        //濾波器設定
        hfdcan1_RX_Filter.IdType = FDCAN_STANDARD_ID;// FDCAN_EXTENDED_ID
        hfdcan1_RX_Filter.FilterIndex = 0; /* 濾波器器索引 */
        hfdcan1_RX_Filter.FilterType = FDCAN_FILTER_MASK;/* 濾波器類型 */
        hfdcan1_RX_Filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;/* 濾波器連到RXFIFO0 */
        hfdcan1_RX_Filter.FilterID1 = 0x000;
        hfdcan1_RX_Filter.FilterID2 = 0x7FF;

        hfdcan1_RX_Filter.IdType = FDCAN_EXTENDED_ID;
        hfdcan1_RX_Filter.FilterIndex = 1; /* 濾波器器索引 */
        hfdcan1_RX_Filter.FilterType = FDCAN_FILTER_MASK;/* 濾波器類型 */
        hfdcan1_RX_Filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;/* 濾波器連到RXFIFO0 */
        hfdcan1_RX_Filter.FilterID1 = 0x00;  //濾波器設置為全接收  //ex:0x20005參考kde get temperture
        hfdcan1_RX_Filter.FilterID2 = 0x1FFFFFFF;

        if (HAL_FDCAN_ConfigFilter(&hfdcan1, &hfdcan1_RX_Filter) != HAL_OK) {
                /* Filter configuration Error */
                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(&hfdcan1, FDCAN_REJECT, FDCAN_REJECT, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE) != HAL_OK) {
                Error_Handler();
        }

        // Create queues that act as buffer for tx and rx
        fdcan1_txq = xQueueCreate(32,sizeof(fdcan_txq_element));
        //fdcan1_rxq = xQueueCreate(256, sizeof(uint8_t));      //256? 再確認長度
        fdcan1_rxq = xQueueCreate(32, sizeof(fdcan_rxq_element));   //四個單元 長度為sizeof(fdcan_rxq_element)=64
        if ((fdcan1_rxq == NULL)|| (fdcan1_txq == NULL)){
                Error_Handler();
        }
    // Create binary semaphore that is used to inform tasks if fdcan1 is ready to transmit or not
        fdcan1_bi_semaphore = xSemaphoreCreateBinary();
    xSemaphoreGive(fdcan1_bi_semaphore); //初始時,fdcan為ready狀態

        /* Start the FDCAN module */
        if (HAL_FDCAN_Start(&hfdcan1) != HAL_OK)
        {
                Error_Handler();
        }
        /* Enable interrupts */
        if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
        {
                Error_Handler();
        }
        //HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_TX_FIFO_EMPTY , 0);/* 开启 TXFIFO 空中断 */

        if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_TX_FIFO_EMPTY , 0) != HAL_OK)
        {
                Error_Handler();
        }
}
void fdcan1_transmit_task(void *args __attribute__((unused))) {
        //fdcan_txq_element fdcan_transmit_txq_element;
        uint8_t tx_data[8]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};

        for (;;) {
                                FDCAN_TxHeaderTypeDef fdcan_TxHeader={0};
                                fdcan_TxHeader.Identifier =0x001;// 0x00000205; //ex:0x205參考kde 請求temperture
                                fdcan_TxHeader.IdType = FDCAN_STANDARD_ID;//FDCAN_STANDARD_ID;//FDCAN_EXTENDED_ID;
                                fdcan_TxHeader.TxFrameType = FDCAN_DATA_FRAME;//FDCAN_REMOTE_FRAME:遙控幀, FDCAN_DATA_FRAME:數據幀
                                fdcan_TxHeader.DataLength = FDCAN_DLC_BYTES_8;
                                fdcan_TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
                                fdcan_TxHeader.BitRateSwitch = FDCAN_BRS_OFF;//FDCAN_BRS_ON;
                                fdcan_TxHeader.FDFormat = FDCAN_CLASSIC_CAN;//FDCAN_FD_CAN;
                                fdcan_TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;//FDCAN_NO_TX_EVENTS;//DCAN_STORE_TX_EVENTSㄥ
                                fdcan_TxHeader.MessageMarker = 0;

      
                                if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1,&fdcan_TxHeader,tx_data) != HAL_OK)
                                {
                                        db_printf(DB_ALWAYS, "fdcan tram no\n");
                                }else
                                {
                                        db_printf(DB_ALWAYS, "fdcan tram\n");
                                }
                                 vTaskDelay(pdMS_TO_TICKS(1000)); //以下兩者差異
                }
                 //  else {
                        //}
                }
        }

/*
* @brief  Tx Transfer completed callbacks.
* @param  hfdcan: fdcan handle
* @return None
*/
//void HAL_fdcan_TxCpltCallback(FDCAN_HandleTypeDef *hfdcan) {
void HAL_FDCAN_TxFifoEmptyCallback(FDCAN_HandleTypeDef *hfdcan){
        SemaphoreHandle_t *tmp_semphr = NULL;

        BaseType_t xHigherPriorityTaskWoken = pdFALSE;

        if (hfdcan->Instance == FDCAN1) {
                tmp_semphr = &fdcan1_bi_semaphore;
        } else {
                return;
        }
        db_printf(DB_ALWAYS, "tx finish\n");
        if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_TX_FIFO_EMPTY , 0) == HAL_OK)
        {
        }
        xSemaphoreGiveFromISR(*tmp_semphr, &xHigherPriorityTaskWoken);

        //Determine if context switch is needed
        portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
感謝
螢幕快照 2024-05-15 11:35:13.png
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107643
QQ
发表于 2024-5-16 08:51:49 | 显示全部楼层
iriss 发表于 2024-5-15 11:43
感謝回覆
如圖, 我看邏輯分析的cam_L 看到拉低後拉高, 後續就沒變化

你的CAN主时钟配置在那里,也就是你注释上展示的170M,这个是从那个地方配置得出的。


特别注意,这个时钟最好别超过80
回复

使用道具 举报

13

主题

32

回帖

71

积分

初级会员

积分
71
 楼主| 发表于 2024-5-16 11:24:49 | 显示全部楼层
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV5;
  RCC_OscInitStruct.PLL.PLLN = 68;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV8;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
  {
    Error_Handler();
  }
}
螢幕快照 2024-05-16 11:23:12.png
回复

使用道具 举报

13

主题

32

回帖

71

积分

初级会员

积分
71
 楼主| 发表于 2024-5-16 15:07:11 | 显示全部楼层
後續我用FDCAN_MODE_EXTERNAL_LOOPBACK檢查, 邏輯分析can tx, 可以看到tx封包, 但改回FDCAN_MODE_NORMAL, tx封包就不對, 連id都錯, 就只改hfdcan1.Init.Mode, ?? 還是還要動哪個參數??
回复

使用道具 举报

13

主题

32

回帖

71

积分

初级会员

积分
71
 楼主| 发表于 2024-5-16 15:48:40 | 显示全部楼层
剛剛那個情況應該是線路問題
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107643
QQ
发表于 2024-5-17 08:56:19 | 显示全部楼层
iriss 发表于 2024-5-16 15:48
剛剛那個情況應該是線路問題

最终解决了吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-6-10 01:42 , Processed in 0.196184 second(s), 30 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表