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、该问题是否有相应的解决方式?
