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.

[参考译文] TMS320F280025:TMS320f280025

Guru**** 2391415 points
Other Parts Discussed in Thread: C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1241019/tms320f280025-tms320f280025

器件型号:TMS320F280025
主题中讨论的其他器件:C2000WARE

大家好,

任何人帮助我在 CAN 接口,我做了初始化与示例代码 bitfield 可以并尝试回送,在回送它的工作完美,并进入中断也,但一旦我删除回送模式,意味着回送模式是0和测试寄存器也是0。 然后它停止工作,它将不会进行 CAN 中断,任何人请引导我,并更多的说明使用 GPIO 32和 GPIO 33 ,所以任何细节规范需要在这些 GPIO 初始化作为 CAN TX 和 CANRX

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

    Sanmati,  

    您曾提到、当您关闭环回模式时、CAN 操作不起作用。 请注意、由于 CAN 协议期望 ACK 信号、因此需要一个收发器才能成功进行通信。  

    有关常见的调试策略、您可以参考以下应用手册。

    谢谢。

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

    大家好,Sahil,

    所有与 CAN 相关的硬件都已在板上添加  ,但不会发生 CAN 中断,请参考 以下配置   

    GPIO_SetupPinMux (32、GPIO_MUX_CPU1、10);
    GPIO_SetupPinOptions (32、GPIO_output、GPIO_PushPull);
    GPIO_SetupPinMux (33、GPIO_MUX_CPU1、10);
    GPIO_SetupPinOptions (33、GPIO_output、GPIO_ASYNC);

    空 InitCAN (空)
    {

     ClkCfgRegs.CLKSRCCTL2.bit.CANABCLKSEL = 0;


    int16_t iMsg;

    //
    //将 CAN 控制器置于初始化状态,而不考虑之前的状态。 这个
    //将控制器置于空闲状态,并允许消息对象 RAM
    //已编程。
    //
    CanaRegs.CAN_CTL.bit.Init = 1;
    CanaRegs.CAN_CTL.bit.SWR = 1;

    //
    //等待 BUSY 位清零
    //
    while (CanaRegs.CAN_IF1CMD.bit.BUSY)
    {

    //
    //将仲裁寄存器中的报文值位清零 这表明
    //消息无效,是离开消息的"安全"条件
    //对象。 相同的 ARB 寄存器用于对所有消息对象进行编程。
    //
    CanaRegs.CAN_IF1CMD.bit.DIR = 1;
    CanaRegs.CAN_IF1CMD.bit.ARB = 1;
    CanaRegs.CAN_IF1CMD.bit.Control = 1;

    CanaRegs.CAN_IF1ARB.all = 0;

    CanaRegs.CAN_IF1MCTL.ALL = 0;
    CanaRegs.CAN_CTL.bit.DAR = 1;

    CanaRegs.CAN_IF2CMD.bit.DIR = 1;
    CanaRegs.CAN_IF2CMD.bit.ARB = 1;
    CanaRegs.CAN_IF2CMD.bit.Control = 1;

    CanaRegs.CAN_IF2ARB.all = 0;

    CanaRegs.CAN_IF2MCTL.ALL = 0;

    CanaRegs.CAN_CTL.bit.ABO = 1;

    CanaRegs.CAN_ABOTR = 0x02;

    //循环遍历所有的32个报文对象

    for (iMsg = 1;iMsg <= 32;iMsg+=2)
    {
    //
    //等待 BUSY 位清零
    //
    while (CanaRegs.CAN_IF1CMD.bit.BUSY)
    {

    //
    //开始对报文对象进行编程
    //
    CanaRegs.CAN_IF1CMD.bit.MSG_NUM = iMsg;

    //
    //等待 BUSY 位清零
    //
    while (CanaRegs.CAN_IF2CMD.bit.BUSY)
    {

    //
    //开始对报文对象进行编程
    //
    CanaRegs.CAN_IF2CMD.bit.MSG_NUM = iMsg + 1;

    //
    //确认任何挂起的状态中断。
    //
    易失性 uint32_t 丢弃 Read = CanaRegs.CAN_ES.all;

     uint32_t status = setCANBitRate (100000,000,500000);

    uint32_t setCANBitRate (uint32_t sourceClock、uint32_t bitrate)
    {
    uint32_t 设计速率;
    uint32_t canBits;
    uint32_t predivide;
    uint32_t regValue;
    uint16_t canControlValue;

    //
    //计算所需的时钟速率。
    //
    desedRatio =源时钟/比特率;

    //
    //确保所需的比率不会过大。 这将强制
    //要求比特率大于请求的值。
    //
    if (((sourceClock / desiredRatio)> bitrate)
    {
    所需比率+=1;

    //
    //检查所有可能的值以查找匹配值。
    //
    while (desedRatio <= CAN_MAX_PRE_DIVENCH * CAN_MAX_BIT_DIVENCH)
    {
    //
    //循环通过所有可能的 CAN 位分频。
    //
    for (canBits = CAN_MAX_bit_division;
    canBits >= can_min_bit_division;
    canBits--)
    {
    //
    //对于给定的 CAN 位分频值,保存预分频值。
    //
    PreDivide = desiredRatio / canBits;

    //
    //如果计算出的分频值与所需的时钟比率相匹配,则
    //返回这些比特率并设置 CAN 位时序。
    //
    if ((predivide * canBits)= desiredRatio)
    {
    //
    //通过添加位定时开始构建位定时值
    //时间份额。
    //
    regValue = canBitValues[canBits - CAN_MIN_BIT_DIVIDENS];

    //
    //要设置位定时寄存器,必须将控制器设置为
    //已放置
    //在初始化模式中(如果尚未),以及配置更改
    //位被启用。 则应将寄存器的状态保存到
    //这样就可以恢复它。
    //
    canControlValue = CanaRegs.CAN_CTL.all;
    CanaRegs.CAN_CTL.bit.Init = 1;
    CanaRegs.CAN_CTL.bit.CCE = 1;

    //
    //现在添加位速率的预分频。
    //
    regValue |=((predivide - 1)和 CAN_BTR_BRP_M)|
    (((PreDivide - 1)<< 10)& CAN_BTR_BRPE_M);

    //
    //设置中的时钟位以及
    //预分频。
    //
    CanaRegs.CAN_BTR.all = regValue;

    //
    //恢复保存的 CAN 控制寄存器。
    //
    CanaRegs.CAN_CTL.all = canControlValue;

    //
    //返回计算出的比特率。
    //
    return (sourceClock /(predivide * canBits);

    //
    //将分频值向上移动一个,然后再次查看。 只有在极少数情况下
    //需要2个以上的循环来查找值。
    //
    desiredRatio++;

    返回0;

    //
    // setupMessageObject -将消息对象设置为发送或接收
    //
    void setupMessageObject (uint32_t Objid、uint32_t msgid、msgObjType msgType、int16_t msgEnableInterrupt)
    {
    //
    //等待 BUSY 位清零
    //
    while (CanaRegs.CAN_IF1CMD.bit.BUSY)
    {

    //
    //清除并写入寄存器以对报文对象进行编程。
    //
    CanaRegs.CAN_IF1CMD.all = 0;
    CanaRegs.CAN_IF1MSK.all = 0;
    CanaRegs.CAN_IF1ARB.all = 0;
    CanaRegs.CAN_IF1MCTL.ALL = 0;

    //
    //设置 Control、Mask 和 ARB 位,以便将其传输到
    //消息对象。
    //
    CanaRegs.CAN_IF1CMD.bit.Control = 1;
    CanaRegs.CAN_IF1CMD.bit.ARB = 1;
    CanaRegs.CAN_IF1CMD.bit.Mask = 1;
    CanaRegs.CAN_IF1CMD.bit.DIR = 1;

    //
    //设置发送方向
    //
    if (msgType == MSG_OBJ_TYPE_TRANSMIT_REMOTE)
    {
    CanaRegs.CAN_IF1ARB.bit.Dir = 0;
    CanaRegs.CAN_IF1MCTL.bit.TxRqst =1;

    if (msgType == MSG_OBJ_TYPE_RECEIVE)
    {
    CanaRegs.CAN_IF1ARB.bit.Dir = 0;
    CanaRegs.CAN_IF1MCTL.bit.TxRqst =0;

    if (msgType == MSG_OBJ_TYPE_RxTx_REMOTE)
    {
    CanaRegs.CAN_IF1ARB.bit.Dir = 1;
    CanaRegs.CAN_IF1ARB.bit.XTD = 0;
    CanaRegs.CAN_IF1MCTL.bit.RmtEn =1;
    CanaRegs.CAN_IF1MCTL.bit.umask =1;

    CanaRegs.CAN_IF1MSK.bit.MDir = 1;
    CanaRegs.CAN_IF1MSK.bit.MXtd =0;
    CanaRegs.CAN_IF1MSK.bit.MSK = 0x1FFFFFFF;//msgid;

    if (msgEnableInterrupt == Enable_Rxinterrupt)
    {
    CanaRegs.CAN_IF1MCTL.bit.RxIE =1;
    CanaRegs.CAN_CTL.bit.IE0 =1;
    CanaRegs.CAN_GLB_INT_EN.bit.GLBINT0_EN =1;

    //
    //设置消息 ID (此示例假定11位 ID 掩码)

    CanaRegs.CAN_IF1ARB.bit.ID = msgid;
    CanaRegs.CAN_IF1ARB.bit.MsgVal = 1;

    //
    //设置数据长度,因为这是针对所有传输设置的。 这是
    //同时也是单次传输而不是 FIFO 传输,因此应设置 EOB 位。
    //
    CanaRegs.CAN_IF1MCTL.bit.DLC = messageSize;
    CanaRegs.CAN_IF1MCTL.bit.EOB = 1;

    //将数据传输到消息对象 RAM
    CanaRegs.CAN_IF1CMD.bit.MSG_NUM = Objid;

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

    好的、我会审阅代码并回复给您。  

    您使用什么器件/节点来接收帧? 请注意、您需要在 CAN 总线上至少有两个节点才能成功通信。

    谢谢。

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

    Sahil ,

    我们在 CAN 总线上使用3个节点。

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

    Sanmati,

                   使用位字段而不使用 Driverlib 是有原因的吗? 请注意、弃用了对位字段的支持、以后将只支持/更新 Driverlib。

    我强烈建议您查看 SPRACE5A 中的调试提示。 并在您的硬件上尝试使用 C2000ware Driverlib 示例。 由于这些都是经过测试的示例、因此您可以使用它们来确定 H/W 中是否存在任何问题。 确定您是硬件问题还是软件问题非常重要。

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

    Hareesh、

    我将无法使用 drivellib、因为我的其他应用程序和其他代码已经采用 bitfield 格式、并且我只能尝试添加 drivelib、它又出现了另外10个错误、因此请帮我并仅针对使用 bitfield 来指导我。  

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

    Sanmati,  

    setupMessageObject 函数中、需要注意的一点是、IF1CMD 应以单个32位写入的方式写入。 这是因为、在对该寄存器进行写操作后、BUSY 位置位、使得从 IFx 寄存器到报文 RAM 的数据传输需要特定数量的周期。  

    特别是在下面提到的情况中、这可能会导致错误写入。

    但是、可以定义影子变量、将所有值输入到影子变量中、并且可以在32位单次写入中写入、如下所示:

    谢谢。

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

    大家好,Sahil,

    我们也已尝试过此功能,如果需要更改,请返回以下配置。

    void setupMessageObject (uint32_t Objid、uint32_t msgid、msgObjType msgType、int16_t msgEnableInterrupt)
    {
    联合 CAN_IF1CMD_REG CAN_IF1CMD_shadow;

    //
    //等待 BUSY 位清零
    //
    while (CanaRegs.CAN_IF1CMD.bit.BUSY)
    {

    //
    //清除并写入寄存器以对报文对象进行编程。
    //
    CAN_IF1CMD_shadow.all = 0;
    CanaRegs.CAN_IF1CMD.all = 0;
    CanaRegs.CAN_IF1MSK.all = 0;
    CanaRegs.CAN_IF1ARB.all = 0;
    CanaRegs.CAN_IF1MCTL.ALL = 0;

    //
    //设置 Control、Mask 和 ARB 位,以便将其传输到
    //消息对象。
    //
    CAN_IF1CMD_shadow.bit.Control = 1;
    can_IF1CMD_shadow.bit.arb = 1;
    CAN_IF1CMD_shadow.bit.Mask = 1;
    CAN_IF1CMD_SHADD.bit.DIR = 1;
    // CanaRegs.CAN_IF1CMD.bit.Control = 1;
    // CanaRegs.CAN_IF1CMD.bit.ARB = 1;
    // CanaRegs.CAN_IF1CMD.bit.Mask = 1;
    // CanaRegs.CAN_IF1CMD.bit.DIR = 1;

    //
    //设置发送方向
    //
    if (msgType == MSG_OBJ_TYPE_TRANSMIT)
    {
    CanaRegs.CAN_IF1ARB.bit.Dir = 1;

    if (msgType == MSG_OBJ_TYPE_TRANSMIT_REMOTE)
    {
    CanaRegs.CAN_IF1ARB.bit.Dir = 0;
    CanaRegs.CAN_IF1MCTL.bit.TxRqst =1;

    if (msgType == MSG_OBJ_TYPE_RECEIVE)
    {
    CanaRegs.CAN_IF1ARB.bit.Dir = 0;
    CanaRegs.CAN_IF1MCTL.bit.TxRqst =0;

    if (msgType == MSG_OBJ_TYPE_RxTx_REMOTE)
    {
    CanaRegs.CAN_IF1ARB.bit.Dir = 1;
    CanaRegs.CAN_IF1ARB.bit.XTD = 0;
    CanaRegs.CAN_IF1MCTL.bit.RmtEn =1;
    CanaRegs.CAN_IF1MCTL.bit.umask =1;

    CanaRegs.CAN_IF1MSK.bit.MDir = 1;
    CanaRegs.CAN_IF1MSK.bit.MXtd =0;
    CanaRegs.CAN_IF1MSK.bit.MSK = 0x1FFFFFFF;//msgid;

    if (msgEnableInterrupt == Enable_Rxinterrupt)
    {
    CanaRegs.CAN_IF1MCTL.bit.RxIE =1;
    CanaRegs.CAN_CTL.bit.IE0 =1;
    CanaRegs.CAN_GLB_INT_EN.bit.GLBINT0_EN =1;
    CanaRegs.CAN_CTL.bit.EIE = 1;
    CanaRegs.CAN_CTL.bit.SIE =1;// 3错误中断启用

    否则
    {
    CanaRegs.CAN_IF1MCTL.bit.RxIE =0;
    CanaRegs.CAN_CTL.bit.IE0 = 0;
    CanaRegs.CAN_CTL.bit.EIE = 0;
    CanaRegs.CAN_CTL.bit.SIE =0;// 3错误中断启用
    CanaRegs.CAN_GLB_INT_EN.bit.GLBINT0_EN =0;


    //
    //设置消息 ID (此示例假定11位 ID 掩码)
    //
    CanaRegs.CAN_IF1ARB.bit.ID = msgid;
    CanaRegs.CAN_IF1ARB.bit.MsgVal = 1;

    //
    //设置数据长度,因为这是针对所有传输设置的。 这是
    //同时也是单次传输而不是 FIFO 传输,因此应设置 EOB 位。
    //
    CanaRegs.CAN_IF1MCTL.bit.DLC = messageSize;
    CanaRegs.CAN_IF1MCTL.bit.EOB = 1;

    //
    //将数据传输到消息对象 RAM
    //
    CAN_IF1CMD_SHADD.bit.MSG_NUM = Objid;
    CanaRegs.CAN_IF1CMD.all = CAN_IF1CMD_shadow.all;

     

    谢谢。

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

    Sanmati,

      我们不能在 e2e 上支持调试代码。 您能否在您的硬件上运行 Driverlib 示例、看看它是否有效? 这样、我们至少可以确定您的设置中没有硬件问题。 然后、您可以将注意力转向软件。