您好,我在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 s
till 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);
}