void InitECana(void) { Uint16 i; // // Create a shadow register structure for the CAN control registers. This // is needed, since only 32-bit access is allowed to these registers. // 16-bit access to these registers could potentially corrupt the register // contents or return false data. This is especially true while writing // to/reading from a bit (or group of bits) among bits 16 - 31 // struct ECAN_REGS ECanaShadow; EALLOW; // EALLOW enables access to protected bits SysCtrlRegs.PCLKCR0.bit.ECANAENCLK=1; // // Configure eCAN RX and TX pins for CAN operation using eCAN regs // 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; // // Configure eCAN for HECC mode - (reqd to access mailboxes 16 thru 31) // HECC mode also enables time-stamping feature // ECanaShadow.CANMC.all = ECanaRegs.CANMC.all; ECanaShadow.CANMC.bit.SCB = 1; ECanaRegs.CANMC.all = ECanaShadow.CANMC.all; // // Initialize all bits of 'Master Control Field' to zero // Some bits of MSGCTRL register come up in an unknown state. For proper // operation, all bits (including reserved bits) of MSGCTRL must be // initialized to zero // for(i=0;i<32;i++) { ECanaMboxes.MBOXn[i].MSGCTRL.all = 0x00000000; } // // TAn, RMPn, GIFn bits are all zero upon reset and are cleared again // as a matter of precaution. // 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; ECanaShadow.CANES.all = ECanaRegs.CANES.all; do { ECanaShadow.CANES.all = ECanaRegs.CANES.all; } while(ECanaShadow.CANES.bit.CCE != 1 ); // Wait for CCE bit to be set ECanaShadow.CANBTC.all = 0; ECanaShadow.CANBTC.bit.BRPREG = 15; // 60/15+1 = 3.75Mhz ECanaShadow.CANBTC.bit.SJWREG = 2; // ECanaShadow.CANBTC.bit.TSEG2REG = 2; // 3.75/(10+2+3) = 250Khz,采样率80% ECanaShadow.CANBTC.bit.TSEG1REG = 10; ECanaShadow.CANBTC.bit.SAM = 1; ECanaRegs.CANBTC.all = ECanaShadow.CANBTC.all; ECanaShadow.CANMC.all = ECanaRegs.CANMC.all; ECanaShadow.CANMC.bit.CCR = 0 ; // Set CCR = 0 ECanaShadow.CANMC.bit.PDR = 0 ; // 正常模式,不允许低功耗 ECanaShadow.CANMC.bit.DBO = 1 ; // 8字节数据顺序 1:byte1,byte0,byte3,byte2,byte5,byte4,byte7,byte6 // 0:byte2,byte3,byte0,byte1,byte6,byte7,byte4,byte5 ECanaShadow.CANMC.bit.WUBA =0 ; // 0:向PDR写0,离开低功耗,1:检测总线状态离开低功耗 ECanaShadow.CANMC.bit.CDR = 0 ; // 改变数据域请求 ECanaShadow.CANMC.bit.ABO = 1 ; // 自动连接总线位 ECanaShadow.CANMC.bit.STM = 0 ; // 1:环回自测模式,0:正常模式 ECanaShadow.CANMC.bit.SRES = 0; // 1:复位,0:无效 ECanaShadow.CANMC.bit.MBNR = 0; // Mailbox number ECanaRegs.CANMC.all = ECanaShadow.CANMC.all; for(i=0;i<32;i++) { ECanaMboxes.MBOXn[i].MSGCTRL.bit.TPL = 32-i; //数据越大,邮箱优先级越高,优先发送 ECanaMboxes.MBOXn[i].MSGCTRL.bit.RTR = 0; // 远程发送请求,0:没有远程帧 ECanaMboxes.MBOXn[i].MSGCTRL.bit.DLC = 8; // 全部按8个字节长度, } do { ECanaShadow.CANES.all = ECanaRegs.CANES.all; } while(ECanaShadow.CANES.bit.CCE != 0 );// Wait for CCE bit to be cleared // // Disable all Mailboxes // ECanaRegs.CANME.all = 0; // Required before writing the MSGIDs EDIS; }
现象:程序在运行时会卡死在上述代码的69行的while(ECanaShadow.CANES.bit.CCE != 1 );等待该标志位置位,程序将不会往下执行,重新刷写程序并在仿真状态能够通过while循环,并正常运行。
代码结构:在此正式程序之前会有bootloader程序(自己创建的),在bootloader程序中已经执行过can初始化,在APP程序再次执行中会卡死在69行位置。
问题:1、can初始化是否只能执行一次?
2、该问题是否有相应的解决方式?