This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
问题说明:我在程序中,将3个邮箱配置为接收邮箱,将接收中断配置为ECAN0INT中断线,当某个邮箱接收到数据后,触发邮箱中断,然后根据CANRMP寄存器的标志位确定是哪个邮箱触发了中断,对该邮箱进行接收处理。奇怪的是,程序刚开始运行一直正常,但是运行到一个小时左右后,出现故障。通过反复的测试,总结出故障的现象为,当我向dsp中发送数据时,能够确定邮箱接收到了数据,并且触发了邮箱中断,但是该邮箱的CANRMP标志位并没有被置位,因此dsp程序中无法判别哪个邮箱触发了中断,而且发送邮箱能够正常发送数据。经过测试,确定错误计数寄存器CANTEC/CANREC均正常。
以上为我所遇到的问题,不知道哪位朋友能够解惑,说一说解决方法或者可能的原因,谢谢!
贴一段你的程序看看.
还有没有别的中断?
3个数据的发送间隔是多少?
CAN中断中还有其他的程序执行没有?
对CANRMP的操作有没有使用影子寄存器.有可能错误清除CMP.
interrupt void Ecan0ISR(void)
{
Can_receivecounter++;
DINT;
if(ECanaRegs.CANRMP.all&0x00040000)
{CANSXSRX18();
receiveflag18=1;
}
if(ECanaRegs.CANRMP.all&0x00080000)
{CANSXSRX19();
receiveflag19=1;
}
if(ECanaRegs.CANRMP.all&0x20000000)
{
CANSXSRX29();
receiveflag29=1;
}
PieCtrlRegs.PIEACK.bit.ACK9 = 1;
EINT;
}
void CANSXSRX29(void)
{
ECanaRegs.CANRMP.all = (ECanaRegs.CANRMP.all|0x20000000);
a=ECanaMboxes.MBOX29.MDL.byte.BYTE0;
b=ECanaMboxes.MBOX29.MDL.byte.BYTE1;
}
上面是中断程序和接收邮箱程序
interrupt void Ecan0ISR(void)
{
Can_receivecounter++;
DINT;
if(ECanaRegs.CANRMP.all&0x00040000)
{CANSXSRX18();
receiveflag18=1;
}
if(ECanaRegs.CANRMP.all&0x00080000)
{CANSXSRX19();
receiveflag19=1;
}
if(ECanaRegs.CANRMP.all&0x20000000)
{CANSXSRX29();
receiveflag29=1;
}
PieCtrlRegs.PIEACK.bit.ACK9 = 1;
EINT;
}
void CANSXSRX29(void)
{
ECanaRegs.CANRMP.all = (ECanaRegs.CANRMP.all|0x20000000);
a=ECanaMboxes.MBOX29.MDL.byte.BYTE0;
b=ECanaMboxes.MBOX29.MDL.byte.BYTE1;
}
上面是中断程序和接收邮箱程序
建议改为:
interrupt void Ecan0ISR(void)
{
struct ECAN_REGS ECanaShadow;//注意引用CAN的头文件
Can_receivecounter++;
//DINT; //删除这个,其他的中断中也不要写这个.进中断之后会自动禁止,除非你想使能别人打断,这里可以写EINT.
ECanaShadow.CANRMP.all = 0;
ECanaShadow.CANRMP.all = ECanaRegs.CANRMP.all;
//if(ECanaRegs.CANRMP.all&0x00040000)
if((ECanaShadow.CANRMP.all & 0x00040000) ==0x00040000)
{CANSXSRX18();
receiveflag18=1;
}
//if(ECanaRegs.CANRMP.all&0x00080000)
if((ECanaShadow.CANRMP.all & 0x00080000) ==0x00080000 )
{CANSXSRX19();
receiveflag19=1;
}
//if(ECanaRegs.CANRMP.all&0x20000000)
if((ECanaShadow.CANRMP.all & 0x20000000) ==0x20000000)
{CANSXSRX29();
receiveflag29=1;
}
//PieCtrlRegs.PIEACK.bit.ACK9 = 1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
//EINT;
}
void CANSXSRX29(void)
{
ECanaRegs.CANRMP.all = 0x20000000;//其他邮箱按设计赋值,只清除对应的位
//ECanaRegs.CANRMP.all = (ECanaRegs.CANRMP.all|0x20000000);//这样先读后写,如果收到两帧,则又可能清除其他的位.
//ECanaRegs.CANRMP.all = RMP_TEMP;//也可以带参
a=ECanaMboxes.MBOX29.MDL.byte.BYTE0;
b=ECanaMboxes.MBOX29.MDL.byte.BYTE1;
}
你再试试.
你好,我按照你说的试了一下,现象还是和原来一样。
程序刚开始正常,运行一个小时后,通过观测Can_receivecounter++的值,这个值还能递增,说明程序能够进入邮箱中断;但是观测ECanaRegs.CANRMP.bit.RMP29的值,这个值一直保持为0,而且提取ECanaMboxes.MBOX29.MDL.byte.BYTE0和ECanaMboxes.MBOX29.MDL.byte.BYTE1的数据,也是变化的,说明邮箱29能够接收到数据,并且能够触发邮箱中断,但是CANRMP却没有被置位。
不知道是什么原因?
你的意思是运行一段时间后,程序中a,b的值不变化了吗?
由于进入中断后,RMP29很快会被清0 .你是在什么地方打断点看的?
你可以在运行一段时间后,在中断中打一个断点,发送一组数据看看, 看进入中断后,RMP的那一位置位了?
对对,运行一个小时左右,a、b的值就不变了。RMP位一直保持为0,但是能确定接收邮箱29肯定接收到了数据,并且中断也进入了。
我是用其他邮箱查询发送的,将邮箱29中的数据和RMP位赋给邮箱15,用邮箱15将他们发送给上位机观察的。我试验了好多次,基本都是在一个小时左右出现故障。
void Ecan_init()
{
/*-------------------------------------------------------------------------*/
// configure CAN pins using GPIO regs here
EALLOW;
GpioMuxRegs.GPFMUX.bit.CANTXA_GPIOF6 = 1;
GpioMuxRegs.GPFMUX.bit.CANRXA_GPIOF7 = 1;
EDIS;
/*-------------------------------------------------------------------------*/
// Configure the eCAN RX and TX pins for eCAN transmissions
EALLOW;
ECanaRegs.CANTIOC.bit.TXFUNC = 1;
ECanaRegs.CANRIOC.bit.RXFUNC = 1;
EDIS;
/*-------------------------------------------------------------------------*/
// eCAN mode (reqd to access 32 mailboxes)
EALLOW;
ECanaRegs.CANMC.bit.SCB = 1; // eCAN mode
EDIS;
ECanaRegs.CANME.all = 0x00000000;
/*-------------------------------------------------------------------------*/
/* Clear all TAn bits */
ECanaRegs.CANTA.all = 0xFFFFFFFF;
/*-------------------------------------------------------------------------*/
/* Clear all RMPn bits(write 1 to clear) */
ECanaRegs.CANRMP.all = 0xFFFFFFFF;
/*-------------------------------------------------------------------------*/
/* Clear all interrupt flag bits */
ECanaRegs.CANGIF0.all = 0xFFFFFFFF;
ECanaRegs.CANGIF1.all = 0xFFFFFFFF;
/*-------------------------------------------------------------------------*/
/* disbale global interrupt and mailbox interrupt */
EALLOW;
ECanaRegs.CANGIM.all = 0x00000000;
ECanaRegs.CANMIM.all = 0x00000000;
EDIS;
/*-------------------------------------------------------------------------*/
/* Configure bit timing parameters */
EALLOW;
ECanaRegs.CANMC.bit.CCR = 1; // Set CCR = 1
EDIS;
while(ECanaRegs.CANES.bit.CCE != 1 ) {} // Wait for CCE bit to be set..
/*-------------------------------------------------------------------------*/
EALLOW;
ECanaRegs.CANBTC.bit.BRPREG = 19; // 150MHz/20=7.5MHz
ECanaRegs.CANBTC.bit.TSEG1REG = 10;
ECanaRegs.CANBTC.bit.TSEG2REG = 2; //Bode rate:7.5M/(1+11+3)=500kb
EDIS;
/*-------------------------------------------------------------------------*/
EALLOW;
ECanaRegs.CANMC.bit.CCR = 0; // Set CCR = 0
EDIS;
while(ECanaRegs.CANES.bit.CCE != 0 ) {} // Wait for CCE bit to be cleared..
/*-------------------------------------------------------------------------*/
/* Disable all Mailboxes */
ECanaRegs.CANME.all = 0x00000000; // Required before writing the MSGIDs
/*-------------------------------------------------------------------------*/
EALLOW;
ECanaRegs.CANMC.bit.STM = 0; // Configure CAN for normal mode
ECanaRegs.CANMC.bit.DBO = 1;
ECanaRegs.CANMC.bit.ABO = 1;
ECanaRegs.CANMC.bit.PDR = 0;
ECanaRegs.CANMC.bit.WUBA = 0;
EDIS;
ECanaRegs.CANMC.bit.SRES = 0;
ECanaRegs.CANMC.bit.CDR = 0;
ECanaRegs.CANMC.bit.MBNR = 0;
/*-------------------------------------------------------------------------*/
EcanMboxConfig();
/*-------------------------------------------------------------------------*/
EALLOW; // Enable EALLOW
ECanaRegs.CANMIL.all = ECanaRegs.CANMIL.all&0x00000000;//在中断0产生中断
ECanaRegs.CANMIM.all = ECanaRegs.CANMIM.all|0x200C0000;
ECanaRegs.CANGIM.all = ECanaRegs.CANGIM.all|0x00000001;
EDIS; // Disable EALLOW
}
上面是邮箱的配置,麻烦帮忙看一下
贴一下这个EcanMboxConfig();
如果开始可以正常运行,后面邮箱数据可以更新, 我认为CAN这部分没有问题, 你整个程序是否还有其他的部分,你试试屏蔽其他的部分,但是测试CAN 看一下.
你可以运行一段时间后,打一个断点看,不建议再用其他邮箱进行发送.多利用watch窗口看看.