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.

[参考译文] TMS320F280025C:CMPSS CTRIPL 假正极触发器?

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

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1075957/tms320f280025c-cmpss-ctripl-false-positive-trigger

部件号:TMS320F280025C
“线程:C2000WARE”中讨论的其它部件

您好,

我注意到我在 XbarRegs.XBARFLG1中的所有 CMPSX CTRIPL 标志都是真的,我认为它们应该是假的。

这是我设置 CMPSS 的代码。 我正在反向比较低,我正在尝试使用 CTRIPL 来检查我的值是否低于 DACL。 我这样做对吗? (代码主要来自通用电机控制实验室,对 CMpss 功能没有修改)。

void HAL_setupCMPSSs(HAL_MTR_Handle handle) {
    HAL_MTR_Obj *obj = (HAL_MTR_Obj*) handle;

#if defined(MOTOR1_ISBLDC) || defined(MOTOR1_DCLINKSS)
    // Refer to the Table 9-2 in Chapter 9 of TMS320F28004x
    // Technical Reference Manual (SPRUI33B), to configure the ePWM X-Bar
#if defined(BSXL8323RS_REVA) || defined(BSXL8323RH_REVB)
    uint16_t cmpsaDACL = MTR1_CMPSS_DACL_VALUE;

    ASysCtl_selectCMPLPMux(MTR1_IDC_CMPLP_SEL, MTR1_IDC_CMPLP_MUX);

    // Enable CMPSS and configure the negative input signal to come from the DAC
    CMPSS_enableModule(obj->cmpssHandle[0]);

    // NEG signal from DAC for COMP-L
    CMPSS_configLowComparator(obj->cmpssHandle[0], CMPSS_INSRC_DAC);

    // Configure the output signals. Both CTRIPH/L and CTRIPOUTH/L will be fed by
    // the asynchronous comparator output.
    // Dig filter output ==> CTRIPL, Dig filter output ==> CTRIPOUTL
    CMPSS_configOutputsLow(obj->cmpssHandle[0],
                           CMPSS_TRIP_FILTER |
                           CMPSS_TRIPOUT_FILTER |
                           CMPSS_INV_INVERTED);

    // Configure digital filter. For this example, the maxiumum values will be
    // used for the clock prescale, sample window size, and threshold.
    // Initialize the filter logic and start filtering
    CMPSS_configFilterLow(obj->cmpssHandle[0], 32, 32, 30);
    CMPSS_initFilterLow(obj->cmpssHandle[0]);

    // Set up COMPHYSCTL register
    // COMP hysteresis set to 2x typical value
    CMPSS_setHysteresis(obj->cmpssHandle[0], 1);

    // Use VDDA as the reference for the DAC and set DAC value to midpoint for
    // arbitrary reference
    CMPSS_configDAC(obj->cmpssHandle[0],
               CMPSS_DACREF_VDDA | CMPSS_DACVAL_SYSCLK | CMPSS_DACSRC_SHDW);

    // Set DAC-L to allowed MAX -ve current
    CMPSS_setDACValueLow(obj->cmpssHandle[0], cmpsaDACL);

    // Clear any low comparator digital filter output latch
    CMPSS_clearFilterLatchLow(obj->cmpssHandle[0]);
#else
#error This board doesn't support single shunt
#endif  // BSXL8323RS_REVA || BSXL8323RH_REVB
#else   // !(MOTOR1_ISBLDC || MOTOR1_DCLINKSS)
    // Refer to the Table 9-2 in Chapter 9 of TMS320F28004x
    // Technical Reference Manual (SPRUI33B), to configure the ePWM X-Bar
    uint16_t cmpsaDACH = MTR1_CMPSS_DACH_VALUE;
    uint16_t cmpsaDACL = MTR1_CMPSS_DACL_VALUE;

    uint16_t cnt;

    if(handle == hal.mtrHandle[MTR_1]) {
        ASysCtl_selectCMPHPMux(MTR1_IU_CMPHP_SEL, MTR1_IU_CMPHP_MUX);
        ASysCtl_selectCMPLPMux(MTR1_IU_CMPLP_SEL, MTR1_IU_CMPLP_MUX);

        ASysCtl_selectCMPHPMux(MTR1_IV_CMPHP_SEL, MTR1_IV_CMPHP_MUX);
        ASysCtl_selectCMPLPMux(MTR1_IV_CMPLP_SEL, MTR1_IV_CMPLP_MUX);

//        ASysCtl_selectCMPHPMux(MTR1_IW_CMPHP_SEL, MTR1_IW_CMPHP_MUX);
//        ASysCtl_selectCMPLPMux(MTR1_IW_CMPLP_SEL, MTR1_IW_CMPLP_MUX);
    } else if(handle == hal.mtrHandle[MTR_2]) {
#ifdef MTR2
        cmpsaDACH = MTR2_CMPSS_DACH_VALUE;
        cmpsaDACL = MTR2_CMPSS_DACL_VALUE;

        ASysCtl_selectCMPHPMux(MTR2_IU_CMPHP_SEL, MTR2_IU_CMPHP_MUX);
        ASysCtl_selectCMPLPMux(MTR2_IU_CMPLP_SEL, MTR2_IU_CMPLP_MUX);

        ASysCtl_selectCMPHPMux(MTR2_IV_CMPHP_SEL, MTR2_IV_CMPHP_MUX);
        ASysCtl_selectCMPLPMux(MTR2_IV_CMPLP_SEL, MTR2_IV_CMPLP_MUX);

//        ASysCtl_selectCMPHPMux(MTR2_IW_CMPHP_SEL, MTR2_IW_CMPHP_MUX);
//        ASysCtl_selectCMPLPMux(MTR2_IW_CMPLP_SEL, MTR2_IW_CMPLP_MUX);
#endif
    }

    DEVICE_DELAY_US(500);

    for (cnt = 0; cnt < 2; cnt++) {

        // Set DAC-H to allowed MAX +ve current
        CMPSS_setDACValueHigh(obj->cmpssHandle[cnt], cmpsaDACH);

        // Set DAC-L to allowed MAX -ve current
        CMPSS_setDACValueLow(obj->cmpssHandle[cnt], cmpsaDACL);

        // NEG signal from DAC for COMP-H
        CMPSS_configHighComparator(obj->cmpssHandle[cnt], CMPSS_INSRC_DAC);

        // NEG signal from DAC for COMP-L
        CMPSS_configLowComparator(obj->cmpssHandle[cnt], CMPSS_INSRC_DAC | CMPSS_INV_INVERTED); //CMPSS_INV_INVERTED

        // Enable CMPSS and configure the negative input signal to come from the DAC
        CMPSS_enableModule(obj->cmpssHandle[cnt]);

        // Configure digital filter. For this example, the maxiumum values will be
        // used for the clock prescale, sample window size, and threshold.
        CMPSS_configFilterHigh(obj->cmpssHandle[cnt], 32, 32, 30);
        CMPSS_initFilterHigh(obj->cmpssHandle[cnt]);

        // Initialize the filter logic and start filtering
        CMPSS_configFilterLow(obj->cmpssHandle[cnt], 32, 32, 30);
        CMPSS_initFilterLow(obj->cmpssHandle[cnt]);

        // Configure the output signals. Both CTRIPH and CTRIPOUTH will be fed by
        // the asynchronous comparator output.
        // Dig filter output ==> CTRIPH, Dig filter output ==> CTRIPOUTH
        CMPSS_configOutputsHigh(obj->cmpssHandle[cnt], CMPSS_TRIP_FILTER); // | CMPSS_TRIPOUT_FILTER

        // Dig filter output ==> CTRIPL, Dig filter output ==> CTRIPOUTL
        CMPSS_configOutputsLow(obj->cmpssHandle[cnt], CMPSS_TRIP_FILTER);

        // Set up COMPHYSCTL register
        CMPSS_setHysteresis(obj->cmpssHandle[cnt], 2);

        // Use VDDA as the reference for the DAC and set DAC value to midpoint for
        // arbitrary reference
        CMPSS_configDAC(obj->cmpssHandle[cnt], CMPSS_DACREF_VDDA | CMPSS_DACVAL_SYSCLK | CMPSS_DACSRC_SHDW);

        // Clear any high comparator digital filter output latch
        CMPSS_clearFilterLatchHigh(obj->cmpssHandle[cnt]);

        // Clear any low comparator digital filter output latch
        CMPSS_clearFilterLatchLow(obj->cmpssHandle[cnt]);

    }

#endif  // !(MOTOR1_ISBLDC || MOTOR1_DCLINKSS)

    return;
} // end of HAL_setupCMPSSs() function

我认为 ADC 值应该与其当前的 DACH 和 DACL 值进行比较:

用于配置 ADC 和 CMpss 的值:

#define MTR1_IU_ADCRESLT        MTR1_IU_ADCRES_BASE + ADC_O_RESULT1     // ADCA-A11*/C0-SOC1
#define MTR1_IV_ADCRESLT        MTR1_IV_ADCRES_BASE + ADC_O_RESULT1     // ADCC-A14/C4* -SOC1

#define MTR2_IU_ADCRESLT        MTR2_IU_ADCRES_BASE + ADC_O_RESULT5     // ADCA-A10/C10*-SOC2
#define MTR2_IV_ADCRESLT        MTR2_IV_ADCRES_BASE + ADC_O_RESULT5     // ADCC-A9*/C8  -SOC3

// CMPSS
#define MTR1_IU_CMPHP_SEL       ASYSCTL_CMPHPMUX_SELECT_1    // CMPSS1-A11
#define MTR1_IU_CMPLP_SEL       ASYSCTL_CMPLPMUX_SELECT_1    // CMPSS1-A11, N/A

#define MTR1_IV_CMPHP_SEL       ASYSCTL_CMPHPMUX_SELECT_3    // CMPSS3-C4
#define MTR1_IV_CMPLP_SEL       ASYSCTL_CMPLPMUX_SELECT_3    // CMPSS3-C4

#define MTR1_IU_CMPHP_MUX       1                            // CMPSS1-A11
#define MTR1_IU_CMPLP_MUX       1                            // CMPSS1-A11

#define MTR1_IV_CMPHP_MUX       4                            // CMPSS3-C4
#define MTR1_IV_CMPLP_MUX       4                            // CMPSS3-C4

#define MTR1_CMPSS_DACH_VALUE   2048+1024+512
#define MTR1_CMPSS_DACL_VALUE   2048-1024-512

#define MTR2_IU_CMPHP_SEL       ASYSCTL_CMPHPMUX_SELECT_2    // CMPSS2-C10
#define MTR2_IU_CMPLP_SEL       ASYSCTL_CMPLPMUX_SELECT_2    // CMPSS2-C10, N/A

#define MTR2_IV_CMPHP_SEL       ASYSCTL_CMPHPMUX_SELECT_4    // CMPSS4-A9
#define MTR2_IV_CMPLP_SEL       ASYSCTL_CMPLPMUX_SELECT_4    // CMPSS4-A9

#define MTR2_IU_CMPHP_MUX       3                            // CMPSS2-C10
#define MTR2_IU_CMPLP_MUX       3                            // CMPSS2-C10

#define MTR2_IV_CMPHP_MUX       0                            // CMPSS4-A9
#define MTR2_IV_CMPLP_MUX       0                            // CMPSS4-A9

#define MTR2_CMPSS_DACH_VALUE   2048+1024+512
#define MTR2_CMPSS_DACL_VALUE   2048-1024-512

谢谢,

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

    我是否 正确解释了 XbarRegs.XBARFLG1? 我假设寄存器中的断路值会告诉您这些 ePWM X 条输入是否已跳闸,对吗? 我还假设这些值等同于反转后数字滤波器(在我的情况下)从 CMpss 模块输出的值。

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

    你好,莎莎,

    是的,您的理解是正确的。 XBARFLG1指示 ePWM X 条或输出 X 条的输入是否跳闸。 由于在压缩器上启用了反转,并且正输入上的信号小于 DACL,因此在用于压缩器的 XBARFLG1中看到的跳闸高状态是有意义的。 如果您有更多问题,请告诉我们。

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

    你好,弗兰克,

    感谢你的回复。 我想我一定会产生误解,我以为我已经将 ADC 输入设置为 compl 的正输入,而 compl 的正输入大于 DACL? 因此,反向 DACL 输出不应该是假的?

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

    莎莎,

    [引用 userid="509967" url="~/support/icros/c2000微控制器-组/CC2000 /f/c2000微控制器-论坛/1075957/tms320f280025c-cmpsss-ctrip-false-positive 触发器/3982956#3982956">感谢您的回复。 我想我一定会产生误解,我以为我已经将 ADC 输入设置为 compl 的正输入,而 compl 的正输入大于 DACL? 因此,反向 DACL 输出不应该是假的?

    没错。 如果启用了反转并且正输入大于 DACL,则输出应为0。 您是否尝试清除 XBARFLG1以查看它是否仍设置为1? 因为在配置过程中,当正输入小于 DACL 时,它可能被设置为1。

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

    我尝试按照您的建议,通过手动设置 XBARCLR1中的相应位来清除 XBARFLG1,但它是有效的。 这些旗帜如预期的那样是假的。 谢谢!

    配置 CMPSSS 以避免假触发器时,是否应遵循操作顺序? 或者,在 HAL_setupCMPS()结束时手动清除它们是否是确保正常功能的唯一方法?

    是否有比使用 XBARCLR1更好的清除方法? 通用电机控制实验室代码是否提供了此功能? 我看到一个名为“CMPSS_clearFilterLatchLow()”的函数,但这似乎不是我需要的。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="509967" url="~/support/icls/c2000-icler-group/c2f/c2000微控制器-forum/1075957/tms320f280025c-cmpsss-ctrip-false-positive 触发器/3983355#3983355]I 尝试清除 XBARG1,并通过手动设置相应的 FLARR1位。 这些旗帜如预期的那样是假的。 谢谢![/引用]

    听得好。

    [引用 userid="509967" url="~/support/icros/c2000微控制器-组/CC2000 /f/c2000微控制器-论坛/1075957/tms320f280025c-cmpsss-ctrip-false-positive 触发器/3983355#3983355]I 是否应该遵循操作顺序来配置错误的 CMPSS 触发器? 或者,在 HAL_setupCMPSSS()结束时手动清除它们是否是确保功能正常的唯一方法?

    通常,您需要在所有配置代码完成后以及应用程序代码开始运行之前清除所有标志。

    [引用 userid="509967" url="~/support/icros/c2000微控制器-组/CC2000 /f/c2000微控制器-论坛/1075957/tms320f280025c-cmps-ctrip-false-positive 触发器/3983355#3983355]\n 是否有比使用 CLXBR1更好的方法来清除它们? 通用电机控制实验室代码是否提供了此功能? 我看到一个名为“CMPSS_clearFilterLatchLow()”的函数,但这似乎不是我需要的。

    我想你可能会在这里感到有些困惑。 XBARFLG 仅对调试非常有用。 此外,它在应用程序中没有任何用处。 基本上,我的意思是,你关心的是,CMpss 在一天结束时跳过 ePWM,而不是在设置 XBARFLG 时跳过。 “CMPSS_clearFilterLatchLow()”函数清除了 COMPxSTS 锁存,该锁存指示是否已设置 CMPSSS 中的锁存。 您是否已确认 ePWM 正按预期从 CMPSs 跳闸?

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

    好的。 我所有的 CmpssXRegs.COMPSTS 都是0,所以我认为这是好的,并且是有效的。  具有讽刺意味的是,用于调试的寄存器导致了我的困惑,但我现在看到,这些寄存器与我的重置代码没有连接,因此它们不会始终显示真实状态。 感谢您的澄清。

    我 的 ePWM 未跳闸。 在测试时,我可以看到 COMPSTS 按预期更改为 true,但 PWM 保持启用状态。 我可以在 EPwmXbarRegs 中看到 MUX 已正确配置和启用。 我可以在 EPwmXRegs.TZFLG DCAEVT1和 DCBEVT1中看到结果,但 PWM 仍在运行。

    我猜我没有正确设置电机故障。 我在这里使用通用电机控制实验室代码,我注意到 DCXEVT1没有 setTripZoneAction,所以我补充了这一点。 我是否错过了其他东西?

    EPWM_enableTripZoneSignals(obj->pwmHandle[cnt], tzOSTSet);
    
    EPWM_enableTripZoneSignals(obj->pwmHandle[cnt], EPWM_TZ_SIGNAL_CBC6);
    
    //enable DC TRIP combinational input
    EPWM_enableDigitalCompareTripCombinationInput(obj->pwmHandle[cnt], dcTripSet, EPWM_DC_TYPE_DCAH);
    
    EPWM_enableDigitalCompareTripCombinationInput(obj->pwmHandle[cnt], dcTripSet, EPWM_DC_TYPE_DCBH);
    
    // Trigger event when DCAH is High
    EPWM_setTripZoneDigitalCompareEventCondition(obj->pwmHandle[cnt], EPWM_TZ_DC_OUTPUT_A1,
                                                 EPWM_TZ_EVENT_DCXH_HIGH);
    
    // Trigger event when DCBH is High
    EPWM_setTripZoneDigitalCompareEventCondition(obj->pwmHandle[cnt], EPWM_TZ_DC_OUTPUT_B1,
                                                 EPWM_TZ_EVENT_DCXL_HIGH);
    
    // Configure the DCA path to be un-filtered and asynchronous
    EPWM_setDigitalCompareEventSource(obj->pwmHandle[cnt], EPWM_DC_MODULE_A, EPWM_DC_EVENT_1,
                                      EPWM_DC_EVENT_SOURCE_FILT_SIGNAL);
    
    // Configure the DCB path to be un-filtered and asynchronous
    EPWM_setDigitalCompareEventSource(obj->pwmHandle[cnt], EPWM_DC_MODULE_B, EPWM_DC_EVENT_1,
                                      EPWM_DC_EVENT_SOURCE_FILT_SIGNAL);
    
    EPWM_setDigitalCompareEventSyncMode(obj->pwmHandle[cnt], EPWM_DC_MODULE_A, EPWM_DC_EVENT_1,
                                        EPWM_DC_EVENT_INPUT_NOT_SYNCED);
    
    EPWM_setDigitalCompareEventSyncMode(obj->pwmHandle[cnt], EPWM_DC_MODULE_B, EPWM_DC_EVENT_1,
                                        EPWM_DC_EVENT_INPUT_NOT_SYNCED);
    
    // Enable DCA as OST
    EPWM_enableTripZoneSignals(obj->pwmHandle[cnt], EPWM_TZ_SIGNAL_DCAEVT1);
    
    // Enable DCB as OST
    EPWM_enableTripZoneSignals(obj->pwmHandle[cnt], EPWM_TZ_SIGNAL_DCBEVT1);
    
    // What do we want the OST/CBC events to do?
    // TZA events can force EPWMxA
    // TZB events can force EPWMxB
    EPWM_setTripZoneAction(obj->pwmHandle[cnt], EPWM_TZ_ACTION_EVENT_TZA, EPWM_TZ_ACTION_LOW);
    
    EPWM_setTripZoneAction(obj->pwmHandle[cnt], EPWM_TZ_ACTION_EVENT_TZB, EPWM_TZ_ACTION_LOW);
    
    EPWM_setTripZoneAction(obj->pwmHandle[cnt], EPWM_TZ_ACTION_EVENT_DCAEVT1, EPWM_TZ_ACTION_LOW);
    
    EPWM_setTripZoneAction(obj->pwmHandle[cnt], EPWM_TZ_ACTION_EVENT_DCBEVT1, EPWM_TZ_ACTION_LOW);

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

    我快速浏览了代码,但没有看到 ePWM Xbar 配置代码。 实际上,我们有一个正在运行的 C2000Ware 示例“C2000Ware_version\driverlib\f28002x\examples\cmps\cmps_ex1_asynch.c”,该示例使用 CMPSS 跳闸 ePWM,并将跳闸路由至输出 Xbar。

    请将该示例与您的进行比较,以查看代码中缺少的内容。 让我们知道您的发现。

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

    啊,对不起,我把这个代码遗漏了,我有它:

    // Configure TRIP using the ePWM X-BAR
    XBAR_setEPWMMuxConfig(MTR1_XBAR_TRIP, MTR1_IU_XBAR_EPWM_MUX);
    XBAR_setEPWMMuxConfig(MTR1_XBAR_TRIP, MTR1_IV_XBAR_EPWM_MUX);
    
    // Disable all the mux first
    XBAR_disableEPWMMux(MTR1_XBAR_TRIP, 0xFFFF);
    
    // Enable Mux to generate TRIP
    XBAR_enableEPWMMux(MTR1_XBAR_TRIP, MTR1_IU_XBAR_MUX | MTR1_IV_XBAR_MUX);
    
    // Set motor 1 DC Trip setting
    dcTripSet = MTR1_DCTRIPIN;

    定义:

    #define MTR1_IU_XBAR_EPWM_MUX   XBAR_EPWM_MUX00_CMPSS1_CTRIPH_OR_L       // CMPSS1-HP
    #define MTR1_IV_XBAR_EPWM_MUX   XBAR_EPWM_MUX04_CMPSS3_CTRIPH_OR_L  // CMPSS3-HP&LP
    
    #define MTR1_IU_XBAR_MUX        XBAR_MUX00          // CMPSS1-HP
    #define MTR1_IV_XBAR_MUX        XBAR_MUX04          // CMPSS3-HP&LP
    
    #define MTR1_XBAR_TRIP          XBAR_TRIP7
    #define MTR1_DCTRIPIN           EPWM_DC_COMBINATIONAL_TRIPIN7

    我只看到了您建议的示例中的一个真正区别(谢谢),即事件源是原始的,而不是过滤器。 我将 我的 setDigitalCompareEventSource 更改为原始信号,而不是从实验代码过滤的信号,但过滤的信号甚至没有设置。

    我确实看到它现在禁用了 PWM,并在 EPwmXRegs.TZFLG 中触发了标志,但当我期望它时,它不会被禁用,因为 CmpssXRegs.COMPSTS 都是假的*脸手掌*。 我尝试用 EPwmXRegs.TZCLR 清除它,但似乎没有任何效果。

     有什么想法吗?

    以下是我在调试过程中查看的一些寄存器:

    我不知道为什么 DCBEVT1跳闸,特别是因为 DCAEVT1没有跳闸,而且它们的配置基本相同(我认为)。

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

    我发现了这个问题,在  setTripZoneDigitalCompareEventCondition()中,我使用 ePWM_TZ_EVENT_DCXL_HIGH 作为 B1而不是 ePWM_TZ_EVENT_DCXH_HIGH。

    它现在正在工作,感谢他们的帮助。

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

    你好,莎莎,

    很高兴听到这个代码正在运行! 如果出现更多问题,请告诉我们。