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.

[参考译文] TMDSCNCD2.8335万:采用Matlab Coder的采样时间ADC

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1097265/tmdscncd28335-sampling-time-adc-with-matlab-coder

部件号:TMDSCNCD2.8335万

大家好,

我是代表客户发布这一信息的。 你好!  

这里是:

我正在尝试使用Simulink编码器对F2.8335万 2.2 controlCARD进行编程。 我尝试实施ADC,现在我正在努力设置正确的采样时间。

出现的问题是,当我将采样时间设置为小于2us时,该程序似乎不再在控制器上工作。 代码本身似乎很好,因为它仍然可以编译。  

我尝试附加Simulink文件,但操作时遇到错误,因此最后插入了该文件的图像。

我已将其降低为ADC的测试环境,并在以后添加了RMS。 运行此程序后,我能够测量数字输出并确保ADC正常工作。 ADC连接到频率高达100kHz的方波发生器。 如前所述,如果我将ADC的采样时间减少到1us,输出将保持为零,并且不会打开和关闭。

我还尝试将采样时间设置为-1,根据MATLAB将其设置为继承时间。

我遵循了Matlab支持问题中提到的解决方案,但没有帮助。

https://ch.mathworks.com/matlabcentral/answers/37.8006万-tunability-of-sample-time-in-code-embedded-coder

在2.8335万的数据表中提到ADC的采样时间可以达到某些GHz,因此我不太确定是什么导致了我的错误。

我希望我没有忘记任何重要的东西来为您树立形象。

提前感谢。

此致,

乔纳森

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

    此器件上的ADC具有12.5MSPS (80ns采样速率)的能力。  是否可以根据上述结构图发布Simulink生成的C代码?  这里有几个因素,既包括设置为ADC的采样和保持窗口,也包括Simulink为采样信号而设置的触发源。  我认为,我可以更容易地看到输出代码,准确地说出正在发生的事情。  也许客户可以在2us (工作中)和1us (不工作)发布代码。

    最佳,

    Matthew

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

    Matthew,您好!

    以下是客户的回应。

    提前感谢您的帮助。 我已经附上了采样时间2us和1us的代码。 我不确定主代码是否足够,所以我附上了整个导出代码,我希望这不是问题。

    我不知道这些附加信息是否有帮助:
    两个独立的GPIO驱动板上的两个LED,其应以0.5Hz的频率闪烁。 如果我将采样时间设置为20us,我可以看到它们闪烁。 将采样时间减少到2us,展位LED保持亮起(我测量到切换速度不快)。

    此致,

    乔纳森

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

    乔纳森
    客户是否发送了代码以附加到开机自检?  我看不到附件。

    最佳,

    Matthew

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

    你好Matthew

    非常感谢您的帮助,并对通信带来的不便深表歉意。 我在获得适当的论坛访问权限时遇到了问题。

    我不知道主代码是否足以让您说出一些信息,但我将从这开始。 否则,我现在就在身边了。

    此致,

    Marius

    具有2us采样时间的工作代码:

    /*
     * Academic License - for use in teaching, academic research, and meeting
     * course requirements at degree granting institutions only.  Not for
     * government, commercial, or other organizational use.
     *
     * File: Test_Sampling_Time.c
     *
     * Code generated for Simulink model 'Test_Sampling_Time'.
     *
     * Model version                  : 1.2
     * Simulink Coder version         : 9.5 (R2021a) 14-Nov-2020
     * C/C++ source code generated on : Fri Apr 29 11:13:56 2022
     *
     * Target selection: ert.tlc
     * Embedded hardware selection: Texas Instruments->C2000
     * Code generation objectives: Unspecified
     * Validation result: Not run
     */
    
    #include "Test_Sampling_Time.h"
    #include "Test_Sampling_Time_private.h"
    
    /* Block signals (default storage) */
    B_Test_Sampling_Time_T Test_Sampling_Time_B;
    
    /* Block states (default storage) */
    DW_Test_Sampling_Time_T Test_Sampling_Time_DW;
    
    /* Real-time model */
    static RT_MODEL_Test_Sampling_Time_T Test_Sampling_Time_M_;
    RT_MODEL_Test_Sampling_Time_T *const Test_Sampling_Time_M =
      &Test_Sampling_Time_M_;
    static void rate_monotonic_scheduler(void);
    uint16_T MW_adcInitFlag = 0;
    
    /*
     * Set which subrates need to run this base step (base rate always runs).
     * This function must be called prior to calling the model step function
     * in order to "remember" which rates need to run this base step.  The
     * buffering of events allows for overlapping preemption.
     */
    void Test_Sampling_Time_SetEventsForThisBaseStep(boolean_T *eventFlags)
    {
      /* Task runs when its counter is zero, computed via rtmStepTask macro */
      eventFlags[1] = ((boolean_T)rtmStepTask(Test_Sampling_Time_M, 1));
    }
    
    /*
     *   This function updates active task flag for each subrate
     * and rate transition flags for tasks that exchange data.
     * The function assumes rate-monotonic multitasking scheduler.
     * The function must be called at model base rate so that
     * the generated code self-manages all its subrates and rate
     * transition flags.
     */
    static void rate_monotonic_scheduler(void)
    {
      /* Compute which subrates run during the next base time step.  Subrates
       * are an integer multiple of the base rate counter.  Therefore, the subtask
       * counter is reset when it reaches its limit (zero means run).
       */
      (Test_Sampling_Time_M->Timing.TaskCounters.TID[1])++;
      if ((Test_Sampling_Time_M->Timing.TaskCounters.TID[1]) > 499999) {/* Sample time: [1.0s, 0.0s] */
        Test_Sampling_Time_M->Timing.TaskCounters.TID[1] = 0;
      }
    }
    
    /* Model step function for TID0 */
    void Test_Sampling_Time_step0(void)    /* Sample time: [2.0E-6s, 0.0s] */
    {
      {                                    /* Sample time: [2.0E-6s, 0.0s] */
        rate_monotonic_scheduler();
      }
    
      /* S-Function (c280xadc): '<Root>/Current_Meassurement' */
      {
        AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;  /* Reset SEQ1 module*/
        AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;/*clear INT sequencer*/
        AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1;  /* Software Trigger*/
        while (AdcRegs.ADCST.bit.INT_SEQ1 == 0) {
        }                                  /*Wait for Sequencer INT bit to clear */
    
        asm(" RPT #11 || NOP");
        Test_Sampling_Time_B.Current_Meassurement = (AdcRegs.ADCRESULT0) >> 4;
      }
    
      /* Switch: '<Root>/Switch' incorporates:
       *  Constant: '<Root>/Constant2'
       *  Gain: '<Root>/Gain'
       *  Gain: '<Root>/Gain1'
       *  Sum: '<Root>/Sum'
       */
      if (Test_Sampling_Time_P.Gain1_Gain *
          Test_Sampling_Time_B.Current_Meassurement * Test_Sampling_Time_P.Gain_Gain
          - Test_Sampling_Time_P.Constant2_Value >
          Test_Sampling_Time_P.Switch_Threshold) {
        /* Switch: '<Root>/Switch' incorporates:
         *  Constant: '<Root>/Constant'
         */
        Test_Sampling_Time_B.Switch = Test_Sampling_Time_P.Constant_Value;
      } else {
        /* Switch: '<Root>/Switch' incorporates:
         *  Constant: '<Root>/Constant1'
         */
        Test_Sampling_Time_B.Switch = Test_Sampling_Time_P.Constant1_Value;
      }
    
      /* End of Switch: '<Root>/Switch' */
    
      /* S-Function (c280xgpio_do): '<Root>/GPIO 02' */
      {
        if (Test_Sampling_Time_B.Switch)
          GpioDataRegs.GPASET.bit.GPIO2 = 1;
        else
          GpioDataRegs.GPACLEAR.bit.GPIO2 = 1;
      }
    }
    
    /* Model step function for TID1 */
    void Test_Sampling_Time_step1(void)    /* Sample time: [1.0s, 0.0s] */
    {
      /* DiscretePulseGenerator: '<Root>/Pulse Generator1' */
      Test_Sampling_Time_B.PulseGenerator1 = (Test_Sampling_Time_DW.clockTickCounter
        < Test_Sampling_Time_P.PulseGenerator1_Duty) &&
        (Test_Sampling_Time_DW.clockTickCounter >= 0L) ?
        Test_Sampling_Time_P.PulseGenerator1_Amp : 0.0;
    
      /* DiscretePulseGenerator: '<Root>/Pulse Generator1' */
      if (Test_Sampling_Time_DW.clockTickCounter >=
          Test_Sampling_Time_P.PulseGenerator1_Period - 1.0) {
        Test_Sampling_Time_DW.clockTickCounter = 0L;
      } else {
        Test_Sampling_Time_DW.clockTickCounter++;
      }
    
      /* S-Function (c280xgpio_do): '<Root>/LED 1' */
      {
        if (Test_Sampling_Time_B.PulseGenerator1)
          GpioDataRegs.GPASET.bit.GPIO31 = 1;
        else
          GpioDataRegs.GPACLEAR.bit.GPIO31 = 1;
      }
    
      /* Logic: '<Root>/NOT' */
      Test_Sampling_Time_B.NOT = !(Test_Sampling_Time_B.PulseGenerator1 != 0.0);
    
      /* S-Function (c280xgpio_do): '<Root>/LED2' */
      {
        if (Test_Sampling_Time_B.NOT)
          GpioDataRegs.GPBSET.bit.GPIO34 = 1;
        else
          GpioDataRegs.GPBCLEAR.bit.GPIO34 = 1;
      }
    }
    
    /* Model initialize function */
    void Test_Sampling_Time_initialize(void)
    {
      /* Registration code */
    
      /* initialize real-time model */
      (void) memset((void *)Test_Sampling_Time_M, 0,
                    sizeof(RT_MODEL_Test_Sampling_Time_T));
    
      /* block I/O */
      (void) memset(((void *) &Test_Sampling_Time_B), 0,
                    sizeof(B_Test_Sampling_Time_T));
    
      /* states (dwork) */
      (void) memset((void *)&Test_Sampling_Time_DW, 0,
                    sizeof(DW_Test_Sampling_Time_T));
    
      /* Start for S-Function (c280xadc): '<Root>/Current_Meassurement' */
      if (MW_adcInitFlag == 0) {
        InitAdc();
        MW_adcInitFlag = 1;
      }
    
      config_ADC_A (0U, 0U, 0U, 0U, 0U);
    
      /* Start for S-Function (c280xgpio_do): '<Root>/GPIO 02' */
      EALLOW;
      GpioCtrlRegs.GPAMUX1.all &= 0xFFFFFFCF;
      GpioCtrlRegs.GPADIR.all |= 0x4;
      EDIS;
    
      /* Start for DiscretePulseGenerator: '<Root>/Pulse Generator1' */
      Test_Sampling_Time_DW.clockTickCounter = 0L;
    
      /* Start for S-Function (c280xgpio_do): '<Root>/LED 1' */
      EALLOW;
      GpioCtrlRegs.GPAMUX2.all &= 0x3FFFFFFF;
      GpioCtrlRegs.GPADIR.all |= 0x80000000;
      EDIS;
    
      /* Start for S-Function (c280xgpio_do): '<Root>/LED2' */
      EALLOW;
      GpioCtrlRegs.GPBMUX1.all &= 0xFFFFFFCF;
      GpioCtrlRegs.GPBDIR.all |= 0x4;
      EDIS;
    }
    
    /* Model terminate function */
    void Test_Sampling_Time_terminate(void)
    {
      /* (no terminate code required) */
    }
    
    /*
     * File trailer for generated code.
     *
     * [EOF]
     */
    

    采样时间为1us的非工作代码:

    /*
     *
     * File: Test_Sampling_Time.c
     *
     * Code generated for Simulink model 'Test_Sampling_Time'.
     *
     * Model version                  : 1.2
     * Simulink Coder version         : 9.5 (R2021a) 14-Nov-2020
     * C/C++ source code generated on : Fri Apr 29 11:12:24 2022
     *
     * Target selection: ert.tlc
     * Embedded hardware selection: Texas Instruments->C2000
     * Code generation objectives: Unspecified
     * Validation result: Not run
     */
    
    #include "Test_Sampling_Time.h"
    #include "Test_Sampling_Time_private.h"
    
    /* Block signals (default storage) */
    B_Test_Sampling_Time_T Test_Sampling_Time_B;
    
    /* Block states (default storage) */
    DW_Test_Sampling_Time_T Test_Sampling_Time_DW;
    
    /* Real-time model */
    static RT_MODEL_Test_Sampling_Time_T Test_Sampling_Time_M_;
    RT_MODEL_Test_Sampling_Time_T *const Test_Sampling_Time_M =
      &Test_Sampling_Time_M_;
    static void rate_monotonic_scheduler(void);
    uint16_T MW_adcInitFlag = 0;
    
    /*
     * Set which subrates need to run this base step (base rate always runs).
     * This function must be called prior to calling the model step function
     * in order to "remember" which rates need to run this base step.  The
     * buffering of events allows for overlapping preemption.
     */
    void Test_Sampling_Time_SetEventsForThisBaseStep(boolean_T *eventFlags)
    {
      /* Task runs when its counter is zero, computed via rtmStepTask macro */
      eventFlags[1] = ((boolean_T)rtmStepTask(Test_Sampling_Time_M, 1));
    }
    
    /*
     *   This function updates active task flag for each subrate
     * and rate transition flags for tasks that exchange data.
     * The function assumes rate-monotonic multitasking scheduler.
     * The function must be called at model base rate so that
     * the generated code self-manages all its subrates and rate
     * transition flags.
     */
    static void rate_monotonic_scheduler(void)
    {
      /* Compute which subrates run during the next base time step.  Subrates
       * are an integer multiple of the base rate counter.  Therefore, the subtask
       * counter is reset when it reaches its limit (zero means run).
       */
      (Test_Sampling_Time_M->Timing.TaskCounters.TID[1])++;
      if ((Test_Sampling_Time_M->Timing.TaskCounters.TID[1]) > 999999) {/* Sample time: [1.0s, 0.0s] */
        Test_Sampling_Time_M->Timing.TaskCounters.TID[1] = 0;
      }
    }
    
    /* Model step function for TID0 */
    void Test_Sampling_Time_step0(void)    /* Sample time: [1.0E-6s, 0.0s] */
    {
      {                                    /* Sample time: [1.0E-6s, 0.0s] */
        rate_monotonic_scheduler();
      }
    
      /* S-Function (c280xadc): '<Root>/Current_Meassurement' */
      {
        AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;  /* Reset SEQ1 module*/
        AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;/*clear INT sequencer*/
        AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1;  /* Software Trigger*/
        while (AdcRegs.ADCST.bit.INT_SEQ1 == 0) {
        }                                  /*Wait for Sequencer INT bit to clear */
    
        asm(" RPT #11 || NOP");
        Test_Sampling_Time_B.Current_Meassurement = (AdcRegs.ADCRESULT0) >> 4;
      }
    
      /* Switch: '<Root>/Switch' incorporates:
       *  Constant: '<Root>/Constant2'
       *  Gain: '<Root>/Gain'
       *  Gain: '<Root>/Gain1'
       *  Sum: '<Root>/Sum'
       */
      if (Test_Sampling_Time_P.Gain1_Gain *
          Test_Sampling_Time_B.Current_Meassurement * Test_Sampling_Time_P.Gain_Gain
          - Test_Sampling_Time_P.Constant2_Value >
          Test_Sampling_Time_P.Switch_Threshold) {
        /* Switch: '<Root>/Switch' incorporates:
         *  Constant: '<Root>/Constant'
         */
        Test_Sampling_Time_B.Switch = Test_Sampling_Time_P.Constant_Value;
      } else {
        /* Switch: '<Root>/Switch' incorporates:
         *  Constant: '<Root>/Constant1'
         */
        Test_Sampling_Time_B.Switch = Test_Sampling_Time_P.Constant1_Value;
      }
    
      /* End of Switch: '<Root>/Switch' */
    
      /* S-Function (c280xgpio_do): '<Root>/GPIO 02' */
      {
        if (Test_Sampling_Time_B.Switch)
          GpioDataRegs.GPASET.bit.GPIO2 = 1;
        else
          GpioDataRegs.GPACLEAR.bit.GPIO2 = 1;
      }
    }
    
    /* Model step function for TID1 */
    void Test_Sampling_Time_step1(void)    /* Sample time: [1.0s, 0.0s] */
    {
      /* DiscretePulseGenerator: '<Root>/Pulse Generator1' */
      Test_Sampling_Time_B.PulseGenerator1 = (Test_Sampling_Time_DW.clockTickCounter
        < Test_Sampling_Time_P.PulseGenerator1_Duty) &&
        (Test_Sampling_Time_DW.clockTickCounter >= 0L) ?
        Test_Sampling_Time_P.PulseGenerator1_Amp : 0.0;
    
      /* DiscretePulseGenerator: '<Root>/Pulse Generator1' */
      if (Test_Sampling_Time_DW.clockTickCounter >=
          Test_Sampling_Time_P.PulseGenerator1_Period - 1.0) {
        Test_Sampling_Time_DW.clockTickCounter = 0L;
      } else {
        Test_Sampling_Time_DW.clockTickCounter++;
      }
    
      /* S-Function (c280xgpio_do): '<Root>/LED 1' */
      {
        if (Test_Sampling_Time_B.PulseGenerator1)
          GpioDataRegs.GPASET.bit.GPIO31 = 1;
        else
          GpioDataRegs.GPACLEAR.bit.GPIO31 = 1;
      }
    
      /* Logic: '<Root>/NOT' */
      Test_Sampling_Time_B.NOT = !(Test_Sampling_Time_B.PulseGenerator1 != 0.0);
    
      /* S-Function (c280xgpio_do): '<Root>/LED2' */
      {
        if (Test_Sampling_Time_B.NOT)
          GpioDataRegs.GPBSET.bit.GPIO34 = 1;
        else
          GpioDataRegs.GPBCLEAR.bit.GPIO34 = 1;
      }
    }
    
    /* Model initialize function */
    void Test_Sampling_Time_initialize(void)
    {
      /* Registration code */
    
      /* initialize real-time model */
      (void) memset((void *)Test_Sampling_Time_M, 0,
                    sizeof(RT_MODEL_Test_Sampling_Time_T));
    
      /* block I/O */
      (void) memset(((void *) &Test_Sampling_Time_B), 0,
                    sizeof(B_Test_Sampling_Time_T));
    
      /* states (dwork) */
      (void) memset((void *)&Test_Sampling_Time_DW, 0,
                    sizeof(DW_Test_Sampling_Time_T));
    
      /* Start for S-Function (c280xadc): '<Root>/Current_Meassurement' */
      if (MW_adcInitFlag == 0) {
        InitAdc();
        MW_adcInitFlag = 1;
      }
    
      config_ADC_A (0U, 0U, 0U, 0U, 0U);
    
      /* Start for S-Function (c280xgpio_do): '<Root>/GPIO 02' */
      EALLOW;
      GpioCtrlRegs.GPAMUX1.all &= 0xFFFFFFCF;
      GpioCtrlRegs.GPADIR.all |= 0x4;
      EDIS;
    
      /* Start for DiscretePulseGenerator: '<Root>/Pulse Generator1' */
      Test_Sampling_Time_DW.clockTickCounter = 0L;
    
      /* Start for S-Function (c280xgpio_do): '<Root>/LED 1' */
      EALLOW;
      GpioCtrlRegs.GPAMUX2.all &= 0x3FFFFFFF;
      GpioCtrlRegs.GPADIR.all |= 0x80000000;
      EDIS;
    
      /* Start for S-Function (c280xgpio_do): '<Root>/LED2' */
      EALLOW;
      GpioCtrlRegs.GPBMUX1.all &= 0xFFFFFFCF;
      GpioCtrlRegs.GPBDIR.all |= 0x4;
      EDIS;
    }
    
    /* Model terminate function */
    void Test_Sampling_Time_terminate(void)
    {
      /* (no terminate code required) */
    }
    
    /*
     * File trailer for generated code.
     *
     * [EOF]
     */

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

    感谢您发布此信息,函数RATE_MONOTONIC_scheduler中的某些内容对我没有意义,在2us版本中,循环计数器为50万。而对于1us,计数器为100万。  我认为,1我们应该是2我们的一半,而不是两倍。  这两个数字都大于16位,所以我认为不存在铸造问题。

    我会看看MW团队是否可以提供一些见解,了解计时器功能到底在发生什么,以及它最终如何调用ADC SOC。

    最佳,

    Matthew

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

    你好,Jonathan:

    您能否分享模型以帮助我们重现问题?

    此致,

    Ram Alla | MathWorks

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

    e2e.ti.com/.../Test_5F00_Sampling_5F00_Time.zip

    尊敬的RAM:感谢您的回复。

    感谢您的回复,我是Jonathan发布此问题的客户。 我已将模型附加到此信息。

    此致,

    Marius