今天在配置CAN的接受邮箱时,出现中断发生后不进设置的中断函数的问题。代码如下:
void CAN_Init(void)
{
// eCAN control registers require read/write access using 32-bits. Thus we
// will create a set of shadow registers for this example. These shadow
// registers will be used to make sure the access is 32-bits and not 16.
struct ECAN_REGS ECanbShadow; //就是为了临时保存数据而定义的
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F2806x_SysCtrl.c file.
// InitSysCtrl();
// Step 2. Initalize GPIO:
// This example function is found in the F2806x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio(); // Skipped for this example
// For this example, configure CAN pins using GPIO regs here
// This function is found in F2806x_ECan.c
InitECanGpio(); //其实就是配置30和31号引脚
// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
// DINT;
// Initialize PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the F2806x_PieCtrl.c file.
// InitPieCtrl();
// Disable CPU interrupts and clear all CPU interrupt flags:
// IER = 0x0000;
// IFR = 0x0000;
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in F2806x_DefaultIsr.c.
// This function is found in F2806x_PieVect.c.
// InitPieVectTable();
EALLOW;
PieVectTable.ECAN1INTB = &Ecan0ISR; //R-CAN1 接收后中断函数
EDIS;
// Initialize eCAN-B module sending data config
//InitECanb();
ConfigCanBSending();
//receiving configuration
CANB_RX_Config(CAN_XCP_RX_ID);
//configure the interrupt
PieCtrlRegs.PIECTRL.bit.ENPIE = 1;
PieCtrlRegs.PIEIER9.bit.INTx8 = 1; //CANB的中断1
IER |= M_INT9;
EINT;
// Enable Global interrupt INTM
ERTM;
}
最后发现问题出在配置中断进入函数的代码时,没有提前把全局中断使能关掉导致的,也就是说加上DINT就好了。
DINT;
EALLOW;
PieVectTable.ECAN1INTB = &Ecan0ISR; //R-CAN1 接收后中断函数
EDIS;
EINT;
更新后的代码如下:
void CAN_Init(void)
{
// eCAN control registers require read/write access using 32-bits. Thus we
// will create a set of shadow registers for this example. These shadow
// registers will be used to make sure the access is 32-bits and not 16.
struct ECAN_REGS ECanbShadow; //就是为了临时保存数据而定义的
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F2806x_SysCtrl.c file.
// InitSysCtrl();
// Step 2. Initalize GPIO:
// This example function is found in the F2806x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio(); // Skipped for this example
// For this example, configure CAN pins using GPIO regs here
// This function is found in F2806x_ECan.c
InitECanGpio(); //其实就是配置30和31号引脚
// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
DINT;
// Initialize PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the F2806x_PieCtrl.c file.
// InitPieCtrl();
// Disable CPU interrupts and clear all CPU interrupt flags:
IER = 0x0000;
IFR = 0x0000;
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in F2806x_DefaultIsr.c.
// This function is found in F2806x_PieVect.c.
// InitPieVectTable();
EALLOW;
PieVectTable.ECAN1INTB = &Ecan0ISR; //R-CAN1 接收后中断函数
EDIS;
// Initialize eCAN-B module sending data config
//InitECanb();
ConfigCanBSending();
//receiving configuration
CANB_RX_Config(CAN_XCP_RX_ID);
//configure the interrupt
PieCtrlRegs.PIECTRL.bit.ENPIE = 1;
PieCtrlRegs.PIEIER9.bit.INTx8 = 1; //CANB的中断1
IER |= M_INT9;
EINT;
// Enable Global interrupt INTM
ERTM;
}
虽然就是短短几行代码,却话费了本人一个上午的时间去找原因。根本原因还是对寄存器的原理以及每句话所起到的作用没有彻底的理解。希望本文能帮助到后来者,少走弯路。