请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
您好!
我在 Cortex M3上遇到了 CanInntHandler 的一些问题、我将其设置为在接收(CANRx)发出中断时调用处理程序、但 它从未调用过。 我可以在 TE 寄存器值上看到中断被创建、消息被看到和处理会导致寄存器 CAN_ES 更新位 Rxok、IF2CMD 寄存器执行 ClrIntPnd
有 CanInit 和 CanIntHandler 的 mycode
/*********
初始化硬件以接收 CAN 消息并启动
CANopen 堆栈的计时器。
输入比特率 如果
成功,以千位输出1为单位的比特率
/
unsigned char canInit (unsigned int bitrate)
{
//初始化 CAN 控制器
int ulBase = CAN0_BASE;
int iMsg;
//检查参数。
ASSERT (CANBaseValid (ulBase));
//将 CAN 控制器置于初始化状态,与之前的状态无关。 这种情况
//将控制器置于空闲状态,并允许消息对象 RAM 处于空闲状态
//已编程。
HWREG (ulBase + CAN_O_CTL)= CAN_CTL_init;
HWREG (ulBase + CAN_O_CTL)= CAN_CTL_SWR;
//等待忙位清零
while (HWREG (ulBase + CAN_O_IF1_CMD)和 CAN_IF1_CMD_BUSY)
{
}
//清除仲裁寄存器中的报文值位。 这表示
//消息无效,是一个“安全”条件,可以离开消息
//对象。 相同的 ARB reg 用于对所有报文对象进行编程。
/* HWREGH (ulBase + CAN_O_IF1_MSK)= 0;
HWREGH (ulBase + CAN_O_IF1_CMD)=(无符号字符) 0xf8;
HWREG (ulBase + CAN_O_IF1_ARB)=(int) 0x8000000 |(int) 0x00000000 |(int) 0x20000000 |(int)((int)(((int) 0和(int) 0x000007FF)<<(int) 18);
HWREG (ulBase + CAN_O_IF1_MCTL)= 0x00001080 |(int) 0x00000000 |(int) 0x00000000 |(int) 0x00000000 |(int) 8;
HWREGH (ulBase + CAN_O_IF2_MSK)= 0;
HWREGH (ulBase + CAN_O_IF2_CMD)=(无符号字符) 0xf8;
HWREG (ulBase + CAN_O_IF2_ARB)=(int) 0x8000000 |(int) 0x00000000 |(int) 0x00000000 |(int)((int)(((int) 0 &(int) 0x000007FF)<<(int) 18);
HWREG (ulBase + CAN_O_IF2_MCTL)= 0x00001080 |(int) 0x00000400 |(int) 0x00000000 |(int) 8;
//循环以编程全部32个报文对象
for (iMsg = 1;iMsg <= 16;iMsg++)
{
//等待忙位清零
while (HWREG (ulBase + CAN_O_IF1_CMD)和 CAN_IF1_CMD_BUSY)
{
}
//开始对消息对象进行编程
HWREGH (ulBase + CAN_O_IF1_CMD)= iMsg;
}
for (iMsg = 16;iMsg <= 32;iMsg++)
{
//等待 BUSY 位清零
while (HWREG (ulBase + CAN_O_IF2_CMD)& CAN_IF2_CMD_BUSY)
{
}
//开始对消息对象
HWREGH (ulBase + CAN_O_IF2_CMD)进行编程;
}
* iMsg = iMsg
HWREGH (ulBase + CAN_O_IF1_CMD + 2)=(CAN_IF1_CMD_WR_RD | CAN_IF1_CMD_ARB |
CAN_IF1_CMD_CONTROL)>> 16;
HWREG (ulBase + CAN_O_IF1_ARB)= 0;
HWREG (ulBase + CAN_O_IF1_MCTL)= 0x1088;
HWREGH (ulBase + CAN_O_IF2_CMD + 2)=(CAN_IF2_CMD_WR_RD | CAN_IF2_CMD_ARB |
CAN_IF1_CMD_CONTROL)>> 16;
HWREG (ulBase + CAN_O_IF2_ARB)= 0;
HWREG (ulBase + CAN_O_IF2_MCTL)= 0x1488;
//循环以编程全部32个报文对象
for (iMsg = 1;iMsg <= 16;iMsg++)
{
//等待忙位清零
while (HWREG (ulBase + CAN_O_IF1_CMD)和 CAN_IF1_CMD_BUSY)
{
}
//开始对消息对象进行编程
HWREGH (ulBase + CAN_O_IF1_CMD)= iMsg;
}
for (iMsg = 16;iMsg <= 32;iMsg++)
{
//等待 BUSY 位清零
while (HWREG (ulBase + CAN_O_IF2_CMD)& CAN_IF2_CMD_BUSY)
{
}
//开始对消息对象进行编程
HWREGH (ulBase + CAN_O_IF2_CMD)= iMsg;
}
//确保更新的中断和新数据标志
//消息对象。
HWREGH (ulBase + CAN_O_IF1_CMD + 2)=(CAN_IF1_CMD_CLRINTPND)>> 16;
HWREGH (ulBase + CAN_O_IF2_CMD + 2)=(CAN_IF2_CMD_CLRINTPND)>> 16;
//循环以编程全部32个报文对象
for (iMsg = 1;iMsg <= 16;iMsg++)
{
//等待忙位清零
while (HWREG (ulBase + CAN_O_IF1_CMD)和 CAN_IF1_CMD_BUSY)
{
}
//开始对消息对象进行编程
HWREGH (ulBase + CAN_O_IF1_CMD)= iMsg;
}
for (iMsg = 16;iMsg <= 32;iMsg++)
{
//等待 BUSY 位清零
while (HWREG (ulBase + CAN_O_IF2_CMD)& CAN_IF2_CMD_BUSY)
{
}
//开始对消息对象进行编程
HWREGH (ulBase + CAN_O_IF2_CMD)= iMsg;
}
//等待忙位清零
while (HWREG (ulBase + CAN_O_IF1_CMD)和 CAN_IF1_CMD_BUSY)
{
}
HWREGH (ulBase + CAN_O_IF1_CMD)= 0x87;
//等待 BUSY 位清零
while (HWREG (ulBase + CAN_O_IF2_CMD)& CAN_IF2_CMD_BUSY)
{
}
HWREGH (ulBase + CAN_O_IF2_CMD)= 0x17;
//确认任何挂起状态中断。
HWREG (ulBase + CAN_O_ES);
//设置可以根据 M3/主子系统时钟计时
CANClkSourceSelect (CAN0_BASE、CAN_CLK_M3);
//设置 CAN 总线的比特率。 此函数设置 CAN
针对标称配置的//总线时序。 您可以实现更多控制
//使用函数 CANBitTimingSet()代替 CAN 总线时序
//如果需要。
//在此示例中、CAN 总线设置为500kHz。 在以下函数中、
//对 SysCtlClockGet ()的调用用于确定该时钟速率
//用于为 CAN 外设计时。 可将其替换为
//固定值如果您知道系统时钟的值,则节省额外的值
//函数调用。 对于某些器件、CAN 外设采用固定计时
// 8MHz,无论在哪种情况下调用的系统时钟如何
// SysCtlClockGet ()应替换为80000。 请查阅数据
//表以了解有关 CAN 外设计时的更多信息。
CANBitRateSet (CAN0_BASE、SysCtlClockGet (SYSTEM_CLOCK_SPEED)、比特率);
//在 CAN 外设上启用中断。 此示例使用静态
//分配中断处理程序,表示处理程序的名称
//位于启动代码的矢量表中。 如果您想使用动态的
//分配矢量表,然后还必须调用 CANIntRegister()
//此处。
// CANIntRegister (CAN0_BASE、CANIntHandler);// if using dynamic vectors
CANIntEnable (CAN0_BASE、CAN_INT_MASTER /*| CAN_INT_ERROR | CAN_INT_STATUS*/);
//在 RAM 矢量表中注册中断处理程序
IntRegister (INT_CAN0INT0、CANIntHandler);
IntRegister (INT_CAN0INT1、CANIntHandler);
//在处理器(NVIC)上启用 CAN 中断。
IntEnable (INT_CAN0INT0);
IntEnable (INT_CAN0INT1);
IntMasterEnable();
//禁用测试模式并选择外部环回
HWREG (CAN0_BASE + CAN_O_CTL)|=(0 | CAN_CTL_IE0 | CAN_CTL_IE1);//禁用测试模式
HWREG (CAN0_BASE + CAN_O_TEST)= 0;//禁用外部环回模式
//启用 CAN 以进行操作。
CANEnable (CAN0_BASE);
返回1;
}
void CANIntHandler (void) { unsigned long ulStatus; 消息 m =消息初始化程序;//包含 CAN 消息; //读取 CAN 中断状态以查找中断原因 ulStatus = CANIntStatus (CAN0_BASE、CAN_INT_STS_CAUST); x=ulStatus; //如果原因是控制器状态中断,则获取状态 if (ulStatus = CAN_INT_INT0ID_STATUS) { //读取控制器状态。 这将返回状态字段 //可以指示各种错误的错误位。 错误处理 //本示例中不是为了简单起见。 请参阅 // API 文档,了解有关错误状态位的详细信息。 //读取此状态的操作将清除中断。 如果 // CAN 外设未与其它 CAN 器件连接到 CAN 总线 //存在,则会发生错误,并在中指示 //控制器状态。 ulStatus = CANStatusGet (CAN0_BASE、CAN_STS_CONTROL); //设置一个标志来指示可能发生的某些错误。 G_bErrFlag = 1; } //检查原因是否是我们正在使用的消息对象1 //发送消息。 否则(((ulStatus > 0)&&(ulStatus <= 32)) { //到达这一点意味着 TX 中断发生在上 //消息对象1、消息 TX 完成。 清除 //消息目标中断。 CANIntClear (CAN0_BASE、1); //递增计数器以跟踪已有多少消息 //已发送。 在实际应用中、这可用于将标志设置为 //指示何时发送消息。 G_ulMsgCount++; if (canPreReceive (ulStatus、&m))(可预接收器(ulStatus、&m))) { canreceive(&M); } //由于消息已发送,请清除所有错误标志。 G_bErrFlag = 0; } //否则,发生意外导致中断的情况。 这应该是 //永远不会发生。 其他 { //此处可以处理伪中断 。} }