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.

[参考译文] TMS320F28388D:CAN 中断

Guru**** 2331900 points
Other Parts Discussed in Thread: TMS320F28388D, SYSCONFIG
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1508507/tms320f28388d-can-interrupt

器件型号:TMS320F28388D
主题: SysConfig 中讨论的其他器件

工具/软件:

大家好!

我正在使用  TMS320F28388D 、并正在通过 CAN 总线接收数据。

在轮询模式下、我使用 while 循环成功接收 CAN 消息。

但是、当我将 CAN 外设配置为中断模式时、不会触发接收中断、也不会接收到数据。

为了测试设置、我正在从 Microchip CAN 总线分析仪工具发送 CAN 消息。 在轮询模式下正确接收消息、但在中断模式下不正确接收消息。

CAN 外设:通过 syscfg 进行配置

测试设置:使用 Microchip CAN 总线分析仪发送消息

观察结果:

轮询模式工作正常(接收到数据)

中断模式无法正常工作:

无中断触发

未收到数据

以下是系统配置的配置

谢谢

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Sudhir:

    我认为 SysConfig 不会在主文件中创建 ISR (中断服务例程)。  SysConfig 会创建 ISR 定义并在 Board_init ()函数中启用中断。  请参阅一个具有 ISR 函数的现有 CAN 示例。  示例 can_ex2_loopback_interrupts 和 can_ex3_external_transmit 在 main 中具有 ISR 函数__interrupt void canISR (void)。  如果没有这个处理程序、将不会处理中断。

    此致、

    Joseph

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Joseph:

    感谢您的答复、  

    是的、我已经 在主文件中编写了 ISR 函数、如示例代码所示。 我还运行了 can_ex2_loopback_interrupts 和 can_ex3_external_transmit 示例、但很遗憾、在我的例子中仍然没有触发中断。

    如果还有其他问题、或者您对进一步调试有任何建议、请告知我

    下面是我的 ISR  

    void INT_myCAN0_0_isr ()

    uint32_t 状态;

    //
    //读取 CAN-B 中断状态以查找中断原因
    //
    STATUS = CAN_getInterruptCause (myCAN0_BASE);

    //
    //如果原因是控制器状态中断、则获取状态
    //
    IF (STATUS == CAN_INT_INT0ID_STATUS)

    //
    //读取控制器状态。 这将返回状态字段
    //可以指示各种错误的错误位。 错误处理
    //为简单起见、此示例中未执行。 请参阅
    // API 文档、了解有关错误状态位的详细信息。
    //读取此状态的行为将清除中断。
    //
    status = CAN_getStatus (myCAN0_base);

    //
    //检查是否发生错误。
    //
    if (((status &~(CAN_STATUS_RXOK))!= CAN_STATUS_LEC_MSK)&&
    ((status &~(CAN_STATUS_RXOK)!= CAN_STATUS_LEC_NONE)))

    //
    //设置一个标志以指示可能发生了一些错误。
    //
    errorFlag = 1;
    }
    }
    //
    //检查原因是否是 CAN-B 接收消息对象1
    //
    否则 if (status == RX_MSG_OBJ_ID)

    //
    //获取收到的消息
    //
    CAN_readMessage (myCAN0_BASE、RX_MSG_OBJ_ID、rxMsgData);

    //
    //到达此处意味着 RX 中断发生在上
    //消息对象1、消息 RX 完成。 清除
    //消息对象中断。
    //
    CAN_clearInterruptStatus (myCAN0_BASE、RX_MSG_OBJ_ID);

    //
    //增加一个计数器、以跟踪已有多少条消息
    //已收到。 在实际应用中、这可用于设置标志
    //指示何时收到消息。
    //
    // rxMsgCount++;

    //
    //收到消息后、清除所有错误标志。
    //
    errorFlag = 0;
    }
    //
    //如果发生意外导致了中断、这将处理它。
    //
    暴露

    //
    //可以在此处执行虚假中断处理。
    //
    }

    //
    //清除 CAN 中断线路的全局中断标志
    //
    can_clearGlobalInterruptStatus (myCAN0_BASE、CAN_GLOBAL_INT_CANINT0);

    //
    //确认位于组9中的该中断
    //
    INTERRUPT_CLEARACKGROUP (INTERRUPT_ACK_group9);
    // can_readMessage (myCAN0_BASE、myCAN0_MessageObj1_ID、&rxMsgData);
    // can_clearInterruptStatus (myCAN0_BASE、myCAN0_MessageObj1_ID);
    // can_clearGlobalInterruptStatus (myCAN0_base, can_global_INT_CANINT0 );
    // Interrupt_clearACKGroup (INTERRUPT_ACK_group9);
    }

    谢谢

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Sudhir:

    您能否发送 CAN 消息对象设置的片段?  您可能需要在 Set Up 对象函数的其中一个参数中设置中断标志。  此外、还发送由 SysConfig 生成的 CAN 中断函数的一个片段。  您可能需要额外的步骤才能使 CAN 中断生效。

    此致、

    Joseph

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Joseph、

    感谢您的答复、  

    下面是 CAN 消息对象设置的片段  

    void myCAN0_init (){
    CAN_initModule (myCAN0_BASE);
    //
    //有关如何设置的信息、请参阅驱动程序库用户指南
    //更严格的时序控制。 此外、请查阅器件数据表
    //有关 CAN 模块时钟的更多信息。
    //
    CAN_setBitTiming (myCAN0_BASE、7、0、15、7 3);
    //
    //启用 CAN 中断
    //
    can_enableInterrupt (myCAN0_BASE、can_INT_error|can_INT_IE0|can_INT_IE1|can_INT_status);
    can_enableGlobalInterrupt (myCAN0_BASE、can_global_INT_CANINT0);
    can_enableGlobalInterrupt (myCAN0_BASE、can_global_INT_CANINT1);
    //
    //初始化用于发送 CAN 消息的发送消息对象。
    //消息对象参数:
    //消息对象标识号:1.
    //消息标识符:0
    //消息帧:CAN_MSG_FRAME_STD
    //消息类型:can_msg_obj_type_tx
    //消息 ID 掩码:0
    //消息对象标志:
    //消息数据长度:4个字节
    //
    can_setupMessageObject (myCAN0_BASE、1、myCAN0_MessageObj1_ID、can_MSG_FRAME_STD、can_MSG_OBJ_TYPE_TX、0、 0,4);
    //
    //初始化用于发送 CAN 消息的发送消息对象。
    //消息对象参数:
    //消息对象标识号:2.
    //消息标识符:1.
    //消息帧:CAN_MSG_FRAME_STD
    //消息类型:can_MSG_OBJ_TYPE_RX
    //消息 ID 掩码:1.
    //消息对象标志:can_MSG_obj_use_ID_filter
    //消息数据长度:0字节
    //
    can_setupMessageObject (myCAN0_BASE、2、myCAN0_MessageObj2_ID、can_MSG_FRAME_STD、can_MSG_OBJ_TYPE_RX、1 can_msg_obj_use_ID_filter、0);
    CAN_setInterruptMux (myCAN0_BASE、2);
    //
    //启动 CAN 模块操作
    //
    can_startModule (myCAN0_base);
    }

    INTERRUPT_REGISTER (INT_myCAN0_0、&INT_myCAN0_0_ISR);
    INTERRUPT_ENABLE (INT_myCAN0_0);

    // INT_myCAN0_1的中断设置
    INTERRUPT_REGISTER (INT_myCAN0_1、&INT_myCAN0_1_ISR);
    INTERRUPT_ENABLE (INT_myCAN0_1);

    void INT_myCAN0_0_isr ()

    uint32_t 状态;

    //
    //读取 CAN-B 中断状态以查找中断原因
    //
    STATUS = CAN_getInterruptCause (myCAN0_BASE);

    //
    //如果原因是控制器状态中断、则获取状态
    //
    IF (STATUS == CAN_INT_INT0ID_STATUS)

    //
    //读取控制器状态。 这将返回状态字段
    //可以指示各种错误的错误位。 错误处理
    //为简单起见、此示例中未执行。 请参阅
    // API 文档、了解有关错误状态位的详细信息。
    //读取此状态的行为将清除中断。
    //
    status = CAN_getStatus (myCAN0_base);

    //
    //检查是否发生错误。
    //
    if (((status &~(CAN_STATUS_RXOK))!= CAN_STATUS_LEC_MSK)&&
    ((status &~(CAN_STATUS_RXOK)!= CAN_STATUS_LEC_NONE)))

    //
    //设置一个标志以指示可能发生了一些错误。
    //
    errorFlag = 1;
    CAN_clearInterruptStatus (myCAN0_BASE、RX_MSG_OBJ_ID);
    can_clearGlobalInterruptStatus (myCAN0_BASE、CAN_GLOBAL_INT_CANINT0);

    //
    //确认位于组9中的该中断
    //
    INTERRUPT_CLEARACKGROUP (INTERRUPT_ACK_group9);
    }
    }
    //
    //检查原因是否是 CAN-B 接收消息对象1
    //
    否则 if (status == RX_MSG_OBJ_ID)

    //
    //获取收到的消息
    //
    CAN_readMessage (myCAN0_BASE、RX_MSG_OBJ_ID、rxMsgData);

    //
    //到达此处意味着 RX 中断发生在上
    //消息对象1、消息 RX 完成。 清除
    //消息对象中断。
    //
    CAN_clearInterruptStatus (myCAN0_BASE、RX_MSG_OBJ_ID);

    //
    //增加一个计数器、以跟踪已有多少条消息
    //已收到。 在实际应用中、这可用于设置标志
    //指示何时收到消息。
    //
    // rxMsgCount++;

    //
    //收到消息后、清除所有错误标志。
    //
    errorFlag = 0;
    }
    //
    //如果发生意外导致了中断、这将处理它。
    //
    暴露

    //
    //可以在此处执行虚假中断处理。
    //
    }

    //
    //清除 CAN 中断线路的全局中断标志
    //
    can_clearGlobalInterruptStatus (myCAN0_BASE、CAN_GLOBAL_INT_CANINT0);

    //
    //确认位于组9中的该中断
    //
    INTERRUPT_CLEARACKGROUP (INTERRUPT_ACK_group9);
    // can_readMessage (myCAN0_BASE、myCAN0_MessageObj1_ID、&rxMsgData);
    // can_clearInterruptStatus (myCAN0_BASE、myCAN0_MessageObj1_ID);
    // can_clearGlobalInterruptStatus (myCAN0_base, can_global_INT_CANINT0 );
    // Interrupt_clearACKGroup (INTERRUPT_ACK_group9);
    }
    void INT_myCAN0_1_isr ()

    // can_readMessage (myCAN0_BASE、myCAN0_MessageObj1_ID、&rxMsgData);
    // can_clearInterruptStatus (myCAN0_BASE、myCAN0_MessageObj1_ID);
    // can_clearGlobalInterruptStatus (myCAN0_base, can_global_INT_CANINT1 );
    // Interrupt_clearACKGroup (INTERRUPT_ACK_group9);
    uint32_t 状态;

    //
    //读取 CAN-B 中断状态以查找中断原因
    //
    STATUS = CAN_getInterruptCause (myCAN0_BASE);

    //
    //如果原因是控制器状态中断、则获取状态
    //
    IF (STATUS == CAN_INT_INT0ID_STATUS)

    //
    //读取控制器状态。 这将返回状态字段
    //可以指示各种错误的错误位。 错误处理
    //为简单起见、此示例中未执行。 请参阅
    // API 文档、了解有关错误状态位的详细信息。
    //读取此状态的行为将清除中断。
    //
    status = CAN_getStatus (myCAN0_base);

    //
    //检查是否发生错误。
    //
    if (((status &~(CAN_STATUS_RXOK))!= CAN_STATUS_LEC_MSK)&&
    ((status &~(CAN_STATUS_RXOK)!= CAN_STATUS_LEC_NONE)))

    //
    //设置一个标志以指示可能发生了一些错误。
    //
    errorFlag = 1;
    }
    }
    //
    //检查原因是否是 CAN-B 接收消息对象1
    //
    否则 if (status == RX_MSG_OBJ_ID)

    //
    //获取收到的消息
    //
    CAN_readMessage (myCAN0_BASE、RX_MSG_OBJ_ID、rxMsgData);

    //
    //到达此处意味着 RX 中断发生在上
    //消息对象1、消息 RX 完成。 清除
    //消息对象中断。
    //
    CAN_clearInterruptStatus (myCAN0_BASE、RX_MSG_OBJ_ID);

    //
    //增加一个计数器、以跟踪已有多少条消息
    //已收到。 在实际应用中、这可用于设置标志
    //指示何时收到消息。
    //
    // rxMsgCount++;

    //
    //收到消息后、清除所有错误标志。
    //
    errorFlag = 0;
    }
    //
    //如果发生意外导致了中断、这将处理它。
    //
    暴露

    //
    //可以在此处执行虚假中断处理。
    //
    }

    //
    //清除 CAN 中断线路的全局中断标志
    //
    CAN_clearGlobalInterruptStatus (myCAN0_BASE、CAN_GLOBAL_INT_CANINT1);

    //
    //确认位于组9中的该中断
    //
    INTERRUPT_CLEARACKGROUP (INTERRUPT_ACK_group9);
    }   

    现在、这一次中断被触发、但出现错误并卡在错误循环中  

    STATUS = CAN_getInterruptCause (myCAN0_BASE);

    //
    //如果原因是控制器状态中断、则获取状态
    //
    IF (STATUS == CAN_INT_INT0ID_STATUS)

    //
    //读取控制器状态。 这将返回状态字段
    //可以指示各种错误的错误位。 错误处理
    //为简单起见、此示例中未执行。 请参阅
    // API 文档、了解有关错误状态位的详细信息。
    //读取此状态的行为将清除中断。
    //
    status = CAN_getStatus (myCAN0_base);

    //
    //检查是否发生错误。
    //
    if (((status &~(CAN_STATUS_RXOK))!= CAN_STATUS_LEC_MSK)&&
    ((status &~(CAN_STATUS_RXOK)!= CAN_STATUS_LEC_NONE)))

    //
    //设置一个标志以指示可能发生了一些错误。
    //
    errorFlag = 1;
    CAN_clearInterruptStatus (myCAN0_BASE、RX_MSG_OBJ_ID);
    can_clearGlobalInterruptStatus (myCAN0_BASE、CAN_GLOBAL_INT_CANINT0);

    //
    //确认位于组9中的该中断
    //
    INTERRUPT_CLEARACKGROUP (INTERRUPT_ACK_group9);
    }
    } 谢谢

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Sudhir:

    将代码插入帖子时、请使用下面的"插入"选项卡、然后选择" "代码"选项。  这使得文章通过分离代码片段和文章的文本更可读。

    查看下面的 setup objects 语句:

    CAN_setupMessageObject(myCAN0_BASE, 1, myCAN0_MessageObj1_ID, CAN_MSG_FRAME_STD,CAN_MSG_OBJ_TYPE_TX, 0, CAN_MSG_OBJ_TX_INT_ENABLE,4);
    
    CAN_setupMessageObject(myCAN0_BASE, 2, myCAN0_MessageObj2_ID, CAN_MSG_FRAME_STD,CAN_MSG_OBJ_TYPE_RX, 1, CAN_MSG_OBJ_USE_ID_FILTER|CAN_MSG_OBJ_RX_INT_ENABLE,0);
    
    

     必须修改 can_setupMessageObject()函数的第二个到最后一个参数、以包括中断标志。  请参阅上面的片段。  上述更改应触发任何发送或接收的 CAN 帧的中断。

    请尝试将这些标志添加到对象设置函数调用中。

    此致、

    Joseph