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.

[参考译文] CCS/LAUNCHXL-F28377S:ADC_SAMPLING_FREQ

Guru**** 2540450 points
Other Parts Discussed in Thread: CONTROLSUITE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/593867/ccs-launchxl-f28377s-adc_sampling_freq

器件型号:LAUNCHXL-F28377S

工具/软件:Code Composer Studio

您好!

我对“2837x_rfft_adc_RT”有疑问:

我需要将我的模数采样率从100ksps 提高到 500ksps、

在"example_setup.h"中更改以下参数就足够了?

#define ADC_SAMPLING_FREQ   100000.0L

或项目中的其他更改是必要的。

感谢你的帮助。

此致、

Amin

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

    我写信告诉您、C2000团队成员已被分配到此帖子、应该很快回答。

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

    看起来、ADC_SAMPLING_FREQ 只调整 main()中的计算。 它不会影响将 examples_setup.c 中的 ePWM 配置为以更快的速率实际触发转换的代码。

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

    尊敬的惠特尼:

    感谢你的答复。 如何将其更改为500kSPS?

    此致、

    Amin

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    example_setup.h 中的 EPWM1_PERIOD 和 EPWM1_DUTY 周期宏控制触发转换的 EPWM。 如果您将它们除以5、则应该这样做。

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

    尊敬的惠特尼:

    在此项目(2837x_rfft_adc_RT)中、有一个方波发生器、我想控制每个脉冲的起始点和停止点、并同时在其他 ADC 通道中对模拟信号进行采样。

    如何生成一定数量的方波、例如1个方波? 我需要在项目中具有每个方波的“开始”和“结束”点,并从每个方波的起点到终点运行 ADC PIN_A0。

    换句话说,如果我们假定“A”是每个脉冲周期的起始点,每个周期的结束点是“B”点, 那么:  

    ADC 的起点=方波开始处(A 点)

    ADC 的终点=方波的终点(B 点)

    如何同步 ADC 通道和方波发生器?

    谢谢、此致、

    Amin

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

    尊敬的 Amin:

    您正在使用的示例已将 PWM 配置为同时启动时钟。 这就是 FPU_startEPWM()中设置 TBCLKSYNC 位的情况。 然后、如果您将两个 PWM 模块配置为具有相同的周期和分频器(请参阅 TBPRD 和 TBCTL 寄存器)、它们也应该具有相同的端点。 你试过这个吗?

    惠特尼

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    ADC 和 PWM 的频率不相等。
    PWM 频率 = 200Hz
    ADC 采样频率 = 500kSPS
    请在项目中向我展示。 感谢你的帮助。
    Amin
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在 examples_setup.h 中 周期和占空比的#define 值是多少?

    此外、请确保在项目的编译器设置中的预定义符号中包含_LAUNCHXL_F28377S。 您需要执行此操作,以确保 InitSysCtrl()正在将系统时钟配置为以预期的200MHz 运行。

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

    在 examples_setup.h 中:

    1
    2.
    3.
    4.
    5.
    6.
    7.
    8.
    9.
    10.
    11.
    #define CPU_FRQ_200MHZ          1
    #define ADC_SAMPLING_FREQ       100000.0L
    #define EPWM_CLK                100000000UL // EPWM_CLK starts off SYSCLK/2
    #define EPWM_CLKDIV             1           // TBCLK = SYSCLK/(2*2)
    #define EPWM_HSPCLKDIV          4           //       = SYSCLK/(2*2*8) or EPWM_CLK/(2*8)
    // desired freq 100KHz
    #define EPWM1_PERIOD            EPWM_CLK/(2*8*100000UL)
    #define EPWM1_DUTY_CYCLE        EPWM1_PERIOD/2UL
    // desired freq 10KHz
    #define EPWM2_PERIOD            (EPWM_CLK)/(2*8*10000UL)
    #define EPWM2_DUTY_CYCLE        EPWM2_PERIOD/2UL
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    该代码看起来像是将 PWM 设置为以100kHz 的频率运行。 您在哪里看到200Hz? 您在示波器上查看 PWM 信号时看到的是这种情况吗?

    惠特尼
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我看到使用示波器时为99.174KHz。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    好的、考虑到您向我展示的代码、这就是我所期望的。 因此、如果您希望以500kHz 的速率触发 ADC 转换、则只需在周期的#defines 中将100k 更改为500k、对吧?

    #define EPWM1_PERIOD ePWM_CLK/(2*8*500000UL)

    或者、我是否误解了您尝试做的事情?

    惠特尼
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    当我更改此行时:
    #define EPWM1_PERIOD EPWM_CLK/(2*8*500000UL)
    ADC 采样频率= 500kSPS、工作正常。
    但对于 PWM 发生器、时间
    #define EPWM2_PERIOD EPWM_CLK/(2*8*200UL)
    ,信号发生器不工作(200Hz 信号)
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我有一个电压控制振荡器、此振荡器具有单输入(连接到 launchpad-f28377的 PWM (200Hz))和单输出(连接到 ADC 引脚 A0、500kSPS)。 我需要从每个脉冲的起点到终点启动 PWM 和 ADC。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    创建了200Hz 脉冲生成。
    正常工作。
    我的问题是如何使用 ADC 设置每个脉冲的开始和停止(采样的开始和停止)?
    Amin
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    以下代码:结果(500kSPS ADC 和200Hz PWM)

    #define CPU_FRQ_200MHz 1
    #define ADC_SAMPLING_FREQ 500000.0L
    #define ePWM_CLK 100000000UL // ePWM_CLK 启动 SYSCLK/2
    #define ePWM_CLKDIV 1 // TBCLK = SYSCLK/(2*2)
    #define ePWM_HSPCLK/2 #define ePWM_CLK/2 = SYSCLQ/
    RELEV/ SYSCLQ2 / RELEVN
    2 = SYSCLQ2 / SYSCLQ2 / SYSCLQ2 / RELEVN 2 = SYSCLQ/ SYSCLQ2 / SYSCLQ/ RELEVN ePWM_CLK/(2*8*500000UL)
    #define EPWM1_DUTY 周期 EPWM1_PERIODE/2UL
    //所需频率10kHz
    #define EPWM2_PERIOD (ePWM_CLK)/(2*8*200UL)
    #define EPWM2_Duty_cycle EPWM2_PERIODE/2UL 



    Amin

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    原始2837x_rfft_adc_RT 示例已将 ADC 的 SOC0配置为由 ePWM1 SOCA 触发(ADCSOC0CTL.TRIGSEL = 5)。 它还将 ePWM 配置为在 TBCTR = CMPA (ETSEL.SOCASEL = 4)时生成 SOCA 信号。 这基本上意味着转换从 ePWM1A 信号的上升沿开始。

    我不确定"停止采样"是什么意思。 转换开始后、采样保持时间由 ADCSOC0CTL.ACQPS 确定、示例代码已将 ADCSOC0CTL.ACQPS 配置为15个 SYSCLK 周期。 我认为这是 F28377S 上进行12位转换所需的最短采样时间。 然后、将结果锁存到结果寄存器中并生成 ADC 中断需要多个周期。 如果需要详细信息、您可以查看 TRM 的 ADC 时序部分:

    www.ti.com/.../spruhm8

    实际采样窗口的末尾不是由 ePWM 决定的。 也许我不完全理解您要做什么...?

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

    Whitney、

    非常感谢你的帮助。

    我的目标是在下一个脉冲的上升沿到上升沿进行 ADC 采样。

    因为我需要将样本(ADC 引脚)对应于每个脉冲(由 PWM 生成)、

    如图所示、采样从每个脉冲的开始到下一个脉冲的开始(这并不是针对所有脉冲完成的)、然后在脉冲的下降沿分割样本。

    我不是说 STOP 函数(在发布"终点"之前说过)、我的目标只是找到每个脉冲上升沿的位置。

    谢谢、此致、

    Amin

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

    好的、我认为我理解。 您可以将 ePWM2配置为在 A CMPA 事件(配置中的上升沿)上触发中断。 controlSUITE 中的 ePWM_UP_AQ 示例演示了如何在需要示例时配置 PWM 中断。 这能满足您的需求吗?

    惠特尼

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

    尊敬的惠特尼:

    在该项目中、脉冲占空比发生了变化、但我不需要这种变化。 我将代码减少为脉冲发生器(ePWM2)。

    e2e.ti.com/.../2017_2D00_05_2D00_23_5F00_18_2D00_33_2D00_40.mp4

    //######################################################################################################################
    //
    ////文件:ePWM_UP_AQ_cpu01.c
    //
    标题:操作限定器模块-使用向上计数。
    //
    //! addtogroup cpu01_example_list
    //! 

    ePWM 操作限定符(ePWM_UP_AQ)

    //! //! 此示例将 ePWM1、ePWM2、ePWM3配置为生成 //! EPWMxA 和 //!上具有独立调制的波形 EPWMxB。 //! //! 比较值 CMPA 和 CMPB 在 ePWM 的 ISR 内进行修改。 //! //! 在本示例中、TB 计数器处于向上计数模式。 //! //! 查看 EPWM1A/B (PA0_GPIO0和 PA1_GPIO1)、EPWM2A/B (PA2_GPIO2和 PA3_GPIO3) //! 和 EPWM3A/B (PA4_GPIO4和 PA5_GPIO5)波形。 //! // //########################################################################################################################## //$TI 发行版:F2837xS 支持库 V210 $// $发行 日期:星期二11月1日15:35:23 CDT 2016 $// 版权所有:版权所有(C) 2014-2016德州仪器(TI)公司-// http://www.ti.com/ 保留所有权利$ //############################################################################################################ // //包含的文件 // #include "F28x_Project.h" // 定义 // #define EPWM2_TIMER_TBPRD 2000 //周期寄存器//////////////////// 2000 #define EPWM2_MAX_CMPA 1950 //1950 #define EPWM2_MIN_CMPA 50 #define EPWM2_MAX_CMPB 1950 //1950 #define EPWM2_MIN_CMPB 50 #define ePWM_CMP_UP 1 #define ePWM_CMP_DOWN 0 // // Globals // typedef struct { volatile struct ePWM_regs * EPwmRegHandle; uint16 ePWM_CMPA_DIRECTION; uint16 ePWM_CMPB_DIRECTION; UINT16 EPwmTimerIntCount; uint16 EPwmMaxCMPA; uint16 EPwmMinCMPA; UINT16 EPwmMaxCMPB; uint16 EPwmMinCMPB; }ePWM_INFO; ePWM_INFO epwm2_INFO; // 函数原型 // 空 InitEPwm2Example (void); __interrupt void epwm2_ISR (void); void update_compare (ePWM_info*); // Main // Main //(void)/步骤1 / void (void)。 初始化系统控制: // PLL、看门狗、启用外设时钟 //此示例函数位于 F2837xS_SYSCTRL.c 文件中。 // InitSysCtrl(); // //步骤2。 初始化 GPIO: //此示例函数位于 F2837xS_GPIO.c 文件中, //说明了如何将 GPIO 设置为其默认状态。 // // InitGpio (); // //启用 PWM2 // CpuSysRegs.PCLKCR2.bit.EPWM2=1; // 对于这种情况、只需初始化 ePWM1、ePWM2、ePWM3的 GPIO 引脚 //这些函数位于 F2837xS_ePWM.c 文件 // InitEPwm2Gpio(); //// 步骤3。 清除所有中断并初始化 PIE 矢量表: //禁用 CPU 中断 // Dint; // //将 PIE 控制寄存器初始化为默认状态。 //默认状态是禁用所有 PIE 中断并 清除标志//。 //此函数位于 F2837xS_PIECTRL.c 文件中。 // InitPieCtrl(); // 禁用 CPU 中断并清除所有 CPU 中断标志: // IER = 0x0000; IFR = 0x0000; // //初始化 PIE 矢量表,其中包含指向 shell 中断 //服务例程(service routines,ISR)的指针。 //这将填充整个表,即使在 本示例中未使用中断//也是如此。 这对于调试很有用。 //可以在 F2837xS_DefaultIsr.c 中找到 shell ISR 例程 //此函数可在 F2837xS_PieVect.c 中找到 // InitPieVectTable(); // //此示例中使用的中断被重新映射到 这个文件中的// ISR 函数。 // EALLOW;//这是写入 EALLOW 受保护寄存器所必需的 PieVectTable.EPWM2_INT =&epwm2_ISR; EDIS;//这是禁止写入 EALLOW 受保护寄存器所必需 的// //对于这个示例,只初始化 ePWM // EALLOW; CpuSysRegs.PCLKCR0.bit.TBCLKSYNC=0; EDIS; InitEPwm2Examples(); EALLOW; CpuSysRegs.PCLKCR0.bit.TBCLKSYNC=1; EDIS; //// 步骤4。 用户特定代码、启用中断: // 启用连接到 EPWM1-3 INT 的 CPU INT3: // IER |= M_INT3; // //在 PIE 中启用 ePWM INTn:组3中断1-3 // PieCtrlRegs.PIEIER3.bit.INTx2 = 1; // 启用全局中断和更高优先级的实时调试事件: // EINT;//启用全局中断 INTM ERTM;//启用全局实时中断 DBGM // //步骤5。 空闲循环。 只需坐下来循环(可选): // for (;;) { ASM (" NOP"); } } // // epwm2_ISR -用于更新比较值的 EPWM2 ISR // __interrupt void epwm2_ISR (void) { // //更新 CMPA 和 CMPB 值 // 更新比较(epwm2_info); // //清除此计时器的 INT 标志 // EPwm2Regs.ETCLR.bit.INT = 1; // //确认此中断以接收来自组3的更多中断 // PieCtrlRegs.PIEACK.all = PIEACK_Group3; } // InitEPwm2Example -初始化 EPWM2值 // 空 InitEPwm2Examples() { // //设置 TBCLK // EPwm2Regs.TBCTL.bit.CTRMODE = TB_EPWDMD 计数;//设置 TBPRD_EPwM2RPM2计数; //设置定时器周期 EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;//禁用相位加载 EPwm2Regs.TBPHS.bit.TBPHS = 0x0000; //相位为0 EPwm2Regs.TBCTR = 0x0000; //清除计数 器 EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV2;//时钟与 SYSCLKOUT EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV2; // 设置影子寄存器加载为零 // EPwm2Regs.TBCMDR.BIT.AMPC2.TL.BIT.AMCMDR.BIT.RC.TL.TL.RCMTL.RCMTL.RCMTL.TL.RCMTL.RCMTL.TL.RCMTL.TL.RCMTL.RCMTL.RCMTL.TL.RCMTL.RCMTL.RBIT.RCMTL.RCMTL.RCMTL.RBIT.RBIT.RCMTL.TL.RCMTL.TL.RCMTL.TL.TL.TL.TL.RBIT.RBIT.RCMTL.TL.TL.RBIT_RCMTL.RCMTL.RBIT.RCMTL.TL.TL.RBIT.RBIT. //设置比较 A 值 EPwm2Regs.CMPB.bit.CMPB = EPWM2_MAX_CMPB; //设置比较 B 值 // 设置操作 // EPwm2Regs.AQCTLA.bit.PRD = AQ_CLEAR; //在周期 EPwm2Regs.AQCTLA.bit.CAU = AQ_SET 时清除 PWM2A; //在事件 A 上设置 PWM2A、 //向上计数 EPwm2Regs.AQCTLB.bit.PRD = AQ_CLEAR; //在周期 EPwm2Regs.AQCTLB.bit.CBU = AQ_SET 时清除 PWM2B; //在事件 B 上设置 PWM2B、 //向上计数 // //中断,其中我们将更改比较值 // EPwm2Regs.ETSEL.bit.INTSEL = et_CTR_ZERO; //选择零事件 EPwm2Regs.ETSEL.bit.INTEN 上的 INT = 1; //启用 INT EPwm2Regs.ETPS.bit.INTPRD = et_3rd; //生成第3个事件的 INT // 信息此示例用于跟踪 // CMPA/CMPB 值 移动的方向,允许的最小值和最大值以及 //指向正确 ePWM 寄存器的指针 // epwm2_info.epwm_cmpa_direction = ePWM_cmp_up; //首先增大 CMPA epwm2_info.ePWM_CMPB_Direction = ePWM_CMP_DOWN;//并减小 CMPB epwm2_info.EPwmTimerIntCount = 0; //将中断置零 //计数 器 epwm2_info.EPwmRegHandle =&EPwm2Regs; //将指针设置为 // ePWM 模块 epwm2_info.EPwmMaxCMPA = EPWM2_MAX_CMPA; //设置最小值/最大值 // CMPA/CMPB 值 epwm2_info.EPwmMinCMPA = EPWM2_min_CMPA; epwm2_info.EPwmMaxCMPB = EPWM2_MAX_CMPB; epwCount_info.EPwmMinCMPB = EPWM2_MIN_CMPB; } // 将 每个值进行比较/ePWM/更新/?/ePWM//einfo/ePWM//ePWM//ePWM=/ePWM//ePWM/ e/ePWM//ePWM//ePWM/ e/ePWM/ e/ePWM/ ePWM/ e/ePWM/ ePWM//ePWM/ eCO/eCO/eCO/eCO/eCO/eCO/eCO/eCO/eCO/eCO/ePWM/ eCO/eCO/eCO/e 10 { ePWM_INFO->EPwmTimerIntCount = 0; // //如果我们增加 CMPA,请检查是否 //我们达到了最大值。 如果不是、请增大 CMPA //否则、更改方向并减小 CMPA // if (ePWM_INFO->ePWM_CMPA_DIRECTION == ePWM_CMP_UP) { if (ePWM_INFO->EPwmRegHandle->CMPA.bit.CMPA < ePWM_INFO->EPwmMaxCMPA) { ePWM_INFO->EPwmRegHandle->CMPA.bit.CMPA++; } 其他 { ePWM_INFO->ePWM_CMPA_DIRECTION = ePWM_CMP_DOWN; ePWM_INFO->EPwmRegHandle->CMPA.bit.CMPA--; } } // //如果我们降低了 CMPA,请检查是否 //我们达到最小值。 如果不是、请减小 CMPA //否则,更改方向并增加 CMPA // 其他 { if (ePWM_INFO->EPwmRegHandle->CMPA.bit.CMPA =ePWM_INFO->EPwmMinCMPA) { ePWM_INFO->ePWM_CMPA_DIRECTION = ePWM_CMP_UP; ePWM_INFO->EPwmRegHandle->CMPA.bit.CMPA++; } 其他 { ePWM_INFO->EPwmRegHandle->CMPA.bit.CMPA--; } } // //如果我们增加 CMPB,请检查是否 //我们达到了最大值。 如果不是、则增加 CMPB //否则、更改方向并减小 CMPB // if (ePWM_INFO->ePWM_CMPB_DIRECTION == ePWM_CMP_UP) { if (ePWM_INFO->EPwmRegHandle->CMPB.bit.CMPB < ePWM_INFO->EPwmMaxCMPB) { ePWM_INFO->EPwmRegHandle->CMPB.bit.CMPB++; } 其他 { ePWM_INFO->ePWM_CMPB_DIRECTION = ePWM_CMP_DOWN; ePWM_INFO->EPwmRegHandle->CMPB.bit.CMPB--; } } // //如果我们降低 CMPB,请检查是否 //我们达到最小值。 如果不是、减小 CMPB //否则、更改方向并增加 CMPB // 其他 { if (ePWM_INFO->EPwmRegHandle->CMPB.bit.CMPB =>= ePWM_INFO->EPwmMinCMPB) { ePWM_INFO->ePWM_CMPB_DIRECTION = ePWM_CMP_UP; ePWM_INFO->EPwmRegHandle->CMPB.bit.CMPB++; } 其他 { ePWM_INFO->EPwmRegHandle->CMPB.bit.CMPB--; } } 否则 { ePWM_INFO->EPwmTimerIntCount++; } return; } // ////文件结束 //

    谢谢你。

    此致、

    Amin

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

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

    Amin、

    是的、我知道整个示例与您尝试执行的操作无关、但我认为配置 ETSEL 和 ETPS 的几行可能会帮助您在自己的项目中实现中断、如果您决定需要的话。

    惠特尼

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    惠特尼
    您可以建议另一种方法吗?
    Amin
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    另一种检测边缘的方法? 生成 ePWM 中断(或轮询中断标志)是否不适合您?

    惠特尼
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    是的、请更详细地解释。
    Amin
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    一种方法是同时开始 ADC 采样和脉冲生成。
    如果我可以重新启动脉冲发生器和 ADC (ePWM1和 ePWM2)、我的问题将得到解决(ePWM1和 ePWM2在上升沿开始工作并同步)。
    感谢你的帮助。
    Amin
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    好的、也许问题是目前上升沿位于 CMPA 上(这两个 PWM 都不同)。

    //清零 PWM1A
    EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;
    EPwm1Regs.AQCTLA.bit.PRD = AQ_CLEAR;
    //清零 PWM2A
    EPwm2Regs.AQCTLA.bit.CAU = AQ_SET;
    EPwm2Regs.AQCTLA.bit.PRD = AQ_CLEAR;

    那么、您可能希望更改上述代码、以便上升沿为零?

    EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;
    EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;
    EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET;
    EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;

    此外、即使它们开始同步、它们也将不同步。 您目前正在将 ePWM1周期设置为12、将 ePWM2周期设置为31250、不能被12除。 因此、您可以重新配置 ePWM 分频器、直到您能够获得两个可保持同步的 PRD 值、或者您必须通过清除 TBCLKSYNC、清除 TBCTR 和设置 TBCLKSYNC 来重新同步它们。

    如果我一再误解您所说的问题、我会感到抱歉

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

    尊敬的惠特尼:

    根据您的建议、信号不会在特定的边沿生成、而是可变的。

    说明示例:

    假设我们有两个通道同步 ADC、

    ADC1连接到具有固定频率和占空比的脉冲发生器(连接到设备以生成信号的 PWM 通道)。

    ADC2连接到任意信号的。

    然后我们有两个矢量、我们需要找到以下索引(i、j、k、l、…) 来分离第二个通道上的信号(这种方法很复杂)。

    现在、我有一个 PWM 发生器(ePWM2)和一个 ADC 通道(ePWM1)、而不是两个通道同步 ADC。

    如果我知道脉冲是在上升沿生成的、并且 ADC 同时开始采样、

    由于脉冲频率是固定的、因此我可以用固定的索引来分隔样本。

    我需要始终以特殊的方式(上升沿或下降沿)生成脉冲、并在此时开始采样。

    谢谢、此致、

    Amin

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您是否有任何波形捕获显示您的当前配置有什么错误? 我认为我对您尝试执行的操作有着大致的了解、但我不清楚您在执行过程中遇到了哪些困难。

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

    尊敬的惠特尼:

    主要功能如下:

    放置在 while (1)循环中的断点、

    请参阅此函数: __interrupt void adcaIsr()

    //########################################################################################################################
    //! \file /2837x_RFFT_ADC/main.c
    //!
    //! \brief 显示具有来自 ADC 输入的512 pt 实时 RFFT 的演示代码
    //! \Author Vishal Coelho (修改原始版本)
    //! \date 2015年3月26日
    //!
    //! 该程序展示了如何使用12位实时 ADC
    //! 和相关的频谱幅度、相位。 EPWM1和2已设置
    //! 这样 EPWM2输出的方波的频率比
    之慢10倍//! EEPWM1;EEPWM1用作 ADC 的采样时钟、它将
    //! 通过通道 A0 (引脚09)对 EPWM2A (引脚53)进行采样、然后运行 FFT。
    //! 实时 FFT 是逐帧计算的。 一旦整帧为
    //! 在 ADC ISR 中填充、它会设置一个标志来启动 FFT。
    //! 计算完成后将重置标志
    //!
    //! 注意此示例使用 F2837xD controlCARD Rev1.1
    //! 注意输入缓冲区必须与2N 字边界对齐、N 为
    //! 实际 FFT 的大小。 用户可以选择使用替代例程
    、//! RFFT_ADC_f32u ()、如果无法(或不需要)对齐。 在这里
    //! 情况下、可以对段 alignment #pragma 进行注释。 但是、使用此
    //! 函数将降低算法的周期性能。
    //!
    //组: C2000
    //目标系列: F2837x
    //
    //////################################################################################################################
    //$TI 发布:C28x 浮点单元库 V1.50.00.00 $
    //$发布 日期:2017年5月22日$
    //$版权:版权所有(C) 2017 Texas Instruments Incorporated -
    //             http://www.ti.com/ 保留所有权利$
    //##############################################################################################################
    
    //
    //包括
    //*********
    #include "fpu_rfft.h" //主 include 文件
    #include "math.h"
    #include "examples_setup.h"
    
    //!
    //! \addtogroup RFFT_examples ADC 输入(实时)的实数 FFT
    
    //@{
    //*********
    //定义
    //*********
    #define RFFT_STACages 9
    #define RFFT_SIZE (1 << RFFT_STages)
    #define F_PER_SAMPLE (ADC_SAMPLING_FREQ/(float) RFFT_SIZE
    )#define USE_TEST_INPUT 1 //如果不在测试模式中、请务必排除 SIGNAL。asm
    //从构建
    #define Epsilon 0.1
    //*********
    //全局
    //*********
    
    #ifdef __cplusplus
    #pragma DATA_SECTION ("RFFTdata1")
    #else
    #pragma DATA_SECTION (RFFTin1Buff、"RFFTdata1")
    #endif //_cplusplus
    //! 简要 FFT 计算缓冲器
    //! 注意:输入缓冲区需要与2N 字边界对齐
    //! 注意如果 FFT 级数为奇数、FFT 的结果将
    //! 写入该缓冲器
    //! 请注意、此缓冲器采用 N 个12位 ADC 输入、因此它定义为
    //! 无符号 int 数组、但输入//之间的 FFT 算法 ping
    通! 每个级的输出缓冲器、因此该缓冲器需要能够
    //! 容纳 N 个浮点值、且大小应为2 * RFFT_SIZE
    uint16_t RFFTin1Buff[2 * RFFT_SIZE];
    
    #ifdef __cplusplus
    #pragma DATA_SECTION ("RFFTdata2")
    #else
    #pragma DATA_SECTION (RFFTBuff、"RFFTdata2")/#magendif/
    
    ! 简要幅度计算缓冲器
    //!
    float RFFTmagBuff[RFFT_SIZE/2+1];
    
    #ifdef __cplusplus
    #pragma DATA_SECTION ("RFFTdata2")
    #else
    #pragma DATA_SECTION (RFFTmagBuff、"RFFTdata2")
    #endif //_cplusplus
    //! \brief 相位计算缓冲器
    //!
    float RFFTphaseBuff[RFFT_SIZE /2];
    
    #ifdef __cplusplus
    #pragma DATA_SECTION ("RFFTdata3")
    #else
    #pragma DATA_SECTION (RFFToutBuff、"RFFTdata3")
    #endif //_cplusplus
    //! 简要 FFT 计算缓冲器
    //! 注意如果 FFT 级数是偶数、FFT 的结果将
    //! 写入该缓冲器
    //!
    float RFFToutBuff[RFFT_SIZE];
    
    #ifdef __cplusplus
    #pragma DATA_SECTION ("RFFTdata4")
    #else
    #pragma DATA_SECTION (RFFTF32Coef、"RFFTdata4")
    #endif //_cplusplus
    //! \brief Twiddle Factors
    //!
    float RFFTF32Coef[RFFT_SIZE];
    
    //! 简要 RFFT_ADC_F32_struct 对象
    //!
    RFFT_ADC_F32_struct rfft_ADC;
    
    //! 针对 RFFT_ADC_F32_struct 对象的\brief 句柄
    //!
    RFFT_ADC_F32_struct_Handle HND_rfft_ADC =&rfft_ADC;
    
    //! 简要 RFFT_F32_struct 对象
    //!
    RFFT_F32_struct rfft;
    
    //! 针对 RFFT_F32_struct 对象的\brief 句柄
    //!
    RFFT_F32_struct_Handle HND_rfft =&rfft;
    
    //! \brief 标志、用于指示 ADC 已完成采样和存储、
    //! FFT 输入缓冲器中的 N 个点
    //!
    volatile uint16_t flagInputReady = 0;
    
    //! \brief 进入 FFT 输入缓冲器的索引
    //!
    volatile uint16_t sampleIndex = 0;
    
    //*********
    //函数原型
    //*********
    _interrupt void adcaIsr ();
    //*********
    //函数定义
    //*********
    //!
    //! \brief 针对512样本 RFFT ADC 示例的主例程
    //! 返回1
    //!
    //! 该程序展示了如何计算
    //的实际 FFT、幅度和相位! 来自12位 ADC 输入的数据。 输入缓冲器必须与 A
    //!对齐 如果使用 RFFT_F32、则为2N 字边界。
    //! 数据段对齐(#pragma ...) RFFT_ADC_f32u //
    ! 但在运行 RFFT_ADC_F32时需要。 但是、使用未对齐
    的//! 版本将降低算法的周期性能。
    //!
    //! 最小级数为3。 当级数更多
    时//! 大于9时、量化误差会很大、不建议这么做。
    //! 此示例将通过 ADC 通道对 ePWM 通道进行采样、并运行
    //! RFFT 对实信号的影响。
    //!
    //! RFFT_F32_struct 是一个定义为:
    //!
    //! typedef 结构{
    //! float * InBuf;
    //! float * OutBuf;
    //! float * CosSinBuf;
    //! float * MagBuf;
    //! float * PhaseBuf;
    //! uint16_t FFTize;
    //! uint16_t FFTStage;
    //!} RFFT_F32_struct;
    //!
    //! RFFT_ADC_F32_struct 定义为:
    //! typedef 结构{
    //! uint16_t * InBuf;
    //! 无效 *尾线;
    //!} RFFT_ADC_F32_struct;
    //!
    //! 假设:
    //!
    //! -# RFFT_F32_struct 的 OutBuf 必须传递到
    //的尾端! RFFT_ADC_F32_struct
    //! -#输入信号存储在 Signal.asm
    //! -# FFTize 必须是2的幂(32、64、128等)
    //! -# FFTize 必须大于或等于32
    //! -# FFTStages 必须为 log2 (FFTize)
    //! -# InBuf、OutBuf、CosSinBuf 在长度上 FFTize
    //! -#幅度缓冲器的长度为 FFTSize/2+1
    //! -#相位缓冲器的长度为 FFTSize/2
    //!
    //! 观察变量:
    //!
    //! -# InBuf (RFFT_ADC_F32_struct)输入缓冲
    器//! -# BUF (RFFT_F32_STRURT) 未使用
    //! -#尾灯 存储了 OutBuf 的地址
    //! -# OutBuf 输出缓冲器
    //! -# CosSinBuf Twiddle 因子缓冲
    器//! -# MagBuf 幅度缓冲
    器//! -# PhaseBuf 相位缓冲器
    //! -# j 标准化数字频率分量的索引
    //! -#频率 原始信号的实际模拟频率
    //!
    //! 外部连接:
    //! 将 A0 (引脚9)连接到 F2837x controlCARD 上的 EPWM2A (引脚53)。 请参阅
    //! 用于引脚定位的电路板原理图。
    //! 请注意、ADC 将以100KHz 对50%占空比1KHz 波形(EPWM2A)进行采样
    //! 并在其上运行 FFT。 由于输入是方波、因此您将
    //! 请参见第5个 bin
    处的基频1KHz //! (5*FS/N = 5*100K/512 = 976.5)及其所有奇次谐波。 因为采样
    的//! 波形不是 FFT_SIZE 的整数倍、您将看到一些
    //! 频谱泄漏时、基频的一部分将泄漏到第6个容器中。
    //! 克服这一问题的一种方法是在//运行 FFT
    之前窗口输入! 它。
    //!
    int16_t main (void)
    {
    //本地
    uint16_t i、j;
    float freq = 0.0;
    
    #ifdef 闪存
    EALLOW;
    Flash0EccRegs.ecc_enable.bit.enable = 0;
    memcpy (((uint32_t *)&RamfuncsRunStart、(uint32_t *)&RamfuncsLoadStart、
    (uint32_t)&RamfuncsLoadSize);
    FPU_initFlash();
    #endif //flash
    
    FPU_initSystemClocks();
    
    FPU_initEPIE();
    
    //设置 ADC-A
    FPU_initADCA();
    
    //将 EPWM1A 设置为采样时钟、将 EPWM2A 设置为信号
    //采样
    FPU_initEPWM();
    
    //映射 ISR 函数
    EALLOW;
    PieVectTable.ADCA1_INT =&adcaIsr;// ADCA 中断1的函数
    EDIS;
    //启用全局中断和更高优先级的实时调试事件:
    PieCtrlRegs.PIEIER1.bit.INTx1 = 1;//启用 ADC1INT
    IER |= M_INT1;//启用组1中断
    EINT; //启用全局中断 INTM
    ERTM; //启用全局实时中断 DBGM
    
    //启动 ePWM
    FPU_startEPWM ();
    
    //将 RFFT_ADC_F32_struct 链接到 RFFT_F32_struct。 尾指针
    RFFT_ADC_F32_struct 的//被传递到的 OutBuf 指针
    //RFFT_F32_struct
    hnd_rfft_adc->Tail =&(hnd_rfft->OutBuf);
    
    hnd_rfft->FFTize = RFFT_SIZE; //FFT 大小
    hnd_rfft->FFTStage = RFFT_STOPENAINTS; //FFT 级
    
    hnd_rfft_adc->InBuf =&RFFTin1Buff[0];//输入缓冲器(12位 ADC 输入)
    hnd_rfft->OutBuf =&RFFToutBuff[0];//输出缓冲区
    hnd_rfft->CosSinBuf =&RFFTF32Coef[0];//Twiddle 因子
    hnd_rfft->MagBuf =&RFFTmagBuff[0];//幅度输出缓冲区
    hnd_rfft->PhaseBuf =&RFFTphaseBuff[0];//相位输出缓冲器
    
    RFFT_F32_SINCOSTable (HND_RFFT); //Calculate Twiddle Factor
    
    对于(i=0;i < RFFT_SIZE;i++){
    RFFToutBuff[i]= 0; //清理输出缓冲
    器}
    
    对于(i=0;i <= RFFT_SIZE/2;i++){
    RFFTmagBuff[i]= 0; //清理幅度缓冲
    器}
    
    对于(i=0;i < RFFT_SIZ/2;i++){
    RFFTphaseBuff[i]= 0; //清理相位缓冲
    器}
    
    while (1){
    while (flagInputReady = 0){};//等待 ADC ISR 设置该标志
    //然后再继续
    RFFT_ADC_F32 (HND_rfft_ADC);//计算实数 FFT (12位 ADC 输入)<--- 断点
    flagInputReady = 0; //重置标志
    
    在项目中--tmu_support=tmu0时,#ifdef __TMS320C28XX_tmu__//定义
    //属性
    RFFT_F32_MAG_TMU0 (HND_RFFT); //计算幅度
    RFFT_F32_PHASE_TMU0 (HND_RFFT); //计算相
    位#else
    RFFT_F32_MAG (HND_RFFT); //计算幅度
    RFFT_F32_PHASE (HND_RFFT); //计算相
    位#endif //__TMS320C28XX_TMU__
    
    //找出信号频率的最大频率分量
    //分量信号。 该算法仅用于查找频率
    一个分量频率信号的//;在本例中、它给出了
    采样方波的//基频
    J = 1;
    FREQ = RFFTmagBuff[1];
    for (i=2;i 频率){
    J = I;
    FREQ = RFFTmagBuff[i];
    }
    }
    
    //将标准化数字频率转换为实际模拟频率
    //f = m * FS/N
    //其中 m 是最大值的二进制数、即采样 fs
    //频率和 N FFT 中的点数
    FREQ = F_PER_SAMPLE *(float) j;
    }
    
    //执行永远不会达到此点
    返回1;
    }
    
    // main 的末尾
    
    //! \brief ADC 中断服务例程
    //! ISR 会将每个采样值存储在 FFT 缓冲区中、和
    //! 一旦缓冲区已满、升起标志
    //!
    _interrupt void adcaIsr ()
    {
    RFFTin1Buff[sampleIndex++]= AdcaResultRegs.ADCRESULT0;
    if (sampleIndex ==(RFFT_SIZE - 1))){
    sampleIndex = 0;
    flagInputReady = 1;
    
    EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;//<--- 新
    EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;//<--- 新
    EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET;//<--- 新
    EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;//<--- 新
    }
    
    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//清除 INT1标志
    PieCtrlRegs.PIEACK.all = PIEACK_Group1;
    }
    
    //@}//addtogroup
    
    //文件末尾 

    运行程序(使用 Resume (F8))几次的结果并显示在示波器上:

    谢谢你。

    此致、

    Amin

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我在上一篇帖子中建议的 AQCTLA 寄存器配置更改我本来打算添加到 FPU_initEPWM ()函数 examples_setup.c 的末尾以替换已经存在的 AQCTLA 配置代码。 将其放入 ISR 的目的是什么?

    我在示波器捕获中看到这是您的 ePWM2信号。 您希望它看起来是什么样的? 存储在 RFFTin1Buff 中的值是否与您预期的值不同?

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

    我更改了代码、

    void FPU_initEPWM (void)
    {
    CpuSysRegs.PCLKCR2.bit.EPWM1 =1;//启用 EPWM1时钟
    CpuSysRegs.PCLKCR2.bit.EPWM2 =1;//启用 EPWM1时钟
    
    //启用 ePWM GPIO
    InitEPwm1Gpio();
    InitEPwm2Gpio();
    
    EALLOW;
    // ePWM 时钟分频器设置为/2
    ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV=1;
    //关闭 ePWM 时钟
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
    //禁用组上的 SOC
    EPwm1Regs.ETSEL.bit.SOCAEN = 0;
    //在向上计数时选择 SOC
    EPwm1Regs.ETSEL.bit.SOCASEL = 4;
    //在发生第一个事件时生成脉冲
    EPwm1Regs.ETPS.bit.SOCAPRD = 1;
    //将比较 A 值设置为2000次计数
    EPwm1Regs.CMPA.bit.CMPA = EPWM1_DUTY;
    //将周期设置为4000个计数
    EPwm1Regs.TBPRD = EPWM1_PERIOD;
    //冻结计数器
    EPwm1Regs.TBCTL.bit.CTRMODE = 3;
    //启用 SOCA
    EPwm1Regs.ETSEL.bit.SOCAEN = 1;
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = ePWM_HSPCLKDIV;
    //禁用组上的 SOC
    EPwm2Regs.ETSEL.bit.SOCAEN = 0;
    //将比较 A 值设置为10000次计数
    EPwm2Regs.CMPA.bit.CMPA = EPWM2_Duty_cycle;
    //将周期设置为20000个计数
    EPwm2Regs.TBPRD = EPWM2_PERIOD;
    //冻结计数器
    EPwm2Regs.TBCTL.bit.CTRMODE = 3;
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = ePWM_HSPCLKDIV;
    //清除零上的 PWM1A
    // EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;
    EPwm1Regs.AQCTLA.bit.PRD = AQ_CLEAR;
    //清零 PWM2A
    EPwm2Regs.AQCTLA.bit.CAU = AQ_SET;
    EPwm2Regs.AQCTLA.bit.PRD = AQ_CLEAR;*/
    
    EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;
    EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;
    EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET;
    EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;
    
    EDIS;
    } 

    问题是 RFFTin1Buff 上存储的值 是时间中的一个变量

    我需要启动脉冲始终相同。

    此致、

    Amin

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

    好的、你是否尝试了我关于减小 ePWM 时钟上的分频器的其他建议以使 ePWM 保持同步?

    [引用]此外、即使它们开始同步、它们也将不同步。 您目前正在将 ePWM1周期设置为12、将 ePWM2周期设置为31250、不能被12除。 因此、您可以重新配置 ePWM 分频器、直到您能够获得两个可保持同步的 PRD 值、或者您必须通过清除 TBCLKSYNC、清除 TBCTR 和设置 TBCLKSYNC 来重新同步它们。[/QUERP]

    例如、在 examples_setup.h 中

    //
    //定义
    //*********
    #define CPU_FRQ_200MHz 1
    #define ADC_SAMPLING_FREQ 100000.0L
    #define ePWM_CLK 100000000 //ePWM_CLOCK 是 SYSCLK/2
    #define ePWM_CLKDIV 1 //ePWM_CLOCK 是 SYSCLK/(2*2)
    #define ePWM_HSPCLKDIV 2. //ePWM_CLOCK 是 SYSCLK/(4*2*2)
    #define EPWM1_PERIOD ePWM_CLK/(4*2*500000U)
    #define EPWM1_DUTY EPWM1_PERIODE/2
    #define EPWM2_PERIOD ePWM_CLK/(4*2*200U)
    #define EPWM2_Duty_cycle EPWM2_PERIODE/2 

    谢谢、

    惠特尼

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

    感谢你的帮助。 我按如下方式更改了代码、断点:
    while (1){
    while (flagInputReady = 0){};
    RFFT_ADC_F32 (HND_rfft_ADC);//计算实数 FFT (12位 ADC 输入)<--- 断点
    (笑声)

    对于第一次运行、结果良好、RFFTin1Buff 为:

    但我在下一次运行中看不到相同的结果、 RFFTin1Buff[]中的所有索引  都被移入 RFFTin1Buff[0]。

    此致、

    Amin