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.

[参考译文] MSPM0G3507:CAN RX -消息不能可靠接收

Guru**** 2457760 points
Other Parts Discussed in Thread: SYSCONFIG

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1485613/mspm0g3507-can-rx---messages-are-not-received-reliably

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

工具与软件:

您好、TI 专家!

在相关的问题线程中、我遇到的问题是我的 CAN-ID-Filtering 不起作用。 我现在发现了原因:

第一步:我在执行 DL_MCAN_addStdMsgIDFilter()后初始化过滤器 ID、其中配置了过滤器。 因此、我使用未初始化的滤波器 ID 配置了滤波。

第二步:我没有在 SysConfig 中使用"高级配置"、因此我没有设置.filterConfig.anfe = 2和.filterConfig.anfs = 2。 因此、即使在我设法正确设置滤波后、也会接受不匹配帧。

因此、我现在设法使我的滤波工作。

但其他问题仍未解决:

CAN 消息的接收无法可靠地工作。 有时第一条 CAN 消息被正确接收、有时第一条 CAN 消息不会触发 CAN Rx 中断、因此无法接收。

这种不可靠的接收会随着要接收到的每一条消息的继续而继续。 有时它工作,有时不工作。

当未接收到一条消息然后正确接收到下一条消息时、将触发 CAN RX 中断、并设置"新消息位"(MCAN_IR_RF0N_MASK)和"消息 RAM 访问失败位"(MCAN_IR_MRAF_MASK)。

但只有触发 CAN RX 中断的消息才会被接收。 另一条消息不会出现在 Rx 消息结构中。

是否有可能查看 CAN RX FIFO 以了解这些消息是否在 FIFO 中但并未触发中断?

RX MSG RAM 配置正确、FIFO0、FIFO1和缓冲区之间没有重叠。 我不使用 CAN TX、因此不应存在 TX MSG RAM 的重叠和影响。

不触发中断的原因可能是什么、或者更准确地说、是什么原因导致在正确接收到欧姆代码时未收到某些消息?

提前感谢!

Matze

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

    您好!

    我以前没有遇到过这种问题。 通常情况下、如果您的配置正确、 然后 MCU 将接收与滤波器匹配的所有消息。 您是否可以在此处发送 SysConfig 文件、以便我们对其进行查看?

    此致、

    Cash Hao

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

    当然:

    /**
     * These arguments were used when this file was generated. They will be automatically applied on subsequent loads
     * via the GUI or CLI. Run CLI with '--help' for additional information on how to override these arguments.
     * @cliArgs --device "MSPM0G350X" --part "Default" --package "LQFP-48(PT)" --product "mspm0_sdk@2.02.00.05"
     * @v2CliArgs --device "MSPM0G3507" --package "LQFP-48(PT)" --product "mspm0_sdk@2.02.00.05"
     * @versions {"tool":"1.21.0+3721"}
     */
    
    /**
     * Import the modules used in this configuration.
     */
    const ADC12         = scripting.addModule("/ti/driverlib/ADC12", {}, false);
    const ADC121        = ADC12.addInstance();
    const Board         = scripting.addModule("/ti/driverlib/Board");
    const GPIO          = scripting.addModule("/ti/driverlib/GPIO", {}, false);
    const GPIO1         = GPIO.addInstance();
    const GPIO2         = GPIO.addInstance();
    const MCAN          = scripting.addModule("/ti/driverlib/MCAN", {}, false);
    const MCAN1         = MCAN.addInstance();
    const PWM           = scripting.addModule("/ti/driverlib/PWM", {}, false);
    const PWM1          = PWM.addInstance();
    const SYSCTL        = scripting.addModule("/ti/driverlib/SYSCTL");
    const TIMER         = scripting.addModule("/ti/driverlib/TIMER", {}, false);
    const TIMER1        = TIMER.addInstance();
    const ProjectConfig = scripting.addModule("/ti/project_config/ProjectConfig");
    
    /**
     * Write custom configuration values to the imported modules.
     */
    ADC121.$name                      = "ADC12_0";
    ADC121.adcMem0chansel             = "DL_ADC12_INPUT_CHAN_4";
    ADC121.sampleTime0                = "125 us";
    ADC121.sampClkDiv                 = "DL_ADC12_CLOCK_DIVIDE_8";
    ADC121.enabledInterrupts          = ["DL_ADC12_INTERRUPT_MEM0_RESULT_LOADED"];
    ADC121.peripheral.$assign         = "ADC1";
    ADC121.peripheral.adcPin4.$assign = "PB17";
    ADC121.adcPin4Config.$name        = "ti_driverlib_gpio_GPIOPinGeneric1";
    
    Board.peripheral.$assign          = "DEBUGSS";
    Board.peripheral.swclkPin.$assign = "PA20";
    Board.peripheral.swdioPin.$assign = "PA19";
    
    GPIO1.$name                              = "GPIO_GRP_0";
    GPIO1.port                               = "PORTA";
    GPIO1.associatedPins.create(2);
    GPIO1.associatedPins[0].$name            = "DI_BUTTON";
    GPIO1.associatedPins[0].direction        = "INPUT";
    GPIO1.associatedPins[0].interruptEn      = true;
    GPIO1.associatedPins[0].polarity         = "RISE_FALL";
    GPIO1.associatedPins[0].pin.$assign      = "PA28";
    GPIO1.associatedPins[1].$name            = "DO_EN_EXT_LED";
    GPIO1.associatedPins[1].internalResistor = "PULL_UP";
    GPIO1.associatedPins[1].initialValue     = "SET";
    GPIO1.associatedPins[1].pin.$assign      = "PA23";
    
    GPIO2.$name                          = "GPIO_GRP_1";
    GPIO2.associatedPins.create(2);
    GPIO2.associatedPins[0].$name        = "DO_EN_MC33063A";
    GPIO2.associatedPins[0].assignedPort = "PORTA";
    GPIO2.associatedPins[0].pin.$assign  = "PA7";
    GPIO2.associatedPins[1].$name        = "DO_BOOST_PIEZO";
    GPIO2.associatedPins[1].assignedPort = "PORTB";
    GPIO2.associatedPins[1].pin.$assign  = "PB2";
    
    MCAN1.$name                     = "MCAN0";
    MCAN1.fdMode                    = false;
    MCAN1.wkupReqEnable             = true;
    MCAN1.autoWkupEnable            = true;
    MCAN1.emulationEnable           = true;
    MCAN1.dataRatePrescalar_manual  = 1;
    MCAN1.dataTimeSeg1_manual       = 8;
    MCAN1.dataTimeSeg2_manual       = 8;
    MCAN1.stdFiltElem               = "001";
    MCAN1.stdFiltID1                = 416;
    MCAN1.stdFiltID2                = 416;
    MCAN1.extFiltElem               = "001";
    MCAN1.extFiltType               = "00";
    MCAN1.extFiltID1                = 36257792;
    MCAN1.extFiltID2                = 36257792;
    MCAN1.rxBufElemSize             = "DL_MCAN_ELEM_SIZE_8BYTES";
    MCAN1.rxFIFO0ElemSize           = "DL_MCAN_ELEM_SIZE_8BYTES";
    MCAN1.rxFIFO1ElemSize           = "DL_MCAN_ELEM_SIZE_8BYTES";
    MCAN1.enableInterrupt           = true;
    MCAN1.interruptLine1Flag        = ["DL_MCAN_INTERRUPT_RF0N"];
    MCAN1.desiredDataRate           = 0;
    MCAN1.m0interrupts              = ["DL_MCAN_MSP_INTERRUPT_DOUBLE_ERROR_DETECTION","DL_MCAN_MSP_INTERRUPT_LINE0","DL_MCAN_MSP_INTERRUPT_LINE1","DL_MCAN_MSP_INTERRUPT_SINGLE_ERROR_CORRECTION "];
    MCAN1.interruptLine             = ["DL_MCAN_INTR_LINE_NUM_0","DL_MCAN_INTR_LINE_NUM_1"];
    MCAN1.rxFIFO0size               = 10;
    MCAN1.rxFIFO0waterMark          = 8;
    MCAN1.interruptFlags            = ["DL_MCAN_INTERRUPT_RF0F","DL_MCAN_INTERRUPT_RF0N","DL_MCAN_INTERRUPT_RF0W"];
    MCAN1.interruptLine0Flag        = ["DL_MCAN_INTERRUPT_RF0F","DL_MCAN_INTERRUPT_RF0W"];
    MCAN1.stdFiltType               = "00";
    MCAN1.additionalCoreConfig      = true;
    MCAN1.rrfe                      = true;
    MCAN1.rrfs                      = true;
    MCAN1.anfe                      = "2";
    MCAN1.anfs                      = "2";
    MCAN1.rxFIFO1startAddr          = 336;
    MCAN1.rxBufStartAddr            = 372;
    MCAN1.lse                       = 2;
    MCAN1.lss                       = 2;
    MCAN1.desiredNomRate            = 50;
    MCAN1.dataSynchJumpWidth_manual = 8;
    MCAN1.peripheral.$assign        = "CANFD0";
    MCAN1.peripheral.rxPin.$assign  = "PA27";
    MCAN1.peripheral.txPin.$assign  = "PA26";
    MCAN1.txPinConfig.$name         = "ti_driverlib_gpio_GPIOPinGeneric3";
    MCAN1.rxPinConfig.$name         = "ti_driverlib_gpio_GPIOPinGeneric4";
    MCAN1.rxPinConfig.enableConfig  = true;
    
    PWM1.$name                              = "PWM_PIEZO";
    PWM1.ccIndexCmpl                        = [0];
    PWM1.ccIndex                            = [0];
    PWM1.interrupts                         = ["LOAD_EVENT","ZERO_EVENT"];
    PWM1.clockPrescale                      = 4;
    PWM1.timerStartTimer                    = true;
    PWM1.timerCount                         = 5000;
    PWM1.peripheral.$assign                 = "TIMA0";
    PWM1.peripheral.ccp0Pin.$assign         = "PB8";
    PWM1.peripheral.ccp0Pin_cmpl.$assign    = "PB9";
    PWM1.PWM_CHANNEL_0.$name                = "ti_driverlib_pwm_PWMTimerCC0";
    PWM1.PWM_CHANNEL_0.dutyCycle            = 1;
    PWM1.ccp0PinConfig.direction            = scripting.forceWrite("OUTPUT");
    PWM1.ccp0PinConfig.hideOutputInversion  = scripting.forceWrite(false);
    PWM1.ccp0PinConfig.onlyInternalResistor = scripting.forceWrite(false);
    PWM1.ccp0PinConfig.passedPeripheralType = scripting.forceWrite("Digital");
    PWM1.ccp0PinConfig.$name                = "ti_driverlib_gpio_GPIOPinGeneric0";
    PWM1.ccp0Pin_cmplConfig.$name           = "ti_driverlib_gpio_GPIOPinGeneric2";
    
    SYSCTL.validateClkStatus  = true;
    SYSCTL.CANCLKSource       = "SYSPLLCLK1";
    SYSCTL.HFCLKSource        = "HFXT";
    SYSCTL.HFCLK_Freq         = 10000000;
    SYSCTL.SYSPLL_CLK1En      = true;
    SYSCTL.peripheral.$assign = "SYSCTL";
    
    TIMER1.$name            = "TIMER_0";
    TIMER1.timerMode        = "PERIODIC";
    TIMER1.timerClkDiv      = 8;
    TIMER1.timerClkPrescale = 32;
    TIMER1.timerPeriod      = "500 ms";
    TIMER1.interrupts       = ["ZERO"];
    
    ProjectConfig.migrationCondition = true;
    
    /**
     * Pinmux solution for unlocked pins/peripherals. This ensures that minor changes to the automatic solver in a future
     * version of the tool will not impact the pinmux you originally saw.  These lines can be completely deleted in order to
     * re-solve from scratch.
     */
    TIMER1.peripheral.$suggestSolution = "TIMA1";
    

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

    您好!

    我会检查配置。 我观察到了几点。  

    1.尝试启用 TDC 功能

    2.即使不使用 TX MSG RAM。 您仍需要确认地址没有重叠。 当前配置中存在重叠。

    此致、

    Cash Hao

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

    您好、谢谢!

    1.我启用了 TDC 功能:

    ________________________________________________________________

    2.消除了 RX 和 TX Msg RAM 重叠:

    ________________________________________________________________

    但我仍然遇到同样不可靠的接待。

    还有什么可能会出错的想法吗? 我还可以检查哪些内容?

    TDC 的值调整应该在什么限制范围内? 我能否以某种方式测量可能必须补偿的延迟到底有多大?

    提前感谢!

    Matze

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

    您好!

    嗯、我正在检查"消息 RAM 访问故障位"的说明

    消息 RAM 访问失败。 当 Rx 处理程序发生以下情况时会设置该标志:
    -尚未完成验收过滤或已接受的存储
    消息、直到后续消息的仲裁字段生效
    正确操作。 在这种情况下、进行接受过滤或消息存储
    中止、Rx 处理程序开始处理以下各项
    显示的帧类型。
    -无法将消息写入消息 RAM。 阻抗不匹配
    消息存储中止。
    在这两种情况下、均不会更新 FIFO Put 索引、或者 新数据
    未设置专用 Rx 缓冲器的标志、部分存储的消息
    将下一条消息存储到该位置时被覆盖。
    当 Tx 处理程序无法读取 A 时、也会设置该标志
    消息 RAM 及时发出。 消息
    传输被中止。 以防 Tx 处理程序访问失败
    MCAN 切换至受限运行模式。 退出
    受限运行模式下、主机 CPU 必须复位 CCCR.ASM。

    在您的配置中、您可以尝试更改两个过滤器选项、以将消息存储在不同的 FIFO 中。 标准过滤器可以用于保存在 RX FIFO0中、扩展过滤器可以用于保存在 RX FIFO1中。 这有助于避免无法将消息写入 RAM。

    此致、

    Cash Hao

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在您的配置中、您可以尝试更改两个过滤器选项、以将消息存储在不同的 FIFO 中。

    我可以尝试改变这种情况、但我不期望会有太大的改进。  

    原因有四:

    1.第一条消息未到达并不少见,而第二条消息则会设置"消息 RAM 访问失败位"。 我没有看到 RAM 无法访问的可能性。

    2.以较长的时间间隔手动发送 CAN 报文、以便上一条报文必须已经处理好、且 RAM 应该不再忙。

    3. 当我用相同的标准或扩展 ID 发送多条消息时也会发生这种情况。 因此、如果另一个 ID 存储在另一个 FIFO 中、我不希望有任何优势。

    4.我使用4个不同的 ID、2个标准 ID 和2个扩展 ID ... 因此、理论上我会再次在相应的 FIFO 中面临相互干扰的风险。

    你怎么看?

    ____________________________________________

    [报价 userid="353832" url="~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1485613/mspm0g3507-can-rx---messages-are-not-received-reliably/5706711 #5706711"]在什么限制范围内调整 TDC 的值是合理的? 我能否以某种方式衡量我可能必须补偿的延迟到底有多大?

    这些问题有什么想法或答案吗?

    非常感谢、此致、

    Matze

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

    您好!

    我同意您的看法、 第一条消息未到达、然后为到达的第二条消息设置"消息 RAM 访问失败位"的情况非常少见。

     关于这个问题、我没有很多线索。 可能尝试删除滤波器配置、然后检查此问题是否仍然存在。 不带滤波器的原始演示代码肯定不会出现这种问题。 我想它可能与滤波器有关。  

    TDC 的更多信息、我发现它适用于 CAN FD 帧。 它不适用于经典 CAN。 所以、这里无需担心。

    此致、

    Cash Hao

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

    您好!

    同时我发现、CAN 接收的问题是由我设置的 CAN 频率的80 MHz 引起的。 我把我的 CAN 频率改为40 MHz 后,我在 CAN 接收的问题都消失了!

    但我不知道、为什么80 MHz 不能毫无差错地工作。

    我同意您的观点、 第一条消息未到达、然后为到达的第二条消息设置"消息 RAM 访问失败位"的情况非常少见。

    关于这一问题、我还了解到为什么需要澄清:

    当第二个 Msg 的 CAN Rx 中断进入时会设置"消息 RAM 访问失败位"、因为 MRAF 中断未启用、但在消息接收崩溃时仍会设置该位。 但我只看到了在第二条消息的新消息中断被触发时、MRAF 位被置位的情况。

    由于我也激活了 MRAF 中断、因此当第一条消息崩溃时、也会触发包含 MRAF 标志的中断。 每个中断标志现在被正确地分配给接收到的相应的 CAN 消息。