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.
您好!
我在 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; } //否则,发生意外导致中断的情况。 这应该是 //永远不会发生。 其他 { //此处可以处理伪中断 。} }
我能够解决这样一个事实、即它没有调用 CanIntHandler 函数(我曾在 commentaru 中使用过 CAN_INT_Status、该函数曾用于进入) 现在、我遇到了状态始终等于0x8000的问题、但我不知道为什么我认为它、因为我在设置电子邮件箱时出错、但我没有找到任何这样的示例。 此外、即使消息被处理、寄存器 CAN_INT 仍不会更新?????