在2812上实现CAN通信的问题

2019-03-26 15:15发布

我做了一个基于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;
}
请高手能不能帮我分析分析错误报文是怎么发生的,多谢了。 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
4条回答
bevyn
1楼-- · 2019-03-27 00:55
< 没有人遇到过这样的问题吗?各位大侠。
zuiyedemeng
2楼-- · 2019-03-27 06:01
< 最近在调试DSP28035can通信,采用查询方式发送,发送标志始终显示未发送成功,但TX管脚示波器上又有发送数据波形,但显示的波形可以看出发送的数据又是不正确的全为0,请教下知道是怎么回事吗?
代码如下:
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 编辑 ]
zuiyedemeng
3楼-- · 2019-03-27 06:14
 精彩回答 2  元偷偷看……
chjlx2012
4楼-- · 2019-03-27 07:11
您好楼主,您的问题解决了吗,我也是,程序一直卡在哪里,求解决方案,非常感谢

一周热门 更多>