野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 367|回复: 0

CAN通信回环模式无法接收数据

[复制链接]
发表于 2025-3-24 22:17:06 | 显示全部楼层 |阅读模式

开发工具:CUBEIDE
开发板芯片:F407ZGT6
开发板:野火 霸天虎V1



问题如下:
        CAN回环模式测试,调试过程中监视寄存器发现数据已进入发送邮箱,TSR寄存器的RQCP0和TXOK0值为1,说明发送成功,但是寄存器FIFO0的RF0R寄存器值为0,数据未进入FIFO
已用KEIL下载官方回环例程,官方例程回环模式能收发数据,说明CAN设备正常,有大佬帮忙看看这个是什么问题吗?或者需要怎样调试才能发现问题根源?
求指点

工程附件已上传

  已设置筛选器为不过滤,激活FIFO0的接收寄存器,具体代码见后文代码块或附件

寄存器值如下:
原理图如下:
通过CUBEIDE设置CAN2如下:



代码如下
main.c:
  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * [url=home.php?mod=space&uid=90986]@file[/url]           : main.c
  5. * [url=home.php?mod=space&uid=41770]@brief[/url]          : Main program body
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * Copyright (c) 2025 STMicroelectronics.
  10. * All rights reserved.
  11. *
  12. * This software is licensed under terms that can be found in the LICENSE file
  13. * in the root directory of this software component.
  14. * If no LICENSE file comes with this software, it is provided AS-IS.
  15. *
  16. ******************************************************************************
  17. */
  18. /* USER CODE END Header */
  19. /* Includes ------------------------------------------------------------------*/
  20. #include "main.h"
  21. #include "can.h"
  22. #include "usart.h"
  23. #include "gpio.h"

  24. /* Private includes ----------------------------------------------------------*/
  25. /* USER CODE BEGIN Includes */
  26. #include "../../BSP/LED/led.h"
  27. #include "../../SYSTEM/delay/delay.h"
  28. #include "../../BSP/BEEF/beef.h"
  29. #include "../../BSP/KEY/key.h"
  30. #include "string.h"
  31. /* USER CODE END Includes */

  32. /* Private typedef -----------------------------------------------------------*/
  33. /* USER CODE BEGIN PTD */

  34. /* USER CODE END PTD */

  35. /* Private define ------------------------------------------------------------*/
  36. /* USER CODE BEGIN PD */

  37. /* USER CODE END PD */

  38. /* Private macro -------------------------------------------------------------*/
  39. /* USER CODE BEGIN PM */

  40. /* USER CODE END PM */

  41. /* Private variables ---------------------------------------------------------*/

  42. /* USER CODE BEGIN PV */

  43. /* USER CODE END PV */

  44. /* Private function prototypes -----------------------------------------------*/
  45. void SystemClock_Config(void);
  46. /* USER CODE BEGIN PFP */

  47. /* USER CODE END PFP */

  48. /* Private user code ---------------------------------------------------------*/
  49. /* USER CODE BEGIN 0 */

  50. /* USER CODE END 0 */

  51. /**
  52.   * @brief  The application entry point.
  53.   * @retval int
  54.   */
  55. int main(void)
  56. {

  57.   /* USER CODE BEGIN 1 */
  58.     uint8_t key;
  59.     uint8_t i = 0;
  60.     uint8_t cnt = 0;
  61.     uint8_t canbuf[8];
  62.     uint8_t rxlen = 0;
  63.     uint8_t res;
  64.     uint16_t times = 0;
  65.   /* USER CODE END 1 */

  66.   /* MCU Configuration--------------------------------------------------------*/

  67.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  68.   HAL_Init();

  69.   /* USER CODE BEGIN Init */

  70.   /* USER CODE END Init */

  71.   /* Configure the system clock */
  72.   SystemClock_Config();

  73.   /* USER CODE BEGIN SysInit */
  74.     delay_init(84);
  75.   /* USER CODE END SysInit */

  76.   /* Initialize all configured peripherals */
  77.   MX_GPIO_Init();
  78.   MX_USART1_UART_Init();
  79.   MX_CAN2_Init();
  80.   /* USER CODE BEGIN 2 */

  81.   /* USER CODE END 2 */

  82.   /* Infinite loop */
  83.   /* USER CODE BEGIN WHILE */
  84.   while (1)
  85.   {
  86.       key = key_scan(0);

  87.       if(key == KEY2_PRESS)
  88.       {
  89.           printf("Send: ");
  90.           for(i = 0;  i<8;  i++)
  91.           {
  92.               canbuf[i] = cnt+i;
  93.               printf("%d ", canbuf[i]);
  94.           }
  95.           printf("\r\n");

  96.           res = can_send_msg(0x12, canbuf, 8);

  97.           if(res)
  98.           {
  99.               printf("Send Failed!\r\n");
  100.           }
  101.           else
  102.           {
  103.               printf("Send Successful!\r\n");
  104.           }
  105.       }

  106.       rxlen = can_receive_msg(0x12, canbuf);
  107.       if(rxlen)
  108.       {
  109.           printf("Receive:");
  110.           for(i = 0;  i<rxlen;  i++)
  111.           {
  112.               printf("%d ", canbuf[i]);
  113.           }
  114.           printf("\r\n");
  115.       }

  116.       times++;
  117.       if(times %200 == 0)
  118.           printf("Please Press KEY2 To Send Message!\r\n");


  119.       if(times % 30 == 0)
  120.       {
  121.           cnt++;
  122.           LED_R_TOGGLE();
  123.       }

  124.       delay_ms(10);


  125.     /* USER CODE END WHILE */

  126.     /* USER CODE BEGIN 3 */
  127.   }
  128.   /* USER CODE END 3 */
  129. }

  130. /**
  131.   * @brief System Clock Configuration
  132.   * @retval None
  133.   */
  134. void SystemClock_Config(void)
  135. {
  136.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  137.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  138.   /** Configure the main internal regulator output voltage
  139.   */
  140.   __HAL_RCC_PWR_CLK_ENABLE();
  141.   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  142.   /** Initializes the RCC Oscillators according to the specified parameters
  143.   * in the RCC_OscInitTypeDef structure.
  144.   */
  145.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  146.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  147.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  148.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  149.   RCC_OscInitStruct.PLL.PLLM = 25;
  150.   RCC_OscInitStruct.PLL.PLLN = 336;
  151.   RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  152.   RCC_OscInitStruct.PLL.PLLQ = 4;
  153.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  154.   {
  155.     Error_Handler();
  156.   }

  157.   /** Initializes the CPU, AHB and APB buses clocks
  158.   */
  159.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  160.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  161.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  162.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  163.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  164.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  165.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  166.   {
  167.     Error_Handler();
  168.   }
  169. }

  170. /* USER CODE BEGIN 4 */

  171. /* USER CODE END 4 */

  172. /**
  173.   * @brief  This function is executed in case of error occurrence.
  174.   * @retval None
  175.   */
  176. void Error_Handler(void)
  177. {
  178.   /* USER CODE BEGIN Error_Handler_Debug */
  179.     /* User can add his own implementation to report the HAL error return state */
  180.     __disable_irq();
  181.     while (1)
  182.     {
  183.     }
  184.   /* USER CODE END Error_Handler_Debug */
  185. }

  186. #ifdef  USE_FULL_ASSERT
  187. /**
  188.   * @brief  Reports the name of the source file and the source line number
  189.   *         where the assert_param error has occurred.
  190.   * @param  file: pointer to the source file name
  191.   * @param  line: assert_param error line source number
  192.   * @retval None
  193.   */
  194. void assert_failed(uint8_t *file, uint32_t line)
  195. {
  196.   /* USER CODE BEGIN 6 */
  197.     /* User can add his own implementation to report the file name and line number,
  198.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  199.   /* USER CODE END 6 */
  200. }
  201. #endif /* USE_FULL_ASSERT */
复制代码


can.c
  1. /* USER CODE BEGIN Header */
  2. /**
  3.   ******************************************************************************
  4.   * @file    can.c
  5.   * @brief   This file provides code for the configuration
  6.   *          of the CAN instances.
  7.   ******************************************************************************
  8.   * @attention
  9.   *
  10.   * Copyright (c) 2025 STMicroelectronics.
  11.   * All rights reserved.
  12.   *
  13.   * This software is licensed under terms that can be found in the LICENSE file
  14.   * in the root directory of this software component.
  15.   * If no LICENSE file comes with this software, it is provided AS-IS.
  16.   *
  17.   ******************************************************************************
  18.   */
  19. /* USER CODE END Header */
  20. /* Includes ------------------------------------------------------------------*/
  21. #include "can.h"

  22. /* USER CODE BEGIN 0 */
  23. CAN_TxHeaderTypeDef g_canx_txheader;    /* 发送参数句柄 */
  24. CAN_RxHeaderTypeDef g_canx_rxheader;    /* 接收参数句柄 */
  25. CAN_FilterTypeDef sFilterConfig;
  26. /* USER CODE END 0 */

  27. CAN_HandleTypeDef hcan2;

  28. /* CAN2 init function */
  29. void MX_CAN2_Init(void)
  30. {

  31.   /* USER CODE BEGIN CAN2_Init 0 */
  32.     CAN_FilterTypeDef sFilterConfig;    /*配置 CAN 过滤器*/
  33.   /* USER CODE END CAN2_Init 0 */

  34.   /* USER CODE BEGIN CAN2_Init 1 */

  35.   /* USER CODE END CAN2_Init 1 */
  36.   hcan2.Instance = CAN2;
  37.   hcan2.Init.Prescaler = 4;
  38.   hcan2.Init.Mode = CAN_MODE_LOOPBACK;
  39.   hcan2.Init.SyncJumpWidth = CAN_SJW_1TQ;
  40.   hcan2.Init.TimeSeg1 = CAN_BS1_12TQ;
  41.   hcan2.Init.TimeSeg2 = CAN_BS2_8TQ;
  42.   hcan2.Init.TimeTriggeredMode = DISABLE;
  43.   hcan2.Init.AutoBusOff = DISABLE;
  44.   hcan2.Init.AutoWakeUp = DISABLE;
  45.   hcan2.Init.AutoRetransmission = ENABLE;
  46.   hcan2.Init.ReceiveFifoLocked = DISABLE;
  47.   hcan2.Init.TransmitFifoPriority = DISABLE;
  48.   if (HAL_CAN_Init(&hcan2) != HAL_OK)
  49.   {
  50.     Error_Handler();
  51.   }
  52.   /* USER CODE BEGIN CAN2_Init 2 */
  53.   //配置过滤器
  54.   sFilterConfig.FilterBank = 0; // 过滤器组编号
  55.   sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; // 过滤器模式
  56.   sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; // 过滤器尺度
  57.   sFilterConfig.FilterIdHigh = 0x0000; // 过滤器 ID 高 16 位
  58.   sFilterConfig.FilterIdLow = 0x0000; // 过滤器 ID 低 16 位
  59.   sFilterConfig.FilterMaskIdHigh = 0x0000; // 过滤器掩码高 16 位
  60.   sFilterConfig.FilterMaskIdLow = 0x0000; // 过滤器掩码低 16 位
  61.   sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; // 过滤器分配给 FIFO 0
  62.   sFilterConfig.FilterActivation = ENABLE; // 使能过滤器
  63.   sFilterConfig.SlaveStartFilterBank = 14; // CAN2 的过滤器起始位置

  64.   if(HAL_CAN_ConfigFilter(&hcan2, &sFilterConfig) != HAL_OK)
  65.   {     /*过滤器配置*/
  66.       Error_Handler();
  67.   }

  68.   if(HAL_CAN_Start(&hcan2) != HAL_OK)
  69.   {     /*启动CAN外围设备*/
  70.       Error_Handler();
  71.   }

  72. /*使能中断接收,FIFO0消息挂号中断允许,选则CAN外设中断源为“ CAN 接收 FIFO 0 消息挂起中断”,
  73. * 同时需要使能打开CAN的中断响应,此处未写是因在可视化界面已配置,
  74. * 会在HAL_CAN_Init初始化时调用的HAL_CAN_MspInit函数中进行使能*/
  75.   //__HAL_CAN_ENABLE_IT(&hcan2, CAN_IT_RX_FIFO0_MSG_PENDING);
  76.   HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO0_MSG_PENDING);




  77.   /* USER CODE END CAN2_Init 2 */

  78. }

  79. void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
  80. {

  81.   GPIO_InitTypeDef GPIO_InitStruct = {0};
  82.   if(canHandle->Instance==CAN2)
  83.   {
  84.   /* USER CODE BEGIN CAN2_MspInit 0 */

  85.   /* USER CODE END CAN2_MspInit 0 */
  86.     /* CAN2 clock enable */
  87.     __HAL_RCC_CAN2_CLK_ENABLE();
  88.     __HAL_RCC_CAN1_CLK_ENABLE();

  89.     __HAL_RCC_GPIOB_CLK_ENABLE();
  90.     /**CAN2 GPIO Configuration
  91.     PB12     ------> CAN2_RX
  92.     PB13     ------> CAN2_TX
  93.     */
  94.     GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13;
  95.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  96.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  97.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  98.     GPIO_InitStruct.Alternate = GPIO_AF9_CAN2;
  99.     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  100.     /* CAN2 interrupt Init */
  101.     HAL_NVIC_SetPriority(CAN2_RX0_IRQn, 1, 0);
  102.     HAL_NVIC_EnableIRQ(CAN2_RX0_IRQn);
  103.   /* USER CODE BEGIN CAN2_MspInit 1 */


  104.   /* USER CODE END CAN2_MspInit 1 */
  105.   }
  106. }

  107. void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)
  108. {

  109.   if(canHandle->Instance==CAN2)
  110.   {
  111.   /* USER CODE BEGIN CAN2_MspDeInit 0 */

  112.   /* USER CODE END CAN2_MspDeInit 0 */
  113.     /* Peripheral clock disable */
  114.     __HAL_RCC_CAN2_CLK_DISABLE();
  115.     __HAL_RCC_CAN1_CLK_DISABLE();

  116.     /**CAN2 GPIO Configuration
  117.     PB12     ------> CAN2_RX
  118.     PB13     ------> CAN2_TX
  119.     */
  120.     HAL_GPIO_DeInit(GPIOB, GPIO_PIN_12|GPIO_PIN_13);

  121.     /* CAN2 interrupt Deinit */
  122.     HAL_NVIC_DisableIRQ(CAN2_RX0_IRQn);
  123.   /* USER CODE BEGIN CAN2_MspDeInit 1 */

  124.   /* USER CODE END CAN2_MspDeInit 1 */
  125.   }
  126. }

  127. /* USER CODE BEGIN 1 */
  128. /**
  129. * * @brief CAN 发送一组数据
  130. * * [url=home.php?mod=space&uid=87825]@note[/url] 发送格式固定为: 标准 ID, 数据帧
  131. * * @param id : 标准 ID(11 位)
  132. * * @retval 发送状态 0, 成功; 1, 失败;
  133. * */
  134. uint8_t can_send_msg(uint32_t id, uint8_t *msg, uint8_t len)
  135. {
  136.     uint32_t TxMailBox = CAN_TX_MAILBOX0;

  137.     g_canx_txheader.StdId = id;         /*标准标识符*/
  138.     g_canx_txheader.ExtId = id;         /*扩展标识符(29位)*/
  139.     g_canx_txheader.IDE = CAN_ID_STD;           /* 使用标准帧 */
  140.     g_canx_txheader.RTR = CAN_RTR_DATA;     /* 数据帧 */
  141.     g_canx_txheader.DLC = len;

  142.     if(HAL_CAN_AddTxMessage(&hcan2, &g_canx_txheader, msg, &TxMailBox) != HAL_OK)
  143.     {
  144.         return 1;
  145.     }

  146.     /*等待发送完成,所有邮箱为空(3个邮箱)*/
  147.     while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan2) !=3);

  148.     return 0;

  149. }

  150. /** * @brief CAN 接收数据查询
  151. * * @note 接收数据格式固定为: 标准 ID, 数据帧
  152. * * @param id : 要查询的 标准 ID(11 位)
  153. * * @param buf : 数据缓存区
  154. * * @retval 接收结果
  155. * * @arg 0 , 无数据被接收到;
  156. * * @arg 其他, 接收的数据长度
  157. * */
  158. uint8_t can_receive_msg(uint32_t id, uint8_t *buf)
  159. {
  160.     if(HAL_CAN_GetRxFifoFillLevel(&hcan2, CAN_RX_FIFO0) == 0)
  161.     {
  162.         return 0;
  163.     }
  164.     if(HAL_CAN_GetRxMessage(&hcan2, CAN_RX_FIFO0, &g_canx_rxheader, buf) != HAL_OK)
  165.     {
  166.         return 0;
  167.     }

  168.     /*接收到的ID不对/不是标准帧/不是数据帧*/
  169.     if(g_canx_rxheader.StdId != id || g_canx_rxheader.IDE != CAN_ID_STD || g_canx_rxheader.RTR != CAN_RTR_DATA)
  170.     {
  171.         return 0;
  172.     }

  173.     return g_canx_rxheader.DLC;
  174. }
  175. /* USER CODE END 1 */
复制代码


14_CAN_YeHuo.rar

7.86 MB, 下载次数: 0

CUBEIDE工程

回复

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2025-4-2 01:16 , Processed in 0.194081 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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