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.

[参考译文] TMS320F28388D:针对 ADC+DMA 上的 Ping Pong 缓冲器的不同 ePWM 频率

Guru**** 2601915 points
Other Parts Discussed in Thread: SYSCONFIG, C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1112744/tms320f28388d-different-epwm-frequencies-for-ping-pong-buffers-on-adc-dma

器件型号:TMS320F28388D
Thread 中讨论的其他器件:SysConfigC2000WARE

您好!

是否可以在单个 ADC 的单个 DMA 设置中即时更改乒乓缓冲器的 PWM 频率?

假设我们要在同一 ADC 通道上设置两个不同的采样周期(不同的频率和不同的长度)。 您建议如何执行此操作?

此时、我们有一个长块、然后抽取其中一个、但现在我们需要对2个 ADC 通道执行相同的操作、并且器件上没有足够的存储器。 在硬件上,我们还将 ADC 连接了两个...所以这是可能的。 但我不确定如何实现它。

此致

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

    您好、Francisco、

    在下图中、如果信号需要高采样率的点是确定的、则可以通过某种方法来调整 PWM 的频率。  当采样需要更快切换时、可通过在该实例写入 TBPRD 寄存器来完成此操作。

    此致、

    Joseph

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

    答案是肯定的。 在影子模式下设置 EPWM PRD、然后可以写入 PRD、最后一个周期完成后、新的 PRD 将生效。

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

    谢谢

    您有没有关于 PRD 影子模式和 TBPRD 的示例?

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

    谢谢

    是的、信号采样频率始终是确定性的。

    例如、我们要设置一个完整的6k 采样块、其中5k 使用一个采样频率、其余1k 采样使用更高频率(第一个频率的 x4因子)。

    您是否愿意为此提供一个示例?

    此致

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

    这是我的实际 PWM 代码:

    void ConfigureEPWM(void)
    {
    
    //
    // Make the timer count up
    //
    	EPwm2Regs.TBCTL.all = 0x0000;
    	EPwm2Regs.TZCTL.all = 0x0000;
    
    	EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
    
    	EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;
    
    	EPwm2Regs.TBPRD = 199;            // 500khz
    
    
    //
    // Set the A output on zero and reset on CMPA
    //
    	EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET;
    	EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;
    
    
    	EPwm2Regs.AQCTLA.bit.PRD = AQ_TOGGLE;        // Toggle on PRD
    
    //
    // Set CMPA to 20us to get a 50% duty
    //
    	EPwm2Regs.CMPA.bit.CMPA = 100;        //80;//1200;//2000
    
    //
    // Start ADC when timer equals zero (note: don't enable yet)
    //
    	EPwm2Regs.ETSEL.bit.SOCASEL = ET_CTR_ZERO;
    	EPwm2Regs.ETPS.bit.SOCAPRD = ET_1ST;
    
    //
    // Enable initialization of the SOCA event counter. Since we are
    // disabling the ETSEL.SOCAEN bit, we need a way to reset the SOCACNT.
    // Hence, enable the counter initialize control.
    //
    	EPwm2Regs.ETCNTINITCTL.bit.SOCAINITEN = 1;
    }

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

    使用 driverlib/SysConfig 示例。 它们都在影子模式下使用 PRD。

    C2000WARE/driverlib/f2838x/examples/C28x/ePWM

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

    谢谢你 Nima。

    我能否举个例子说明如何实现这一点?

    we would like to set a full 6k samples block for example, 5k of them using 100kHz and the rest 1k sampling using 500kHz.
    
    Then we would go back to the first block
    
    

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

    这并不简单、因为事件触发中断被限制为15、所以对于较高的数字、我们将有许多中断。

    我们希望在每个周期结束时仅使用1个中断。

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

    是否可以使用 DMA 通道执行此操作(如之前的共享代码 EPwm2已用于 ADC 采样)

    如果您可以共享一个示例或一段代码、那将非常棒。

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

    朴世利

    我无法提供自定义应用程序代码。 请研究这些示例并尝试实施所需的系统。  

    NIMA

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

    如果您将事件触发事件计数设置为1、它将在每个周期生成1个中断。  

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

    DMA 可以访问 ePWM 寄存器。 您可以查看 ePWM DMA 示例。 您需要的应该可以通过 ADC ePWM 和 DMA 实现

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

    你好 Nima。

    我对执行情况有一些疑问。 我已经为 ADC 和计时器实现了 DMACH1和 CH2。 如何在 DMACH5上添加此功能?

    下面是一个示例。

    PieVectTable.DMA_CH5_INT =&dmach5_isr_timer;

    //INTERRUPT for TIMER
    PieVectTable.DMA_CH5_INT = &dmach5_isr_TIMER;
    
    void ConfigureEPWM(void)
    {
    
    //
    // Make the timer count up
    //
    	EPwm2Regs.TBCTL.all = 0x0000;
    	EPwm2Regs.TZCTL.all = 0x0000;
    
    	EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
    
    	EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;
    
    	EPwm2Regs.TBPRD = 199;            // 500khz
    
    
    //
    // Set the A output on zero and reset on CMPA
    //
    	EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET;
    	EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;
    
    
    	EPwm2Regs.AQCTLA.bit.PRD = AQ_TOGGLE;        // Toggle on PRD
    
    //
    // Set CMPA to 20us to get a 50% duty
    //
    	EPwm2Regs.CMPA.bit.CMPA = 100;        //80;//1200;//2000
    
    //
    // Start ADC when timer equals zero (note: don't enable yet)
    //
    	EPwm2Regs.ETSEL.bit.SOCASEL = ET_CTR_ZERO;
    	EPwm2Regs.ETPS.bit.SOCAPRD = ET_1ST;
    
    //
    // Enable initialization of the SOCA event counter. Since we are
    // disabling the ETSEL.SOCAEN bit, we need a way to reset the SOCACNT.
    // Hence, enable the counter initialize control.
    //
    	EPwm2Regs.ETCNTINITCTL.bit.SOCAINITEN = 1;
    }
    
    //
    // DMA setup channels.
    //
    
    void DMA_for_ADCS()
    {
    
    	//
    	// Initialize DMA
    	//
    		DMAInitialize();
    
    	//
    	// DMA set up for first ADC
    	//
    
    	
    		DMACH1AddrConfig(adcData_compuesto, &AdccResultRegs.ADCRESULT0);
    
    		DmaRegs.CH1.BURST_SIZE.bit.BURSTSIZE = 0;
    
    
    
    		DMACH1TransferConfig(RESULTS_BUFFER_SIZE_TOTAL - 1, 0, 2);
    
    		
    		DMACH1ModeConfig(
    		DMA_ADCCINT1,
    							PERINT_ENABLE,
    							ONESHOT_DISABLE,
    							CONT_ENABLE,
    							SYNC_DISABLE,
    							SYNC_SRC,
    							OVRFLOW_DISABLE,
    							SIXTEEN_BIT,
    							CHINT_END,
    							CHINT_ENABLE);
    
    	//
    	// DMA set up for second ADC
    	//
    		
    		DMACH2AddrConfig(&adcData_compuesto[1], &AdcaResultRegs.ADCRESULT0);
    
    
    		DmaRegs.CH2.BURST_SIZE.bit.BURSTSIZE = 0;
    		 
    		DMACH2TransferConfig(RESULTS_BUFFER_SIZE_TOTAL- 1, 0, 2);
    		DMACH2ModeConfig(
    	
    				DMA_ADCAINT2,
    				PERINT_ENABLE,
    				ONESHOT_DISABLE,
    				CONT_ENABLE,
    				SYNC_DISABLE,
    				SYNC_SRC,
    				OVRFLOW_DISABLE,
    				SIXTEEN_BIT,
    				CHINT_END,
    				CHINT_DISABLE);
    
    
    }
    
    void initDMA()
    {
        //
        // Initialize DMA
        //
        DMA_initController();
        
        //.
        //.......................
        DMA_for_ADCS();
        //........................
    
    
      ////////////////////////////////////////////////////                    
        //my doubt!!!!                    
        ////////////////////////////////////////////////////
        
        //
        // DMA CH5
        //
        DMA_configAddresses(DMA_CH5_BASE, (uint16_t *)(EPwm2Regs + EPWM_O_CMPA),
                            compareConfigs);
                      
      
      //no burst now
        //DMA_configBurst(DMA_CH5_BASE, BURST, 1, 1);
        //DMA_configTransfer(DMA_CH5_BASE, TRANSFER, 1, 1-BURST);
        
        //samller buffer to generate interrupt and change FREQ
        DMACH5TransferConfig(RESULTS_BUFFER_SIZE_SMALLER - 1, 0, 2);
        
        //What is this setup??????
        DMA_configMode(DMA_CH5_BASE, DMA_TRIGGER_EPWM2SOCA, DMA_CFG_ONESHOT_DISABLE |
                       DMA_CFG_CONTINUOUS_ENABLE | DMA_CFG_SIZE_16BIT);
    
    
    	DMACH5ModeConfig(
    	
    		//DMA_ADCAINT1,
    		DMA_TRIGGER_EPWM2SOCA, //IS it ok?
    			PERINT_ENABLE,
    			ONESHOT_DISABLE,
    			CONT_ENABLE,
    			SYNC_DISABLE,
    			SYNC_SRC,
    			OVRFLOW_DISABLE,
    			SIXTEEN_BIT,
    			CHINT_END,
    			CHINT_DISABLE);
    
    
        //
        // Configure DMA Ch5 interrupts
        //
        DMA_setInterruptMode(DMA_CH5_BASE, DMA_INT_AT_END);
        DMA_enableInterrupt(DMA_CH5_BASE);
        DMA_enableTrigger(DMA_CH5_BASE);
    
        
    
    }

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

    您可以使用 DMA 将数据从 ADC 移到存储器中的某个位置。

    现在、您想将数据移动到 ePWM 中、对吧?

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

    我们需要对 ePWM 脉冲进行计数、并在任何定义的时刻相应地更改 PRD

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

    在这种情况下、您只需使用 ET 模块、对 PRD 进行计数并在 ISR 中进行更改。

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

    你好。

    您是否能够提供示例?

    谢谢你

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

    您好、您能提供一个示例吗?

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

    您好、Pak、

    我无法共享示例代码。 您必须使用 C2000Ware/driverlib 文件夹中的现有软件并实现此功能。

    NIMA

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

    我建议使用 driverlib 和 SysConfig 来简化您的开发。

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

    对于此类问题、我们将产品移植到 ST 和 NXP

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

    朴世利

    我无法与您在论坛上的共享特定于应用的代码。 我可以帮助您在使用我们的 SDK 实施时朝着正确的方向进行指导。

    例如、  

    如果您为 DMA 的 CH5实施了代码、但代码无法正常工作、我可以为您提供有关代码需要如何更改或代码行为方式为何的指导。

    但是、我无法编写代码并通过论坛与您共享。 它不会让我通过点击授权来提供完整的应用示例。

    我建议您实施 ePWM 中断计数器代码、然后实施 DMA5通道、当您达到阈值时、立即启动该 DMA 通道。 如果您的代码不起作用、您可以共享 DMA5 CH 配置代码和 ePWM 事件计数代码、我本人和我们的 DMA 专家将非常乐意为您提供有关器件运行方式的原因的指导。

    NIMA

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

    哇、很有趣的是、我一直在找一个示例、您"无法分享示例代码。 您必须使用 C2000Ware/driverlib 文件夹中的现有软件并实现此功能。" 然后我可以重写 TI 的一段代码、然后您可以进行检查。

    不在论坛上公开,以便每个人都能进入论坛。 有时、我在 e2e 上找到了一些答案、其中有一些私有文件共享、需要检查。 然后、我向 TI 要求他们、并被告知负责该公司的人员不再在该公司工作。 浪费时间。

    根据您的竞争对手的经验、在高级情况下、我提出了相同的请求、一些专家编写了代码并与我们分享进行测试。

    这只是一个事实、我在解释我们选择其他供应商的原因(我不是唯一具有相同经验的供应商)。 只是反馈。

    祝你度过美好的一天!

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

    朴世利

    我理解您的沮丧。 但一般来说、我可以帮助调试问题或指导您如何实现自己的想法。  在您分享您的高级想法后、我无法为您实施代码。  

    对于您的 DMA、如果您与我共享您的想法的初始实施以及您认为应该如何实施的方框图、我可以通过告知您理解中的任何错误或任何器件限制来指导您完成其余的工作。 我甚至可以为您查看您的代码、并告诉您可能存在的问题区域。

    NIMA

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

    你好 Nima。

    很多帖子都是毫无结果的...例如:

    https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1113376/tms320f28388d-possible-bug-on-dma-adc-training-example

    其他问题在内部得到解决、这使得具有相同问题的其他工程师难以找到快速解决方案。

    例如、在这个线程中、我只是要求一个简单的示例、说明如何在同一 ADC DMA 块内的两个不同频率下动态更改 ePWM 的频率、从而对 ADC 进行采样。 我共享了一些代码。 我共享了一个图。

    最后、我在我的代码中执行了权变措施(仍然对该解决方案感兴趣)、但我们的工程资源需要专注于我们的应用、而不是通过 TI DSP 芯片实现功能...而 IMHO TI 似乎不分享这一愿景。

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

    朴世利

    一般而言、TI 会跟踪工程师的响应时间和效率。 我们有很多有关 E2E 支持的规则。 对于新的 C2000线程、没有回答的问题非常少见、但我看到的是您共享的问题。

    对于那个、

     if (PingPongState == 0) {
            // Set DMA address to start at ping buffer.
            DMA_configAddresses(DMA_CH1_BASE,
                                (const void *)AdcBufRaw,
                                (const void *)(ADCARESULT_BASE + ADC_O_RESULT0));
    
            // Fill AdcBuf with contents of the pong buffer.
            AdcBufRawPtr = AdcBufRaw + ADC_BUF_LEN;
            for (i = 0; i < ADC_BUF_LEN; i++) { 
                *(AdcBufPtr++) = *(AdcBufRawPtr++);
            }
        } else {
            // Set DMA address to start at pong buffer.
            DMA_configAddresses(DMA_CH1_BASE,
                                (const void *)(AdcBufRaw + ADC_BUF_LEN),
                                (const void *)(ADCARESULT_BASE + ADC_O_RESULT0));
    
            // Fill AdcBuf with contents on the ping buffer.
            AdcBufRawPtr = AdcBufRaw;
            for (i = 0; i < ADC_BUF_LEN; i++) {
                *(AdcBufPtr++) = *(AdcBufRawPtr++);
            }
        }
    
        // Toggle PingPongState.
        PingPongState ^= 1;

    逻辑看起来正确。 是的、这是第一次执行空缓冲区复制、但从第二次开始按预期工作。

    首次:

    为 ADC 尚未接收的下一组采样设置 DMA。

    您将在 AdcBufRaw[0..ADC_BUF_LEN-1]中填充这些值。 尚未收到任何资料。 DMA 将执行此操作。

    然后将上次接收到的内容 AdcBufRaw[ADC_BUF_LEN 复制到 ADC_BUF_LEN*2-1]到 AdcBufRawPtr 中。

    是的,由于 AdcBufRawPtr  的 AdcBufRaw[ADC_BUF_LEN 至 ADC_BUF_LEN*2-1]为空,因此第一次将用空值填充 AdcBufRawPtr。

    例如、我们要设置一个完整的6k 采样块、其中5k 采样使用100kHz、其余1k 采样使用500kHz。

    更改 EPWM 频率后、您应该能够自动更改 ADC 采样率、因为它连接到 DMA 以接收样本。

    这是我要做的、

    1.将 EPWM PRD 设置为100KHz。

    2.设置 ADC + DMA 以传输6K 样本

    3.运行 ePWM。

    4、DMA 传输完成后、产生中断、更改 EPWM PRD (500kHz)、保留相同的 DMA 设置、但传输大小设置为1K 除外。

    等待下一个 ISR 完成 DMA

    6.返回第1步重复。