[STM32F4]

STM32FCAN发送出错是什么原因?

[复制链接]
6881|16
手机看帖
扫描二维码
随时随地手机跟帖
icaredbd|  楼主 | 2017-5-18 15:39 | 显示全部楼层 |阅读模式
本帖最后由 icaredbd 于 2017-5-18 15:42 编辑

在环回模式下可以成功,但是在正常工作模式下,没有成功发送数据。
CAN_TransmitStatus最终返回
CAN_TxStatus_Pending,请问大牛们是什么原因?
u8 CAN1_Send_Msg(u8* msg,u8 len)
{        
  u8 mbox;
  u16 i=0;
  CanTxMsg TxMessage;
  TxMessage.StdId=0x12;         
  TxMessage.ExtId=0x12;         
  TxMessage.IDE=0;               
  TxMessage.RTR=0;                 
  TxMessage.DLC=len;                                                        
  for(i=0;i<len;i++)
  TxMessage.Data=msg;                                    
  mbox= CAN_Transmit(CAN1, &TxMessage);   
  i=0;
  while((CAN_TransmitStatus(CAN1, mbox)==CAN_TxStatus_Failed)&&(i<0XFFF))i++;        //µÈ´ý·¢ËͽáÊø
  if(i>=0XFFF)return 1;
  return 0;        
}


uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage)
{
  uint8_t transmit_mailbox = 0;
  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_CAN_IDTYPE(TxMessage->IDE));
  assert_param(IS_CAN_RTR(TxMessage->RTR));
  assert_param(IS_CAN_DLC(TxMessage->DLC));

  /* Select one empty transmit mailbox */
  if ((CANx->TSR&CAN_TSR_TME0) == CAN_TSR_TME0)
  {
    transmit_mailbox = 0;
  }
  else if ((CANx->TSR&CAN_TSR_TME1) == CAN_TSR_TME1)
  {
    transmit_mailbox = 1;
  }
  else if ((CANx->TSR&CAN_TSR_TME2) == CAN_TSR_TME2)
  {
    transmit_mailbox = 2;
  }
  else
  {
    transmit_mailbox = CAN_TxStatus_NoMailBox;
  }

  if (transmit_mailbox != CAN_TxStatus_NoMailBox)
  {
    /* Set up the Id */
    CANx->sTxMailBox[transmit_mailbox].TIR &= TMIDxR_TXRQ;
    if (TxMessage->IDE == CAN_Id_Standard)
    {
      assert_param(IS_CAN_STDID(TxMessage->StdId));  
      CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage->StdId << 21) | \
                                                  TxMessage->RTR);
    }
    else
    {
      assert_param(IS_CAN_EXTID(TxMessage->ExtId));
      CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage->ExtId << 3) | \
                                                  TxMessage->IDE | \
                                                  TxMessage->RTR);
    }

    /* Set up the DLC */
    TxMessage->DLC &= (uint8_t)0x0000000F;
    CANx->sTxMailBox[transmit_mailbox].TDTR &= (uint32_t)0xFFFFFFF0;
    CANx->sTxMailBox[transmit_mailbox].TDTR |= TxMessage->DLC;

    /* Set up the data field */
    CANx->sTxMailBox[transmit_mailbox].TDLR = (((uint32_t)TxMessage->Data[3] << 24) |
                                             ((uint32_t)TxMessage->Data[2] << 16) |
                                             ((uint32_t)TxMessage->Data[1] << 8) |
                                             ((uint32_t)TxMessage->Data[0]));
    CANx->sTxMailBox[transmit_mailbox].TDHR = (((uint32_t)TxMessage->Data[7] << 24) |
                                             ((uint32_t)TxMessage->Data[6] << 16) |
                                             ((uint32_t)TxMessage->Data[5] << 8) |
                                             ((uint32_t)TxMessage->Data[4]));
    /* Request transmission */
    CANx->sTxMailBox[transmit_mailbox].TIR |= TMIDxR_TXRQ;
  }
  return transmit_mailbox;
}

/**
  * @brief  Checks the transmission status of a CAN Frame.
  * @param  CANx: where x can be 1 or 2 to select the CAN peripheral.
  * @param  TransmitMailbox: the number of the mailbox that is used for transmission.
  * @retval CAN_TxStatus_Ok if the CAN driver transmits the message,
  *         CAN_TxStatus_Failed in an other case.
  */
uint8_t CAN_TransmitStatus(CAN_TypeDef* CANx, uint8_t TransmitMailbox)
{
  uint32_t state = 0;

  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_CAN_TRANSMITMAILBOX(TransmitMailbox));

  switch (TransmitMailbox)
  {
    case (CAN_TXMAILBOX_0):
      state =   CANx->TSR &  (CAN_TSR_RQCP0 | CAN_TSR_TXOK0 | CAN_TSR_TME0);
      break;
    case (CAN_TXMAILBOX_1):
      state =   CANx->TSR &  (CAN_TSR_RQCP1 | CAN_TSR_TXOK1 | CAN_TSR_TME1);
      break;
    case (CAN_TXMAILBOX_2):
      state =   CANx->TSR &  (CAN_TSR_RQCP2 | CAN_TSR_TXOK2 | CAN_TSR_TME2);
      break;
    default:
      state = CAN_TxStatus_Failed;
      break;
  }
  switch (state)
  {
      /* transmit pending  */
    case (0x0): state = CAN_TxStatus_Pending;
      break;
      /* transmit failed  */
     case (CAN_TSR_RQCP0 | CAN_TSR_TME0): state = CAN_TxStatus_Failed;
      break;
     case (CAN_TSR_RQCP1 | CAN_TSR_TME1): state = CAN_TxStatus_Failed;
      break;
     case (CAN_TSR_RQCP2 | CAN_TSR_TME2): state = CAN_TxStatus_Failed;
      break;
      /* transmit succeeded  */
    case (CAN_TSR_RQCP0 | CAN_TSR_TXOK0 | CAN_TSR_TME0):state = CAN_TxStatus_Ok;
      break;
    case (CAN_TSR_RQCP1 | CAN_TSR_TXOK1 | CAN_TSR_TME1):state = CAN_TxStatus_Ok;
      break;
    case (CAN_TSR_RQCP2 | CAN_TSR_TXOK2 | CAN_TSR_TME2):state = CAN_TxStatus_Ok;
      break;
    default: state = CAN_TxStatus_Failed;
      break;
  }
  return (uint8_t) state;
}

zhuomuniao110| | 2017-5-18 16:44 | 显示全部楼层
代码自己写的还是用的库函数?

使用特权

评论回复
icaredbd|  楼主 | 2017-5-18 16:56 | 显示全部楼层
用的是stm32f4xx_can.c的库函数,bsp\stm32f40x\Libraries\STM32F4xx_StdPeriph_Driver\src下面的CAN实现库。
我在上面附了代码

使用特权

评论回复
yklstudent| | 2017-5-18 17:33 | 显示全部楼层
确认硬件和接线没有问题?????

使用特权

评论回复
icaredbd|  楼主 | 2017-5-18 17:39 | 显示全部楼层
确认硬件和接线没有问题,跑了另外一套软件是OK,所以验证过的。

使用特权

评论回复
icaredbd|  楼主 | 2017-5-18 17:42 | 显示全部楼层
怎么查找can发送出错原因?
怎么验证系统时钟和can 波特率设置有没有生效?

使用特权

评论回复
icaredbd|  楼主 | 2017-5-18 22:02 | 显示全部楼层
已经解决,代码没有问题。
是外围电路问题。

使用特权

评论回复
sanfuzi| | 2017-5-19 00:12 | 显示全部楼层
自测能够通过?

使用特权

评论回复
sanfuzi| | 2017-5-19 00:13 | 显示全部楼层
STM32的can可以自测。

使用特权

评论回复
空空空| | 2017-7-19 16:55 | 显示全部楼层
sanfuzi 发表于 2017-5-19 00:13
STM32的can可以自测。

问下怎么自测

使用特权

评论回复
pattywu| | 2017-7-19 16:59 | 显示全部楼层
自己发送,自己接收,是指测试模式,不是CAN_TX接到CAN_RX。

使用特权

评论回复
空空空| | 2017-7-19 17:01 | 显示全部楼层
sanfuzi 发表于 2017-5-19 00:13
STM32的can可以自测。

问下怎么自测?????

使用特权

评论回复
空空空| | 2017-7-19 17:23 | 显示全部楼层
pattywu 发表于 2017-7-19 16:59
自己发送,自己接收,是指测试模式,不是CAN_TX接到CAN_RX。

不可以回环测试吗,我现在CAN通信发送数据没有得到邮箱,一直transmit_mailbox=CAN_TxStatus_NoMailBox,查了配置没发现哪里错了,回环测试也失败

使用特权

评论回复
ningling_21| | 2017-7-19 18:42 | 显示全部楼层
查看一下是不是发送邮箱满了

使用特权

评论回复
空空空| | 2017-7-19 20:34 | 显示全部楼层
不是的,我后来参考官方例子,CAN回环测试通过,正常模式还是不行,量了CAN收发芯片电压,不在工作电压范围,是不是因为收发芯片没工作的原因,但是怎么会导致stm32邮箱问题

使用特权

评论回复
pattywu| | 2017-7-19 20:36 | 显示全部楼层
CAN通信,要有接收方,并且有确认信号,才算发送成功。
不是串口,发送方只管发,不对方在不在接收,不管对方在不在线。

使用特权

评论回复
空空空| | 2017-7-20 09:55 | 显示全部楼层
pattywu 发表于 2017-7-19 20:36
CAN通信,要有接收方,并且有确认信号,才算发送成功。
不是串口,发送方只管发,不对方在不在接收,不管 ...

你的意思是一定要接接收方才行?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

11

帖子

0

粉丝