9761|4

6

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

在2812上实现CAN通信的问题 [复制链接]

我做了一个基于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;
}
请高手能不能帮我分析分析错误报文是怎么发生的,多谢了。

最新回复

您好楼主,您的问题解决了吗,我也是,程序一直卡在哪里,求解决方案,非常感谢  详情 回复 发表于 2016-4-26 11:12
点赞 关注
 

回复
举报

6

帖子

0

TA的资源

一粒金砂(中级)

沙发
 
没有人遇到过这样的问题吗?各位大侠。
 
 

回复

5

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
最近在调试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 编辑 ]
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(中级)

4
 
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;

}
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(中级)

5
 
您好楼主,您的问题解决了吗,我也是,程序一直卡在哪里,求解决方案,非常感谢
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表