ST MCU Finder
安装免费手机应用,
寻找理想的ST MCU
查看: 274|回复: 1
收起左侧

[STM32F4] CAN 接收中断,数据接收异常

[复制链接]

1

主题

2

帖子

6

积分

实习生

 楼主| 发表于 2017-4-21 12:19 | 显示全部楼层 |返回版面|阅读模式
使用Cube库,FreeRTOS,CAN中断接收
Cube Can 中断服务函数如下:
  1. static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
  2. {
  3.   /* Get the Id */
  4.   hcan->pRxMsg->IDE = (uint8_t)0x04 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
  5.   if (hcan->pRxMsg->IDE == CAN_ID_STD)
  6.   {
  7.     hcan->pRxMsg->StdId = 0x000007FFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21U);
  8.   }
  9.   else
  10.   {
  11.     hcan->pRxMsg->ExtId = 0x1FFFFFFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3U);
  12.   }
  13.   
  14.   hcan->pRxMsg->RTR = (uint8_t)0x02 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
  15.   /* Get the DLC */
  16.   hcan->pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
  17.   /* Get the FIFONumber */
  18.   hcan->pRxMsg->FIFONumber = FIFONumber;
  19.   /* Get the FMI */
  20.   hcan->pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8U);
  21.   /* Get the data field */
  22.   hcan->pRxMsg->Data[0U] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
  23.   hcan->pRxMsg->Data[1U] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8U);
  24.   hcan->pRxMsg->Data[2U] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16U);
  25.   hcan->pRxMsg->Data[3U] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24U);
  26.   hcan->pRxMsg->Data[4U] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
  27.   hcan->pRxMsg->Data[5U] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8U);
  28.   hcan->pRxMsg->Data[6U] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16U);
  29.   hcan->pRxMsg->Data[7U] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24U);
  30.   /* Release the FIFO */
  31.   /* Release FIFO0 */
  32.   if (FIFONumber == CAN_FIFO0)
  33.   {
  34.     __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
  35.    
  36.     /* Disable FIFO 0 message pending Interrupt */
  37.     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP0);
  38.   }
  39.   /* Release FIFO1 */
  40.   else /* FIFONumber == CAN_FIFO1 */
  41.   {
  42.     __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
  43.    
  44.     /* Disable FIFO 1 message pending Interrupt */
  45.     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP1);
  46.   }
  47.   
  48.   if(hcan->State == HAL_CAN_STATE_BUSY_RX)
  49.   {   
  50.     /* Disable Error warning, Error passive, Bus-off, Last error code
  51.        and Error Interrupts */
  52.     __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
  53.                                CAN_IT_EPV |
  54.                                CAN_IT_BOF |
  55.                                CAN_IT_LEC |
  56.                                CAN_IT_ERR);
  57.   }
  58.   
  59.   if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
  60.   {
  61.     /* Disable CAN state */
  62.     hcan->State = HAL_CAN_STATE_BUSY_TX;
  63.   }
  64.   else
  65.   {
  66.     /* Change CAN state */
  67.     hcan->State = HAL_CAN_STATE_READY;
  68.   }

  69.   /* Receive complete callback */
  70.   HAL_CAN_RxCpltCallback(hcan);

  71.   /* Return function status */
  72.   return HAL_OK;
  73. }
复制代码

我的应用程序:
  1. static uint8_t can_rec_ack(uint32_t millisec)
  2. {
  3.     if(osSemaphoreWait(can_xSemaphore, millisec) == osOK)
  4.         return 1;
  5.     else
  6.         return 0;
  7. }

  8. uint8_t can_call(uint8_t dt, uint8_t slot)
  9. {
  10.     CAN_EXID_UN can_id;
  11.     can_id.id.d_id = 0x0;
  12.     can_id.id.dir = CAN_ID_M2S;
  13.     can_id.id.fun = CF_CALL;
  14.     can_id.id.type = dt;
  15.     can_id.id.slot = slot;

  16.     hcan1.pTxMsg->DLC = 1;
  17.     hcan1.pTxMsg->Data[0] = 0xAA;
  18.     hcan1.pTxMsg->ExtId = can_id.value;
  19.     HAL_CAN_Receive_IT(&hcan1, CAN_FIFO0);
  20.     if(HAL_OK == HAL_CAN_Transmit(&hcan1, 10))
  21.     {
  22.         if(can_rec_ack(100))
  23.         {
  24.             osDelay(2);
  25.             log_printf(LOG_INFO, "CAN_RX:0x%X-0x%X,Ack:0x%X;soft_ver:%d;hw_ver:%d;build:%d\r\n",hcan1.Instance->sFIFOMailBox[0].RDLR,
  26.             hcan1.Instance->sFIFOMailBox[0].RDHR, hcan1.pRxMsg->Data[0], hcan1.pRxMsg->Data[1], hcan1.pRxMsg->Data[2], *(uint32_t *)&hcan1.pRxMsg->Data[4]);
  27.             return 1;
  28.         }
  29.         else
  30.         {
  31.             log_printf(LOG_ERR, "%s call dev:%d slot:%d timeout\r\n", __func__, dt, slot);
  32.             return 0;
  33.         }
  34.     }
  35.     else
  36.     {
  37.         log_printf(LOG_ERR, "%s send sta 0x%X\r\n", __func__, hcan1.State);
  38.         return 0;
  39.     }
  40. }
复制代码


主设备呼叫从设备,从设备回复8个字节。主设备先启动接收中断,然后发出呼叫帧,马上从设备回复,HAL_CAN_RxCpltCallback函数发信号量,此时去读hcan1.pRxMsg->Data中的8个字节,发现全0,但是直接通过寄存器访问的方式去读,数据都已经收到了。加延时的话也可以从hcan1.pRxMsg->Data中读取正确的值。是哪里有cache吗?还是其他的什么原因?

我在中断服务函数的第71行代码执行之后去读hcan1.pRxMsg->Data,数据不对,那说明中断服务函数的22-29行还没生效?

1

主题

2

帖子

6

积分

实习生

 楼主| 发表于 2017-4-21 14:58 | 显示全部楼层 |返回版面
问题出在信号量上了CMSIS-RTOS的osSemaphoreCreate(osSemaphore(CAN_SEM) , 1 ),创建了一个信号量,并初始化成有效,所以第一次就没收到CAN数据就进去读了
您需要登录后才可以回帖 登录 | 注册 手机登录

本版积分规则

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