你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

CAN 接收中断,数据接收异常

[复制链接]
captainliuy 提问时间:2017-4-21 12:24 /
使用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 评论1 发布时间:2017-4-21 12:24

举报

1个回答
captainliuy 回答时间:2017-4-21 14:58:17
问题出在信号量上了CMSIS-RTOS的osSemaphoreCreate(osSemaphore(CAN_SEM) , 1 ),创建了一个信号量,并初始化成有效,所以第一次就没收到CAN数据就进去读了

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2 结帖奖励

查看全部评分

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版