打印

stm32 can如何发送扩展帧,扩展ID如何发送,现在是对不上

[复制链接]
22297|31
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zangjinlian|  楼主 | 2013-8-5 09:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
今天偶然用到CAN的扩展帧,现在的问题是,我发送的和我接收的对不上,我发的时候,是判断了是标准帧还是扩展帧,当判断标准帧的时候发送的ID和接收的ID可以对应上,但是,发送的是扩展帧的时候,发送的ID不知道如何加载进去,我把STDID和EXTID分开,开始的时候是STDID作低位,EXTID是高位,还有一个方式是,STDID作为标准帧,EXTID的是扩展帧的ID,这两种都不是很对……

请大虾不吝赐教
沙发
vacky| | 2013-8-5 09:32 | 只看该作者
楼主最好把代码贴一下,方便分析,扩展帧29位中低11位是标准帧

使用特权

评论回复
板凳
zangjinlian|  楼主 | 2013-8-5 09:34 | 只看该作者
vacky 发表于 2013-8-5 09:32
楼主最好把代码贴一下,方便分析,扩展帧29位中低11位是标准帧

是呀,但是在程序中,不知道如何添加

使用特权

评论回复
地板
zangjinlian|  楼主 | 2013-8-5 09:35 | 只看该作者
int8_t Can_Send_Msg(int8_t* msg,int8_t len)
{       
  int8_t mbox;
  int16_t i=0;
  CanTxMsg TxMessage;
  GPIO_SetBits(GPIOA, GPIO_Pin_2);
  TxMessage.StdId=FStdId;//FStdId;                                         // 标准标识符为(11位)
  TxMessage.ExtId=FExtId;//FExtId;                                 // 设置扩展标示符(29位)
  TxMessage.IDE=FIDE;         // 使用扩展标识符
  TxMessage.RTR=FRTR;         // 消息类型为数据帧,一帧8位          
  TxMessage.DLC=len;        // 发送两帧信息
  for(i=0;i<len;i++)
  TxMessage.Data[i]=msg[i];                                 // 第一帧信息         
  mbox= CAN_Transmit(CAN1, &TxMessage);   
  i=0;
  while((CAN_TransmitStatus(CAN1, mbox)!=CANTXFAILED)&&(i<0XFFF))i++;        //等待发送结束
  if(i>=0XFFF)return 1;
  return 0;               

}

使用特权

评论回复
5
zangjinlian|  楼主 | 2013-8-5 09:36 | 只看该作者
TxMessage.StdId=FStdId;//FStdId;                                         // 标准标识符为(11位)
  TxMessage.ExtId=FExtId;//FExtId;

我想知道,这两个ID值,该如何载入

使用特权

评论回复
6
vacky| | 2013-8-5 09:38 | 只看该作者
使用扩展帧就直接使用TxMessage.RTR=FRTR;  这条
TxMessage.IDE=FIDE;这条可以去掉
你要发的扩展标示符就是FExtId

使用特权

评论回复
7
zangjinlian|  楼主 | 2013-8-5 09:41 | 只看该作者
vacky 发表于 2013-8-5 09:38
使用扩展帧就直接使用TxMessage.RTR=FRTR;  这条
TxMessage.IDE=FIDE;这条可以去掉
你要发的扩展标示符就 ...

TxMessage.IDE=FIDE;         // 使用扩展标识符
  TxMessage.RTR=FRTR;         // 消息类型为数据帧,一帧8位
可是这两个的作用是不一样的吧,我理解一个标准帧和扩展帧,一个是数据帧和远程帧

使用特权

评论回复
8
andyding| | 2013-8-5 13:13 | 只看该作者
学习了!

使用特权

评论回复
9
nucdck| | 2013-8-5 13:33 | 只看该作者
//        TxMessage.StdId = ((0x03 & 0x000f)<<4) | (0x000f) & 0x00ff;// 设定标准标识符 ,帧类型3bit + 目的地址4bit + 本单元地址4bit
          TxMessage.ExtId = (0x03<<24) | (0x0f<<20) |(0x01) & 0x00ff; // 设定扩展标识符
          TxMessage.RTR = CAN_RTR_DATA;// 设定消息标识符的类型
          TxMessage.IDE = CAN_ID_EXT;  // 设定待传输消息的帧类型
          TxMessage.DLC = 2;                   //设定待传输消息的帧长度       
          TxMessage.Data[0]=FPGA_addr;
        TxMessage.Data[1]=i;
//        TxMessage.Data[2]=(temp_int/1000) |0x30; temp_int=temp_int%1000;
//        TxMessage.Data[3]=(temp_int/100)  |0x30; temp_int=temp_int%100;
//        TxMessage.Data[4]=(temp_int/10)   |0x30; temp_int=temp_int%10;
//        TxMessage.Data[5]= temp_int                  |0x30;

        CAN_Transmit(CAN1, &TxMessage);        //开始一个消息的传输

使用特权

评论回复
10
zangjinlian|  楼主 | 2013-8-5 14:35 | 只看该作者
nucdck 发表于 2013-8-5 13:33
//        TxMessage.StdId = ((0x03 & 0x000f)

我现在发送的时候跟踪,确实是发送的扩展帧,但接的时候仍然是标准帧

使用特权

评论回复
11
zangjinlian|  楼主 | 2013-8-5 14:37 | 只看该作者
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&TSR_TME0) == TSR_TME0)
  {
    transmit_mailbox = 0;
  }
  else if ((CANx->TSR&TSR_TME1) == TSR_TME1)
  {
    transmit_mailbox = 1;
  }
  else if ((CANx->TSR&TSR_TME2) == TSR_TME2)
  {
    transmit_mailbox = 2;
  }
  else
  {
    transmit_mailbox = CAN_NO_MB;
        RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1, ENABLE);
    RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1, DISABLE);
  }
  if (transmit_mailbox != CAN_NO_MB)
  {
    /* Set up the Id */
    CANx->sTxMailBox[transmit_mailbox].TIR &= TMIDxR_TXRQ;
    if (TxMessage->IDE == CAN_ID_STD)
    {
      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;
}






void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage)
{
  GPIO_SetBits(GPIOA, GPIO_Pin_2);
  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_CAN_FIFO(FIFONumber));
  /* Get the Id */
  RxMessage->IDE = (uint8_t)0x04 & CANx->sFIFOMailBox[FIFONumber].RIR;
  if (RxMessage->IDE == CAN_ID_STD)
  {
          FIDE=0;
    RxMessage->StdId = (uint32_t)0x000007FF & (CANx->sFIFOMailBox[FIFONumber].RIR >> 21);          //标准帧
  }
  else
  {
          FIDE=1;
    RxMessage->ExtId = (uint32_t)0x1FFFFFFF & (CANx->sFIFOMailBox[FIFONumber].RIR >> 3);          //数据帧
  }
  
  RxMessage->RTR = (uint8_t)0x02 & CANx->sFIFOMailBox[FIFONumber].RIR;
  /* Get the DLC */
  RxMessage->DLC = (uint8_t)0x0F & CANx->sFIFOMailBox[FIFONumber].RDTR;
  /* Get the FMI */
  RxMessage->FMI = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDTR >> 8);
  /* Get the data field */
  RxMessage->Data[0] = (uint8_t)0xFF & CANx->sFIFOMailBox[FIFONumber].RDLR;
  RxMessage->Data[1] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 8);
  RxMessage->Data[2] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 16);
  RxMessage->Data[3] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 24);
  RxMessage->Data[4] = (uint8_t)0xFF & CANx->sFIFOMailBox[FIFONumber].RDHR;
  RxMessage->Data[5] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 8);
  RxMessage->Data[6] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 16);
  RxMessage->Data[7] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 24);
  /* Release the FIFO */
  CAN_FIFORelease(CANx, FIFONumber);
}

使用特权

评论回复
12
flyleaf91| | 2013-8-5 14:50 | 只看该作者
野火stm32开发板有开源的CAN 扩展帧 代码

使用特权

评论回复
13
vacky| | 2013-8-5 14:54 | 只看该作者
zangjinlian 发表于 2013-8-5 09:36
TxMessage.StdId=FStdId;//FStdId;                                         // 标准标识符为(11位)
   ...

这两条ID值只能选其一使用,TxMessage.StdId是标准标示符,TxMessage.ExtId是扩展标示符,直接填写你要发的标示符就好了啊,
比如你要发送的标准标示符为0X0602那就写TxMessage.StdId=0X0602;
如果你要发送扩展标示符为0X00200602那就写TxMessage.ExtId=0X00200602;
楼主说的如何载入是什么意思?

使用特权

评论回复
14
zangjinlian|  楼主 | 2013-8-5 15:25 | 只看该作者
vacky 发表于 2013-8-5 14:54
这两条ID值只能选其一使用,TxMessage.StdId是标准标示符,TxMessage.ExtId是扩展标示符,直接填写你要发 ...

呵呵,这个不是只写一个,是写好程,让程序选其中一个,当然我这个是有标志的,当这个标志是扩展帧的时候,就可以选择扩展帧的ID发送

使用特权

评论回复
15
zangjinlian|  楼主 | 2013-8-5 15:28 | 只看该作者
如果只写一个,当还想发送数据帧的时候怎么办,所以我现在的问题就是,当我想发送数据帧的时候能发,想发扩展帧的时候也能发,现在的问题是,我可以发送扩展帧了,但是接收的那边的标志还是数据帧
/* Get the Id */
  RxMessage->IDE = (uint8_t)0x04 & CANx->sFIFOMailBox[FIFONumber].RIR;
  if (RxMessage->IDE == CAN_ID_STD)
  {

程序还是走到标准帧的里面

使用特权

评论回复
16
tergy2012| | 2013-8-5 15:41 | 只看该作者
看到好问题,路过学学习

使用特权

评论回复
17
vacky| | 2013-8-5 15:53 | 只看该作者
zangjinlian 发表于 2013-8-5 15:28
如果只写一个,当还想发送数据帧的时候怎么办,所以我现在的问题就是,当我想发送数据帧的时候能发,想发扩 ...

楼主的测试环境是怎么样的 用的是板子自身的回环模式?还是两块板子之间的通行?
发完一帧 要发下一帧不同类型的就重新填写TxMessage这个发送结构体啊

使用特权

评论回复
18
tergy2012| | 2013-8-5 15:53 | 只看该作者
路过学习的啊

使用特权

评论回复
19
cjhk| | 2013-8-5 18:44 | 只看该作者
学习学习   这一块   了解的不多  楼主    希望能早点将这个问题解决了

使用特权

评论回复
20
zangjinlian|  楼主 | 2013-8-6 09:51 | 只看该作者
vacky 发表于 2013-8-5 15:53
楼主的测试环境是怎么样的 用的是板子自身的回环模式?还是两块板子之间的通行?
发完一帧 要发下一帧不 ...

我用的是两个板子对发的,其中还有一个上位机,但是我现在如果没有发送扩展帧而是标准帧的时候一切是正常的。

使用特权

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

本版积分规则

10

主题

127

帖子

4

粉丝