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.

[参考译文] LAUNCHXL-F280049C:数字 SDK 库中的 Sogi PLL 未正常工作。

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1391688/launchxl-f280049c-sogi-pll-from-digital-sdk-library-not-working-as-it-should

器件型号:LAUNCHXL-F280049C
主题中讨论的其他器件:PMP23338PMP23069

工具与软件:

大家好、我一直在尝试使用数字 SDK 库中的库来实现单相 PLL、而我一直在努力使其工作。 我正在提供频率为60Hz 的(0至2V)正弦波信号。 我使用我的 ADC 引脚并在其上运行 PLL 算法来检测这一点。 出于某种原因、我需要将 AC_FREQ 加倍、以使其生成频率相似但未完全锁定的正弦波。 请查看我的代码和程序中的图像。 我正在使用 DAC 读取输出信号、这些信号是我通过 ADC 检测到的正弦波、我还显示了正弦波输出。  

注意:我以30kHz 的频率触发 ePWM、这与我用于 PLL 的频率相同。 出于某种原因、当我显示正弦波时、它是同相的、但余弦波是90异相的。

请提供任何帮助以使其正常工作?

第一张图显示了 PLL 余弦(蓝色)和黄色(输入电压)。

第二张图显示了 PLL 正弦(蓝色)和黄色(输入电压)

#include "driverlib.h"
#include "device.h"
#include "board.h"
#include "c2000ware_libraries.h"
#include "spll_1ph_notch.h"
#include "spll_1ph_sogi.h"
#include "spll_1ph_sogi_fll.h"
#include "dlog_4ch.h"
#include <math.h>

#define AC_FREQ 120
//#define Grid_freq 60
#define ISR_FREQUENCY 30000 //min is 20kHz
#define DBUFF_SIZE     2


SPLL_1PH_SOGI spll1;
float32_t spll_sine;
float32_t spll_cosine;
float32_t spll_theta;
float32_t spll_fo;

float32_t dacVal;
float32_t dacValB;


uint16_t myADC0Results;
float32_t actualDCVoltage;
float32_t currentDCVoltage;

void initEPWM(void);

//
// Main
//
void main(void)
{

    //
    // Initialize device clock and peripherals
    //
    Device_init();

    //
    // Disable pin locks and enable internal pull-ups.
    //
    Device_initGPIO();

    //
    // Initialize PIE and clear PIE registers. Disables CPU interrupts.
    //
    Interrupt_initModule();

    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    //
    Interrupt_initVectorTable();

    //
    // PinMux and Peripheral Initialization
    //
    Board_init();

    SPLL_1PH_SOGI_reset(&spll1);
    SPLL_1PH_SOGI_config(&spll1, AC_FREQ, ISR_FREQUENCY, (float32_t)(222.2862), (float32_t)(-222.034));


    initEPWM();

    //
    // C2000Ware Library initialization
    //
    C2000Ware_libraries_init();


    //
    // Enable Global Interrupt (INTM) and real time interrupt (DBGM)
    //
    EINT;
    ERTM;


    while(1)
    {
        EPWM_enableADCTrigger(EPWM1_BASE, EPWM_SOC_A);
        EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_UP);


        EPWM_disableADCTrigger(EPWM1_BASE, EPWM_SOC_A);
        EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_STOP_FREEZE);

    }
}

void initEPWM(void)
{
    //
    // Disable SOCA
    //
    EPWM_disableADCTrigger(EPWM1_BASE, EPWM_SOC_A);

    //
    // Configure the SOC to occur on the first up-count event
    //
    EPWM_setADCTriggerSource(EPWM1_BASE, EPWM_SOC_A, EPWM_SOC_TBCTR_U_CMPA);
    EPWM_setADCTriggerEventPrescale(EPWM1_BASE, EPWM_SOC_A, 1);

    //
    // Set the compare A value to 1000 and the period to 1999
    // Assuming ePWM clock is 100MHz, this would give 50kHz sampling
    // 50MHz ePWM clock would give 25kHz sampling, etc.
    // The sample rate can also be modulated by changing the ePWM period
    // directly (ensure that the compare A value is less than the period).
    //
    EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_A, 1000);
    EPWM_setTimeBasePeriod(EPWM1_BASE, 1667);

    //
    // Set the local ePWM module clock divider to /1
    //
    EPWM_setClockPrescaler(EPWM1_BASE,
                           EPWM_CLOCK_DIVIDER_2,
                           EPWM_HSCLOCK_DIVIDER_1);

    //
    // Freeze the counter
    //
    EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_STOP_FREEZE);
}

__interrupt void adcB1ISR(void)
{
    //
    // Add the latest result to the buffer
    myADC0Results = ADC_readResult(ADCBRESULT_BASE, ADC_SOC_NUMBER0) +
            ADC_readResult(ADCBRESULT_BASE, ADC_SOC_NUMBER1) +
            ADC_readResult(ADCBRESULT_BASE, ADC_SOC_NUMBER2) +
            ADC_readResult(ADCBRESULT_BASE, ADC_SOC_NUMBER3) >> 2;


    actualDCVoltage = (myADC0Results/4095.0)*3.3;
    currentDCVoltage = (myADC0Results)/4095.0;  //pucalc



        SPLL_1PH_SOGI_run(&spll1, currentDCVoltage);


        spll_sine=spll1.sine;
        spll_cosine=spll1.cosine;
        spll_theta=spll1.theta;


        dacVal = myADC0Results;
        DAC_setShadowValue(myDAC0_BASE, dacVal);
        DEVICE_DELAY_US(2);


        dacValB = ((spll_sine+1)/3.3)*4095;
        DAC_setShadowValue(myDAC1_BASE, dacValB);
        DEVICE_DELAY_US(2);



    //
    // Clear the interrupt flag
    //
    ADC_clearInterruptStatus(myADC0_BASE, ADC_INT_NUMBER1);

    //
    // Check if overflow has occurred
    //
    if(true == ADC_getInterruptOverflowStatus(myADC0_BASE, ADC_INT_NUMBER1))
    {
        ADC_clearInterruptOverflowStatus(myADC0_BASE, ADC_INT_NUMBER1);
        ADC_clearInterruptStatus(myADC0_BASE, ADC_INT_NUMBER1);
    }

    //
    // Acknowledge the interrupt
    //
    Interrupt_clearACKGroup(INT_myADC0_1_INTERRUPT_ACK_GROUP);
}

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

    您好、Gerald

    实现中可能会出现一些错误。

    请参阅 pmp23338参考设计。 此设计使用单相 PLL 检测输入交流电的角度。 此设计的运行情况已经过验证。  

    谢谢你

    侯赛因·阿米尔

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

    你好,阿米尔,感谢的答复。 我浏览了 pmp23338和 pmp23069的参考设计(这些代码在编写时编写)、并查看了 PLL 部分、也做了同样的工作。 我有点困惑、因为代码是一个完整的状态机、我挑选了 PLL 部分。 我想知道我是否应该在代码中执行类似的操作、因为我希望测试的是一个简单的程序。

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

    您好、Gerald

    您无需实现整个状态机。 只需选择 PLL 部分就足够了。 我建议花一些时间浏览 pmp23338的代码以了解 PLL 的操作。 我觉得您在实施中缺少一些东西。  

    谢谢你

    侯赛因·阿米尔

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

    Amir、您好。通过代码后、我意识到为 SPLL 创建了 ISR 循环。 并使用了 ADC 触发器来检测值。 我想了解是否需要使用计时器在单独的 ISR 循环中处理 SPLL? 我当前正在使用 ePWM 触发器对 ADC 值进行采样、在该 ADC ISR 中、我将计算出的 pu 值传递给 SPLL。 因此、spll run 函数在 ADC ISR 内运行。 这个问题可能来自哪里?

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

    Gerald、您好!

    我认为问题不是由于使用 ADC ISR 造成的。 不过、我建议测试参考设计中实现的 SPLL。

    谢谢

    Amir

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

    好 Amir ,感谢您的帮助和耐心。