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.
大佬们,我想问一下,做CAN通信,我用0号邮箱做发送邮箱,16号邮箱作为接收邮箱。但我在十六号邮箱中写了个中断。就是使用CAN调试软件,运行程序,可以看到CAN调试软件中0号邮箱发送的数据。但是我在CAN调试软件上给16号邮箱发送数据程序就进入不到中断了。但是16号邮箱里面的数据变化了。而且从CAN调试软件上0号邮箱发送了一帧01,23,45,67,89,ab,cd,ef。这一帧不知道是怎么产生的。但是我如果在主函数将发送的那部分程序注释掉,在那个接收中断打断点,从CAN调试软件上发送数据是可以直接进入到中断里面的。
主程序: #include "eCAN.h" //定义全局变量 Uint32 MessageSendCount = 0; Uint32 MessageReceiveCount = 0; Uint32 Rec_l; Uint32 Rec_h; Uint16 i = 0,j = 0,k = 0; Uchar senddata[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07}; __interrupt void ECAN0INTB_iSR(void); void main(void) { InitSysCtrl(); DINT; IER = 0x0000; IFR = 0x0000; InitPieCtrl(); InitPieVectTable(); EALLOW; // 写保护 PieVectTable.ECAN0INTB = &ECAN0INTB_iSR; //设置ECAN0INTB中断服务程序的入口地址为ECAN0INTB_iSR EDIS; // 禁用写保护 InitECan(); //使能PIE中断 PieCtrlRegs.PIEIER9.bit.INTx7 = 1; //使能CPU中断 IER |= M_INT9; EINT; //开全局中断 ERTM; //开实时中断 for(;;) { //只使用接收的话,52行-65行注释掉即可 // for(;k<20;) // { ECanbRegs.CANTRS.all = 0x00000001; //1设置TRSn,发送该邮箱中的消息 while(ECanbRegs.CANTA.all == 0){} //等待TA被置位,邮箱消息发送成功则置位 ECanbRegs.CANTA.all = 0x00000001; //如果邮箱n的消息发送成功,则设置该寄存器的第n位 MessageSendCount++; //设断点,观察 ECanbMboxes.MBOX0.MDL.all = senddata[i]; ECanbMboxes.MBOX0.MDH.all = senddata[i + 1]; i = i + 2; if(i > 7) i = 0; // k++; // } } } __interrupt void ECAN0INTB_iSR(void) //eCAN_B { if(ECanbRegs.CANRMP.all != 0) //判断是否有数据 { while(ECanbRegs.CANRMP.all != 0x00010000); ECanbRegs.CANRMP.all = 0x00010000; //复位RMP标志,同时也复位中断标志 Rec_l = ECanbMboxes.MBOX16.MDL.all; //接收到的数据在接收邮箱Mbox16 Rec_h = ECanbMboxes.MBOX16.MDH.all; PieCtrlRegs.PIEACK.bit.ACK9 = 1; EINT; } } ecan.c void InitECan(void) { struct ECAN_REGS ECanbShadow; EALLOW; //配置GPIO引脚工作在eCAN功能 GpioCtrlRegs.GPAPUD.bit.GPIO16 = 1; //禁止上拉GPIO16(CANTXB) GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0; //使能上拉GPIO17(CANRXB) GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3; GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 2; //配置GPIO16为CANTXB GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 2; //配置GPIO17为CANRXB //配置eCAN的RX&TX分别为eCAN的接收和发送引脚 ECanbShadow.CANTIOC.all = ECanbRegs.CANTIOC.all; ECanbShadow.CANTIOC.bit.TXFUNC = 1; ECanbRegs.CANTIOC.all = ECanbShadow.CANTIOC.all; ECanbShadow.CANRIOC.all = ECanbRegs.CANRIOC.all; ECanbShadow.CANRIOC.bit.RXFUNC = 1; ECanbRegs.CANRIOC.all = ECanbShadow.CANRIOC.all; ECanbShadow.CANMC.all = ECanbRegs.CANMC.all; ECanbShadow.CANMC.bit.STM = 0; //工作在正常模式 ECanbShadow.CANMC.bit.SCB = 1; ECanbRegs.CANMC.all = ECanbShadow.CANMC.all; //初始化所有主设备控制区域为0,MCF所有的位都初始化为0 ECanbMboxes.MBOX0.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX1.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX2.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX3.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX4.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX5.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX6.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX7.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX8.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX9.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX10.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX11.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX12.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX13.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX14.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX15.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX16.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX17.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX18.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX19.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX20.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX21.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX22.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX23.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX24.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX25.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX26.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX27.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX28.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX29.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX30.MSGCTRL.all = 0x00000000; ECanbMboxes.MBOX31.MSGCTRL.all = 0x00000000; ECanbShadow.CANTA.all = ECanbRegs.CANTA.all; ECanbShadow.CANTA.all = 0xFFFFFFFF; ECanbRegs.CANTA.all = ECanbShadow.CANTA.all; ECanbShadow.CANRMP.all = ECanbRegs.CANRMP.all; ECanbShadow.CANRMP.all = 0xFFFFFFFF; ECanbRegs.CANRMP.all = ECanbShadow.CANRMP.all; ECanbShadow.CANGIF0.all = ECanbRegs.CANGIF0.all; ECanbShadow.CANGIF0.all = 0xFFFFFFFF; ECanbRegs.CANGIF0.all = ECanbShadow.CANGIF0.all; ECanbShadow.CANGIF1.all = ECanbRegs.CANGIF1.all; ECanbShadow.CANGIF1.all = 0xFFFFFFFF; ECanbRegs.CANGIF1.all = ECanbShadow.CANGIF1.all; /*为eCAN配置位时间参数*/ ECanbShadow.CANMC.all = ECanbRegs.CANMC.all; ECanbShadow.CANMC.bit.CCR = 1; //设置CCR=1 ECanbRegs.CANMC.all = ECanbShadow.CANMC.all; // ECanbShadow.CANES.all = ECanbRegs.CANES.all; ////////////////////// do {ECanbShadow.CANES.all = ECanbRegs.CANES.all; }while(ECanbShadow.CANES.bit.CCE != 1); //等待CCE位被清除 ECanbShadow.CANBTC.all = ECanbRegs.CANBTC.all; ECanbShadow.CANBTC.bit.BRPREG = 9; //数据传输速率 //150/10 = 15 ECanbShadow.CANBTC.bit.TSEG2REG = 2; ECanbShadow.CANBTC.bit.TSEG1REG = 10; ECanbRegs.CANBTC.all = ECanbShadow.CANBTC.all; ECanbShadow.CANMC.all = ECanbRegs.CANMC.all; ECanbShadow.CANMC.bit.CCR = 0; //设置CCR=0 ECanbRegs.CANMC.all = ECanbShadow.CANMC.all; do {ECanbShadow.CANES.all = ECanbRegs.CANES.all; }while(ECanbShadow.CANES.bit.CCE != 0); //等待CCE位被置位 ECanbShadow.CANME.all = ECanbRegs.CANME.all; ECanbShadow.CANME.all = 0; ECanbRegs.CANME.all = ECanbShadow.CANME.all; //接收邮箱的ID ECanbMboxes.MBOX0.MSGID.all = 0x80C80000; //扩展帧 ///////////// ECanbMboxes.MBOX16.MSGID.all = 0x80C20000; //扩展帧 //邮箱0为TX,16为RX ECanbShadow.CANMD.all = ECanbRegs.CANMD.all; ECanbShadow.CANMD.bit.MD0 = 0; //邮箱0,发送 ///////////// ECanbShadow.CANMD.bit.MD16 = 1; //邮箱16,接收 ECanbRegs.CANMD.all = ECanbShadow.CANMD.all; //数据长度为8个byte ECanbMboxes.MBOX0.MSGCTRL.bit.DLC = 8; //////////// ECanbMboxes.MBOX16.MSGCTRL.bit.DLC = 8; //设置发送优先级 2009.3.15 Add ECanbMboxes.MBOX0.MSGCTRL.bit.TPL = 0; //////////// ECanbMboxes.MBOX16.MSGCTRL.bit.TPL = 0; //没有远方应答帧被请求 ECanbMboxes.MBOX0.MSGCTRL.bit.RTR = 0; //////////////看手册弄懂 ECanbMboxes.MBOX16.MSGCTRL.bit.RTR = 0; //向邮箱RAM区写数据 ECanbMboxes.MBOX0.MDL.all = 0x00000000; //0x01234567; //////////////看手册弄懂 ECanbMboxes.MBOX0.MDH.all = 0x00000000; //0x89ABCDEF; //邮箱使能Mailbox0 ECanbShadow.CANME.all = ECanbRegs.CANME.all; ECanbShadow.CANME.bit.ME0 = 1; ////////////// ECanbShadow.CANME.bit.ME16 = 1; ECanbRegs.CANME.all = ECanbShadow.CANME.all; ECanbRegs.CANMIM.all = 0xFFFFFFFF; //邮箱中断使能(只需要测试发送的时候,注释掉该句即可) //邮箱中断将产生在ECAN0INT ECanbRegs.CANMIL.all = 0; ECanbRegs.CANGIF0.all = 0xFFFFFFFF; //ECAN0INT中断请求线被使能 ECanbRegs.CANGIM.bit.I0EN = 1; EDIS; }
这个软件叫CANTest。我现在就是0号邮箱会正常发送我的数组。但是我给DSP发送CAN数据,进入不到接收中断。但是我如果在主函数把那个0号邮箱发送的那几句注释掉,我给DSP发送CAN数据,就能进入到中断,数值也是正确的,我不知道是为啥。
你好,大佬。我发现ECAN在做发送数据的时候,不单单要配置一个发送邮箱。还需要配置一个接收邮箱。我的这个代码是通过一个只有发送功能的代码改的。0号邮箱发送,16号邮箱接收。在编写接收代码的时候,我依旧用的这两个邮箱。是不是应该在配置一组发送和接收邮箱。这样的话应该就不会起冲突。我想问题是不是出在了这里?
我发现ECAN在做发送数据的时候,不单单要配置一个发送邮箱。还需要配置一个接收邮箱
在正常应用程序中情况并非如此。我认为您正在自检模式下使用 CAN 模块。
是不是应该在配置一组发送和接收邮箱。
如果需要接收邮箱来接收发送的数据,则需要手动配置。
我想问题是不是出在了这里?
不,没有问题。在自检模式下,如果要产生接收中断,需要将接收邮箱配置为与发送邮箱相同的MSGID。一旦执行此操作,当接收到消息时,将生成中断。
大佬,我发现了个问题,我如果在中断加上if(ECanbRegs.CANRMP.all != 0)这条语句。我的16号邮箱能接收到我用CANTest发送的报文,ID:00C20000发送的。在调试窗口也能看到16号邮箱里面数据变化是正确的。但是为啥设置断点,程序跳不到断点那里?下面是我的调试图。我如果将中断的这条语句if(ECanbRegs.CANRMP.all != 0)删掉,我向00C20000发送报文是可以调到中断的那个断点处的。但是我的0号邮箱ID:00C80000就无法发送报文。不知道原因是什么,希望大佬能给解惑。