我做了一个基于CAN总线的通信程序,从上位机定时接收控制指令,但大概每过3、4个小时就会收到一帧错误报文。这个问题困扰我了很久,一直解决不了,请哪位大侠帮忙指点指点,多谢了。
问题是这样的,我用19号can邮箱从上位机接收数据,接收的数据为0x11 11 11 11 11 11 11 11,但过一段时间,就会收到0x00 11 11 11 11 11 11 11这样的错误报文,而且根据测试程序看,当发现有错误报文时,立马重新读取,就能读到正确的数据。下面是我的测试程序:
//CANopenTestBuffer为40*8的二维数组,前20*8用来记录发现错误报文后,重新从寄存器读取的数据,后20*8用来记录第一次读错的数据
//另外,设置控制寄存器OPC=1,即当can寄存器数据未被读取前,新到数据是不能覆盖旧数据的
if(ECanaRegs.CANRMP.bit.RMP19==1)
{
TTCANopenRECBuffer[0]=ECanaMboxes.MBOX19.MDL.byte.BYTE0;
TTCANopenRECBuffer[1]=ECanaMboxes.MBOX19.MDL.byte.BYTE1;
TTCANopenRECBuffer[2]=ECanaMboxes.MBOX19.MDL.byte.BYTE2;
TTCANopenRECBuffer[3]=ECanaMboxes.MBOX19.MDL.byte.BYTE3;
TTCANopenRECBuffer[4]=ECanaMboxes.MBOX19.MDH.byte.BYTE4;
TTCANopenRECBuffer[5]=ECanaMboxes.MBOX19.MDH.byte.BYTE5;
TTCANopenRECBuffer[6]=ECanaMboxes.MBOX19.MDH.byte.BYTE6;
TTCANopenRECBuffer[7]=ECanaMboxes.MBOX19.MDH.byte.BYTE7;
if(TTCANopenRECBuffer[0]!=CANopenMBRECBuffer1[0])//以数据变化为判断错误依据
{//当有错误报文时
TrecCounter++;
CANopenMBRECBuffer1[0]=TTCANopenRECBuffer[0];
//当有错误报文发生时,就重新从can寄存器读取数据,存入数组CANopenTestBuffer[testIndex]中
CANopenTestBuffer[testIndex][0]=ECanaMboxes.MBOX19.MDL.byte.BYTE0;
CANopenTestBuffer[testIndex][1]=ECanaMboxes.MBOX19.MDL.byte.BYTE1;
CANopenTestBuffer[testIndex][2]=ECanaMboxes.MBOX19.MDL.byte.BYTE2;
CANopenTestBuffer[testIndex][3]=ECanaMboxes.MBOX19.MDL.byte.BYTE3;
CANopenTestBuffer[testIndex][4]=ECanaMboxes.MBOX19.MDH.byte.BYTE4;
CANopenTestBuffer[testIndex][5]=ECanaMboxes.MBOX19.MDH.byte.BYTE5;
CANopenTestBuffer[testIndex][6]=ECanaMboxes.MBOX19.MDH.byte.BYTE6;
CANopenTestBuffer[testIndex][7]=ECanaMboxes.MBOX19.MDH.byte.BYTE7;
//当有错误报文发生时,把读到到的错误报文存入数组CANopenTestBuffer[testIndex+20]中
CANopenTestBuffer[testIndex+20][0]=TTCANopenRECBuffer[0];
CANopenTestBuffer[testIndex+20][1]=TTCANopenRECBuffer[1];
CANopenTestBuffer[testIndex+20][2]=TTCANopenRECBuffer[2];
CANopenTestBuffer[testIndex+20][3]=TTCANopenRECBuffer[3];
CANopenTestBuffer[testIndex+20][4]=TTCANopenRECBuffer[4];
CANopenTestBuffer[testIndex+20][5]=TTCANopenRECBuffer[5];
CANopenTestBuffer[testIndex+20][6]=TTCANopenRECBuffer[6];
//CANopenTestBuffer[testIndex+20][7]=CANopenMBRECBuffer[7];
testIndex=(testIndex+1)%20;
if(ECanaRegs.CANRML.bit.RML19==1)
CANopenTestBuffer[20][7]++;
}
ECanaRegs.CANRMP.all = 0;
ECanaRegs.CANRMP.bit.RMP19=1;
}
请高手能不能帮我分析分析错误报文是怎么发生的,多谢了。
此帖出自
小平头技术问答
代码如下:
void InitCan(void)
{
struct ECAN_REGS ECanaShadow;
EALLOW;
ECanaShadow.CANTIOC.all = ECanaRegs.CANTIOC.all;
ECanaShadow.CANTIOC.bit.TXFUNC = 1;
ECanaRegs.CANTIOC.all = ECanaShadow.CANTIOC.all;
ECanaShadow.CANRIOC.all = ECanaRegs.CANRIOC.all;
ECanaShadow.CANRIOC.bit.RXFUNC = 1;
ECanaRegs.CANRIOC.all = ECanaShadow.CANRIOC.all;
ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
ECanaShadow.CANMC.bit.SCB = 1;// User has selected eCAN mode
ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
ECanaMboxes.MBOX0.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX1.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX2.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX3.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX4.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX5.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX6.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX7.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX8.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX9.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX10.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX11.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX12.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX13.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX14.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX15.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX16.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX17.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX18.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX19.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX20.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX21.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX22.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX23.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX24.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX25.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX26.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX27.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX28.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX29.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX30.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX31.MSGCTRL.all = 0x00000000;
ECanaRegs.CANTA.all = 0xFFFFFFFF; // Clear all TAn bits
ECanaRegs.CANRMP.all = 0xFFFFFFFF; // Clear all RMPn bits
ECanaRegs.CANGIF0.all = 0xFFFFFFFF; // Clear all interrupt flag bits
ECanaRegs.CANGIF1.all = 0xFFFFFFFF;
// Configure bit timing parameters for eCANA
ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
ECanaShadow.CANMC.bit.CCR = 1 ; // Set CCR = 1
ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
// Wait until the CPU has been granted permission to change the configuration registers
do
{
ECanaShadow.CANES.all = ECanaRegs.CANES.all;
} while(ECanaShadow.CANES.bit.CCE != 1 );
ECanaShadow.CANBTC.all = 0;
ECanaShadow.CANBTC.bit.BRPREG = 1; //2 1
ECanaShadow.CANBTC.bit.TSEG2REG = 9; //1 9
ECanaShadow.CANBTC.bit.TSEG1REG = 6; //6 6
ECanaShadow.CANBTC.bit.SAM = 1;
ECanaRegs.CANBTC.all = ECanaShadow.CANBTC.all;
ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
ECanaShadow.CANMC.bit.CCR = 0 ;
/////////////////////////////////////////////////////
/* ECanaShadow.CANMC.bit.PDR = 0;
ECanaShadow.CANMC.bit.DBO = 0;
ECanaShadow.CANMC.bit.WUBA = 0;
ECanaShadow.CANMC.bit.CDR = 0;
ECanaShadow.CANMC.bit.ABO = 0;
ECanaShadow.CANMC.bit.STM = 0;
ECanaShadow.CANMC.bit.SRES = 0;
ECanaShadow.CANMC.bit.MBNR = 0;
ECanaShadow.CANMC.bit.SUSP = 1;*/
/////////////////////////////////////////////////////
ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
do
{
ECanaShadow.CANES.all = ECanaRegs.CANES.all;
} while(ECanaShadow.CANES.bit.CCE != 0 );
//Disable all Mailboxes
ECanaRegs.CANME.all = 0; // disable
EDIS;
EALLOW;
ECanaMboxes.MBOX0.MSGID.all = 0x00040000;//0x9555AAA0 0x00040000
ECanaMboxes.MBOX0.MSGCTRL.bit.DLC = 8; //Send MailBox
ECanaMboxes.MBOX1.MSGCTRL.bit.DLC = 8; //Receive MailBox
ECanaRegs.CANMD.all =0x00000002;//0:send 1:receive
ECanaRegs.CANME.all = 0x00000003;
EDIS;
ECanaMboxes.MBOX0.MDL.all = 0x12345678;//0x9555AAA0;
ECanaMboxes.MBOX0.MDH.all = 0x89ABCDEF;
EALLOW;
ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
ECanaShadow.CANMC.bit.STM = 0; // Configure CAN for self-test mode 1
ECanaShadow.CANMC.bit.DBO = 1;
ECanaShadow.CANMC.bit.ABO = 1; //CAN BUS ON
ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
EDIS;
EALLOW;
ECanaRegs.CANMIM.all=0x00000002;//使能邮箱1接收中断
ECanaRegs.CANMIL.all=0;//所有邮箱在中断0(ECANOINT)产生邮箱中断
ECanaRegs.CANGIF0.all=0xFFFFFFFF;//全局中断标志寄存器CANGIF0所有标志位清零
ECanaRegs.CANGIF1.all=0xFFFFFFFF;//全局中断标志寄存器CANGIF1所有标志位清零
ECanaRegs.CANGIM.bit.I0EN=1;//eCAN模块中中断0使能
EDIS;
}
发送函数:
void sCanSend(void)
{
ECanaRegs.CANTRS.all = 0;
ECanaMboxes.MBOX0.MDL.all = 0x12345678;//0x9555AAA0;
ECanaMboxes.MBOX0.MDH.all = 0x89ABCDEF;
ECanaRegs.CANTRS.all = 0x00000001;
while(ECanaRegs.CANTA.all != 0x00000001 ) {}//程序会一直卡在这里
ECanaRegs.CANTA.all = 0x00000001;
}
[ 本帖最后由 zuiyedemeng 于 2013-5-13 17:10 编辑 ]
一周热门 更多>