Microchip
直播中

乔丽娜

7年用户 1098经验值
私信 关注
[问答]

dsPIC33EP512MU810上的ECAN停止接收数据

您好,我在DSIC33 EP512MU810编译器上遇到的一些问题是XC16 GCC V1.31,当我启动PIC并发送CAN消息时,CAN控制器总是在一些消息(50…500)之后停止接收数据,在C1RxFul1中不再设置任何比特,在C1INTF中不再设置INT标志,也没有错误计数。ER是递增的,并且没有设置错误INT标志,CAN控制器似乎已经死了。但是传入的消息仍然正确地被确认。这与波特率、定时设置和ID-过滤器无关。如果CAN触发器仅被配置为接收,则其行为相同。同样的行为也在不同的板上。从PIC WorkFink发送数据。函数“Chan-RCVI消息”被称为每一个MS,传入的测试消息具有100ms的周期。当问题发生时,我在CFG模式中手动设置CAN控制器,并返回正常模式,而不做任何操作。介于两者之间,它又开始重复了一段时间。在将CAN控制器从我的代码初始化到数据表中的示例时,我看不出有什么不同。我不知道,有人能帮助我吗?最好是:我没有许可,附加文件????

以上来自于百度翻译


      以下为原文

    Hello,
i have some problems with the ECAN on a dsPIC33EP512MU810
compiler is XC16-gcc V1.31

When i start the pic and send can-messages to it, the Can-controller always stops receiving data after some messages (50...500),

no more bit in C1RXFUL1 is set,
no more Int-Flag is set in C1INTF,
also no err-counter is incremented and no error-int-flag is set,
the can-controller seems to be dead.
but incoming messages are still correctly acknowledged.
this is independent from Baudrate, timing-settings and ID-filters.
if the Can-contoller is only configured for receive, its the same behaviour.  
The same behaviour is also on different Boards.
Sending Data from the pic works fine.
the function "can_rcv_message" is called every ms, the incoming test-messages have a cycle of 100ms.
when the problem occures and i set the can-controller manually in cfg-mode and back in normal-mode, without doing anything in between, it starts receving again for some time.
I can't see any difference in initializing the can-controller from my code to the examples in the datasheet.

i have no more idea,
can anyone help me?
best regards
Karl
PS: i have no permission, to attach files ???


/*
* File:   can1.c
* Author: k0017150
*
* Created on 12. September 2017, 15:34
*/

#include "system.h"
#define  _CAN1_    1
#include "can1.h"
#undef    _CAN1_

#define NUM_OF_ECAN_BUFFERS 32
#define RX_BUF_NR 8
#define OPMODE_CFG   0x04
#define OPMODE_RUN   0x00

static unsigned int ecan1msg_buf_tx[NUM_OF_ECAN_BUFFERS][8]  __attribute__((aligned(NUM_OF_ECAN_BUFFERS * 16)));
static unsigned int ecan1msg_buf_rx[NUM_OF_ECAN_BUFFERS][8]  __attribute__((aligned(NUM_OF_ECAN_BUFFERS * 16)));

static int can_is_init;
static UNS32 can_rcv_counter,can_send_counter,can_int_counter;
static can_message_struct dbg_cms;

static void can1_start(void)  // just for test
{
  C1CTRL1bits.REQOP     = OPMODE_CFG;
  while(C1CTRL1bits.OPMODE != OPMODE_CFG);
  
  C1CTRL1bits.REQOP = OPMODE_RUN;                 
  while(C1CTRL1bits.OPMODE != OPMODE_RUN);
}

void can1_init(void)
{
  _TRISF2=0;               // tx ->output
  RPOR8bits.RP98R=0x0E;    //TX -> RF3 RP99
  _TRISF3=1;               // rx ->input
  RPINR26bits.C1RXR=0x63;  //RX  -> RA2 RPI18
  // Set up the ECAN1 module to operate at 500 kbps. The ECAN module should be first placed in configuration mode.
  C1CTRL1               = 0;
  C1CTRL1bits.REQOP     = OPMODE_CFG;
  while(C1CTRL1bits.OPMODE != OPMODE_CFG);
  
  C1CTRL1bits.WIN       = 0;
  C1CTRL1bits.CANCKS    = 1;  // bit ist invers zu datenblatt!
  
  C1CFG1                = 0;
  C1CFG1bits.BRP        = 4;  //Fcy=50MHz, 1Bit=10Tq=2µs  n = Tq[ns]/40-1  
  C1CFG1bits.SJW        = 1;  //SyncJumpWitdh = 1Tq
  
  C1CFG2                = 0;
  C1CFG2bits.SEG2PH     = 2;  // PhaseSeg2 = 2TQ
  C1CFG2bits.SEG2PHTS   = 1;  // PhaseSeg2 = free programmable
  C1CFG2bits.SAM        = 1;  // 1 sample at samplepoint
  C1CFG2bits.SEG1PH     = 2;  // PhaseSeg1 = 3TQ
  C1CFG2bits.PRSEG      = 2;  // PropagationSeg = 3Tq
  
  C1FCTRL               = 0;
  C1FCTRLbits.FSA       = 0x1F; // no fifo
  C1FCTRLbits.DMABS     = 0x06; // 32 buffer
  
  /* Assign 32x8word Message Buffers for ECAN1 in device RAM. This example uses DMA0 for TX DMA1 for RX. */
  DMA0CONbits.SIZE  = 0x0;
  DMA0CONbits.DIR   = 0x1;
  DMA0CONbits.AMODE = 0x2;
  DMA0CONbits.MODE  = 0x0;
  DMA0REQ = 70;
  DMA0CNT = 7;
  DMA0PAD = (volatile unsigned int)&C1TXD;
  DMA0STAL = (unsigned int) &ecan1msg_buf_tx;
  DMA0STAH = (unsigned int) &ecan1msg_buf_tx;
  DMA0CONbits.CHEN = 0x1;
  /* Configure Message Buffer 0 for Transmission and assign priority */
  C1TR01CONbits.TXEN0 = 0x1;
  C1TR01CONbits.TX0PRI = 0x3;
  
  DMA1CONbits.SIZE = 0x0;
  DMA1CONbits.DIR = 0x0;
  DMA1CONbits.AMODE = 0x2;
  DMA1CONbits.MODE = 0x0;
  DMA1REQ = 34;
  DMA1CNT = 7;
  DMA1PAD = (volatile unsigned int)&C1RXD;
  DMA1STAL = (unsigned int) &ecan1msg_buf_rx;
  DMA1STAH = (unsigned int) &ecan1msg_buf_rx;
  
  DMA1CONbits.CHEN = 0x1;
  C1CTRL1bits.WIN = 1;                            // Clear Window Bit to Access ECAN Control Registers  
  C1FMSKSEL1bits.F0MSK=0x0;                       // Select Acceptance Filter Mask 0 for Acceptance Filter 0
//  C1RXM0SIDbits.SID = 0x7F8;                      // Configure Acceptance Filter Mask 0 register to mask SID<2:0> * Mask Bits (11-bits) : 0b111 1111 1000
                                                  // Configure Acceptance Filter 0 to match standard identifier (11-bits): 0b011 1010 xxx with the mask setting, message with SID  range 0x1D0-0x1D7 accepted
  C1RXM0SIDbits.SID = 0x000;  //test ohne filter                     

  C1RXF0SIDbits.SID = 0x01D0;                     // Acceptance Filter 0 to check for Standard Identifier
  
  C1RXM0SIDbits.MIDE = 0x1;
  C1RXF0SIDbits.EXIDE= 0x0;
  C1BUFPNT1bits.F0BP = RX_BUF_NR;                 /* Acceptance Filter 0 to use Message Buffer RX_BUF_NR to store message */
  C1FEN1bits.FLTEN0=0x1;                          /* Filter 0 enabled for Identifier match with incoming message */
  
  C1CTRL1bits.WIN = 0;                            /* Clear Window Bit to Access ECAN Control Registers */
  
  C1CTRL1bits.REQOP = OPMODE_RUN;                 /* At this point the ECAN1 module is ready to transmit a message. Place the ECAN module in  Normal mode. */
  while(C1CTRL1bits.OPMODE != OPMODE_RUN);
  C1RXFUL1 = C1RXFUL2 = C1RXOVF1 = C1RXOVF2 = 0x0000;
  
  can_is_init=1;
}

INT16 can1_rcv_message(can_message_struct *cms)
{  
  UNS16 result=0;
  
  if(can_is_init){
    result = C1RXFUL1 & (1<     if(result){
      C1INTFbits.RBIF=0;
      can_rcv_counter++;
      
      cms->id = (ecan1msg_buf_rx[RX_BUF_NR][0]>>2) & 0x7ff;
      cms->dlc = ecan1msg_buf_rx[RX_BUF_NR][2]&0x0f;
      cms->data[0]=(BYTE)(ecan1msg_buf_rx[RX_BUF_NR][3]&0xff);
      cms->data[1]=(BYTE)((ecan1msg_buf_rx[RX_BUF_NR][3]>>8)&0xff);
      cms->data[2]=(BYTE)(ecan1msg_buf_rx[RX_BUF_NR][4]&0xff);
      cms->data[3]=(BYTE)((ecan1msg_buf_rx[RX_BUF_NR][4]>>8)&0xff);
      cms->data[4]=(BYTE)(ecan1msg_buf_rx[RX_BUF_NR][5]&0xff);
      cms->data[5]=(BYTE)((ecan1msg_buf_rx[RX_BUF_NR][5]>>8)&0xff);
      cms->data[6]=(BYTE)(ecan1msg_buf_rx[RX_BUF_NR][6]&0xff);
      cms->data[7]=(BYTE)((ecan1msg_buf_rx[RX_BUF_NR][6]>>8)&0xff);
      C1RXFUL1 &= (~(1<       memcpy(&dbg_cms,cms,sizeof(can_message_struct));
    }else{
      can_int_counter++;
    }
  }  
  return(result);
}

INT16 can1_send_message(can_message_struct *cms)
{
  int cnt=0,erg=0;
  if(can_is_init){
    // std-id
    ecan1msg_buf_tx[0][0] = (cms->id << 2)&0x1ffc;
    // ext-id
    ecan1msg_buf_tx[0][1] = 0x0000;
    //dlc
    ecan1msg_buf_tx[0][2] = (cms->dlc)&0x0f;
    /* Write message data bytes */
    ecan1msg_buf_tx[0][3] = (UNS16)cms->data[0] + (((UNS16)cms->data[1]) << 8);
    ecan1msg_buf_tx[0][4] = (UNS16)cms->data[2] + (((UNS16)cms->data[3]) << 8);
    ecan1msg_buf_tx[0][5] = (UNS16)cms->data[4] + (((UNS16)cms->data[5]) << 8);
    ecan1msg_buf_tx[0][6] = (UNS16)cms->data[6] + (((UNS16)cms->data[7]) << 8);
    /* Request message buffer 0 transmission */
    C1TR01CONbits.TXREQ0 = 0x1;
    /* The following shows an example of how the TXREQ bit can be polled to check if transmission
    is complete. */
    do{
      erg=C1TR01CONbits.TXREQ0;
    }while((erg == 1) && (cnt++ < 30000));
    erg=!erg;
    C1INTFbits.TBIF=0;
  }  
  if(erg) can_send_counter++;
  return(erg);
}


void can1_setup(void)
{
  int ic,l,ready=0,nab=1;
  if(can_is_init==0){
    init_page("LA61","ecan1","ESC=end  space=send");
    text(1,1,COLOR_NORMAL,"CAN not available !");
    get_ch();
    return;
  }
  
  do{
    if(nab){
      init_page("LA61","ecan1","ESC=end  space=send");
      nab=0;
    }
   
    l=3;
    text(1,l++,COLOR_NORMAL,"TxCounter:    %06lu",can_send_counter);
    text(1,l++,COLOR_NORMAL,"TxErr:        %d",C1TR01CONbits.TXERR0);
    text(1,l++,COLOR_NORMAL,"TxReq:        %d",C1TR01CONbits.TXREQ0);
    text(1,l++,COLOR_NORMAL,"tx-err-cnt:   %05d",C1EC>>8);
    l++;   
    text(1,l++,COLOR_NORMAL,"RxCounter:    %06lu",can_rcv_counter);
    text(1,l++,COLOR_NORMAL,"RxIntCounter: %06lu",can_int_counter);
    text(1,l++,COLOR_NORMAL,"C1RXFUL1:     0x%04X",C1RXFUL1);
    text(1,l++,COLOR_NORMAL,"C1RXOVF1:     0x%04X",C1RXOVF1);
    text(1,l++,COLOR_NORMAL,"rx-err-cnt:   %05d",C1EC&0xff);
    text(1,l++,COLOR_NORMAL,"C1INTF:       0x%04X",C1INTF);
   
    l++;
    text(1,l++,COLOR_NORMAL,"rx-tel:       0x%03X-%d-0x%02X 0x%02X 0x%02X 0x%02X",dbg_cms.id,dbg_cms.dlc,dbg_cms.data[0],dbg_cms.data[1],dbg_cms.data[2],dbg_cms.data[3]);
    ic=get_ch_or_fail();
  
    switch(ic){
      case FN_Esc:
        ready=1;
      break;
      case 'i':
        can1_start();
        nab=1;        
      break;  
      case ' ':
      {
        can_message_struct cms;
        cms.id = 0x182;
        cms.dlc = 3;
        cms.data[0]++;
        cms.data[1]++;
        cms.data[2]++;
        can1_send_message(&cms);
      }
      break;  
      case 'r':
      break;  
    }  
  }while(!ready);
}


回帖(4)

张娜

2019-1-2 16:52:36
可能是DMA勘误表吗?也就是说,由于错误,缓冲区不能(或可以)在DMA空间中。

以上来自于百度翻译


      以下为原文

    Could it be the DMA errata? i.e. buffers can't (or can) be in DMA space due to errata.
举报

杨叶

2019-1-2 16:58:48
嗨,这是你的第一个罐头设计还是以前做过其他的?要检查的一件事是已知的用于DSPIC33 EP512MU810 CAN模块的勘误表:http://WW1.Microchip .com /…EVICEDOC/8000 526G.PDF.有几个问题被记录在案。请检查这些问题与您使用的CAN,看看是否有任何这些问题可能有关。请描述您的硬件(收发器,你使用?)电缆长度?当做

以上来自于百度翻译


      以下为原文

    Hi,
Is it your first CAN design or did you do some others before ?
One thing to check are the known errata for dsPIC33EP512MU810 CAN module :
http://ww1.microchip.com/...eviceDoc/80000526g.pdf
There are several issues which are documented. Please check these issues against your usage of CAN to see if any of these issues could be related.
Please describe your hardware (which transceiver do you use ?). Length of cable ?
Regards
 
举报

余柳婵

2019-1-2 17:06:14
嗨,我有20年的经验,但这是第一次在PIC上实现。达里奥你给了我一个决定的提示:我已经阅读了关于CAN总线的勘误表,但问题是DMA模块。有时,当总线仲裁器在OffjType中保存总线时,RCV中断会丢失。我已经将DMA优先级设置为MAX,现在它从200000个消息开始工作。

以上来自于百度翻译


      以下为原文

    Hi,
i have experience with can since 20 years, but this is the first implementation on a pic.
 
Dario you gave me the deciding hint:
i have read the errata concerning the can-bus, but the problem was the dma-module. Sometimes can-rcv-interrupts are lost, when the bus-arbiter holds the bus in OFF_state. 
I have set the dma-priority to max and now it works since 200000 Messages.
 
thanks a lot
regards
Karl
 
举报

张娜

2019-1-2 17:19:11
好…

以上来自于百度翻译


      以下为原文

    good...
举报

更多回帖

发帖
×
20
完善资料,
赚取积分