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.

[参考译文] TMS320F280049:F280049 SDFM 数据采集问题

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1018345/tms320f280049-f280049-sdfm-data-acquisition-issue

器件型号:TMS320F280049
主题中讨论的其他器件:AMC1306EVM

你(们)好

我使用 sdfm_ex5_filter_sync_fifo_cpuread 示例检查 从 AMC1306EVM 板采集的数据。

我对代码进行了以下更改:

使用 PWM1为 SDFM 提供10MHz 时钟(适用于 AMC1306EVM 和 SD1.C1)。

2.使用 DACA 为 AMC1306EVM 提供0-0.5V 锯齿输出。 (使用内部+1.65V 作为电压基准)

   转换数据后、DAC 数据在 ISR sdfmFIFO1ISR 处进行更改。 (我已确认 DACA 输出)

3.为了检查数据是否正确、程序保存 PWM8.TBCTR 和3个转换后的 FIFO 数据、以此类推

  我可以检查数据采集时间是否正确(它也可以作为分隔符来区分同时获得的3个数据)。

4、只检查 SDFM1.Filter1 并将 SDFM1.D1设置为 GPIO16、SDFM1.C1设置为 GPIO17。

更改后的代码如下所示:

//###########################################################################
//
// FILE:   sdfm_ex5_filter_sync_fifo_cpuread.c
//
// TITLE:  SDFM Type 1 Filter FIFO Example.
//
//! \addtogroup driver_example_list
//! <h1> SDFM Type 1 Filter FIFO </h1>
//!
//! This example configures SDFM1 filter to demonstrate data read through
//! CPU in FIFO & non-FIFO mode. Data filter is configured in mode 0
//! to select SINC3 filter with OSR of 256. Filter output is configured
//! for 16-bit format and data shift of 10 is used.
//!
//! This example demonstrates the FIFO usage if enabled. FIFO length is set
//! at 16 and data ready interrupt is configured to be triggered when FIFO is
//! full. In this example, SDFM filter data is read by CPU in SDFM Data Ready
//! ISR routine.
//!
//! \b External \b Connections \n
//!    Connect Sigma-Delta streams to (SD-D1, SD-C1 to SD-D4,SD-C4)
//!    on GPIO24-GPIO31
//!
//! \b Watch \b Variables \n
//! -  \b filter1Result - Output of filter 1
//!
//
//###########################################################################
// $TI Release: F28004x Support Library v1.09.00.00 $
// $Release Date: Thu Mar 19 07:26:52 IST 2020 $
// $Copyright:
// Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
//
// Redistribution and use in source and binary forms, with or without 
// modification, are permitted provided that the following conditions 
// are met:
// 
//   Redistributions of source code must retain the above copyright 
//   notice, this list of conditions and the following disclaimer.
// 
//   Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the 
//   documentation and/or other materials provided with the   
//   distribution.
// 
//   Neither the name of Texas Instruments Incorporated nor the names of
//   its contributors may be used to endorse or promote products derived
//   from this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//###########################################################################

//
// Included Files
//
#include "driverlib.h"
#include "device.h"
#include <stdio.h>

#define JIAKAI
//
// Defines
//
#define MAX_SAMPLES               1024
#define FIFO_INT_NUM              3U
#define SDFM_FILTER_ENABLE 0x2U

//
// Macro to enable FIFO mode. Make it zero to disable
// FIFO mode.
//
#define ENABLE_FIFO               1

//
// Globals
//
int16_t  filter1Result[200];
#pragma DATA_SECTION(filter1Result, "Filter1_RegsFile");

//
// Function Prototypes
//
void configureSDFMPins(void);
void initEPWM(uint32_t epwmInstance);
void configureDAC(void);
//
// ISRs
//
__interrupt void sdfmFIFO1ISR(void);
__interrupt void sdfm1ErrorISR(void);

//
// Main
//
void main(void)
{
    //
    // Initialize device clock and peripherals
    //
    Device_init();

    //
    // Setup GPIO by disabling pin locks and enabling pullups
    //
    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();

    //
    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP5);
    Interrupt_register(INT_SDFM1DR1, sdfmFIFO1ISR);
    Interrupt_register(INT_SDFM1, sdfm1ErrorISR);

    //
    // Enable SDFM1 interrupts(Data Ready & Error interrupts)
    //
#if (0) // need to move to the palce that all devices are initialized
    Interrupt_enableMaster();
    Interrupt_enable(INT_SDFM1DR1);
    Interrupt_enable(INT_SDFM1);
#endif
    initEPWM(EPWM8_BASE);

    //
    // Configure GPIO pins as SDFM pins
    //
    configureSDFMPins();

    //
    // Input Control Unit
    //
    // Configure Input Control Unit: Modulator Clock rate = Modulator data rate
    //
    SDFM_setupModulatorClock(SDFM1_BASE, SDFM_FILTER_1,
                             SDFM_MODULATOR_CLK_EQUAL_DATA_RATE);

    //
    // Data Filter Unit
    //

    // Configure Data Filter Unit - filter type, OSR value and
    // enable / disable data filter
    //
    SDFM_configDataFilter(SDFM1_BASE, (SDFM_FILTER_1 | SDFM_FILTER_SINC_3 |
           SDFM_SET_OSR(256)), (SDFM_DATA_FORMAT_16_BIT | SDFM_FILTER_ENABLE |
           SDFM_SHIFT_VALUE(0x000A)));

#if (ENABLE_FIFO)
        //
        // Set data ready interrupt source as fifo interrupt
        //
        SDFM_setDataReadyInterruptSource(SDFM1_BASE, SDFM_FILTER_1,
                                         SDFM_DATA_READY_SOURCE_FIFO);

        //
        // Enable FIFO and set the FIFO interrupt level
        //
        SDFM_enableFIFOBuffer(SDFM1_BASE, SDFM_FILTER_1);

        SDFM_setFIFOInterruptLevel(SDFM1_BASE, SDFM_FILTER_1, FIFO_INT_NUM);

        SDFM_enableInterrupt(SDFM1_BASE, SDFM_FILTER_1,
                         (SDFM_FIFO_INTERRUPT | SDFM_FIFO_OVERFLOW_INTERRUPT));
#else
        //
        // Set data ready interrupt source as fifo interrupt
        //
        SDFM_setDataReadyInterruptSource(SDFM1_BASE, SDFM_FILTER_1,
                                         SDFM_DATA_READY_SOURCE_DIRECT);

        SDFM_enableInterrupt(SDFM1_BASE, SDFM_FILTER_1,
                             SDFM_DATA_FILTER_ACKNOWLEDGE_INTERRUPT);
#endif


    //
    // Enable Master filter bit: Unless this bit is set none of the filter
    // modules can be enabled. All the filter modules are synchronized when
    // master filter bit is enabled after individual filter modules are enabled.
    //
    SDFM_enableMasterFilter(SDFM1_BASE);

    //
    // Use PWM8.CMPA signals to synchronize the filters.
    //
#if (0)
    SDFM_disableExternalReset(SDFM1_BASE, SDFM_FILTER_1);
#else
    SDFM_enableExternalReset(SDFM1_BASE, SDFM_FILTER_1);
    SDFM_setPWMSyncSource(SDFM1_BASE, SDFM_FILTER_1, SDFM_SYNC_PWM8_SOCA);
    SDFM_enableWaitForSync(SDFM1_BASE, SDFM_FILTER_1);
#endif

    //
    // Enable modulator failure interrupt, disable threshold interrupts
    //
    SDFM_enableInterrupt(SDFM1_BASE, SDFM_FILTER_1,
                         SDFM_MODULATOR_FAILURE_INTERRUPT);

    SDFM_disableInterrupt(SDFM1_BASE, SDFM_FILTER_1,
                          (SDFM_HIGH_LEVEL_THRESHOLD_INTERRUPT |
                           SDFM_LOW_LEVEL_THRESHOLD_INTERRUPT));

    configureDAC();

    while((HWREGH(EPWM8_BASE + EPWM_O_TBCTR)) < 550);

    //
    // Enable master interrupt so that any of the filter interrupts can trigger
    // by SDFM interrupt to CPU
    //
    SDFM_enableMasterInterrupt(SDFM1_BASE);

#if (1) // need to move to the palce that all devices are initialized
    Interrupt_enableMaster();
    Interrupt_enable(INT_SDFM1DR1);
    Interrupt_enable(INT_SDFM1);
#endif

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

    //
    // Wait for an interrupt
    //
    while(1);
}

//
// sdfm1ErrorISR - SDFM1 Error ISR
//
unsigned long cntErr = 0;
__interrupt void sdfm1ErrorISR(void)
{
    //
    // Clear SDFM flag register (SDIFLG)
    //
    SDFM_clearInterruptFlag(SDFM1_BASE, SDFM_MASTER_INTERRUPT_FLAG |
                            0xFFFF);
    cntErr++;

    //
    // Acknowledge this interrupt to receive more interrupts from group 5
    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP5);
}

#define PWM_TBCTR(_p)       *((uint16_t *)(0x3F04 + 0x100 * (_p)))
unsigned long cntDat = 0;

//
// sdfmFIFO1ISR - SDFM FIFO1 ISR
//
__interrupt void sdfmFIFO1ISR(void)
{
    uint16_t i;
    static uint16_t loopCounter1 = 0;

#if (0)
    SDFM_setOutputDataFormat(SDFM1_BASE, SDFM_FILTER_1,
                             SDFM_DATA_FORMAT_16_BIT);
#endif

    cntDat++;
    //
    // Read SDFM flag register (SDIFLG)
    //
//    if(loopCounter1 >= MAX_SAMPLES)
//    {
//        loopCounter1 = 0;
//        ESTOP0;
//    }

    if(SDFM_getFIFOISRStatus(SDFM1_BASE, SDFM_FILTER_1) == 0x1U)
    {
        filter1Result[loopCounter1] = PWM_TBCTR(8); if (++loopCounter1 >= 200) loopCounter1 = 0;
        for(i = 0; i < FIFO_INT_NUM; i++)
        {
            filter1Result[loopCounter1] =
                         (int16_t)(SDFM_getFIFOData(SDFM1_BASE,
                                                    SDFM_FILTER_1) >> 16U);
            if (++loopCounter1 >= 200) loopCounter1 = 0;
        }

    }
    else if(SDFM_getNewFilterDataStatus(SDFM1_BASE, SDFM_FILTER_1) == 0x1U)
    {
        filter1Result[loopCounter1++] =
               (int16_t)(SDFM_getFilterData(SDFM1_BASE, SDFM_FILTER_1) >> 16U);
        if (++loopCounter1 >= 200) loopCounter1 = 0;
    }

    {
        static int dacVal = 0, iDelta = 5;
        dacVal += iDelta; if (dacVal >= 500) dacVal = 0;

        DAC_setShadowValue(DACA_BASE, (int)(dacVal * 3300.0 / 4095.0));
    }

    //
    // Clear SDFM flag register (SDIFLG)
    //
    SDFM_clearInterruptFlag(SDFM1_BASE, SDFM_MASTER_INTERRUPT_FLAG |
                            SDFM_FILTER_1_FIFO_INTERRUPT_FLAG      |
                            SDFM_FILTER_1_NEW_DATA_FLAG            |
                            SDFM_FILTER_1_FIFO_OVERFLOW_FLAG);

    //
    // Acknowledge this interrupt to receive more interrupts from group 5
    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP5);
}

//
// configureSDFMPins - Configure SDFM GPIOs
//
void configureSDFMPins(void)
{
    uint16_t pin;
#ifdef JIAKAI
    for(pin = 16; pin <= 17; pin++)
    {
//        GPIO_setDirectionMode(pin, GPIO_DIR_MODE_IN);
        GPIO_setMasterCore(pin, GPIO_CORE_CPU1);
        GPIO_setPadConfig(pin, GPIO_PIN_TYPE_STD);
        GPIO_setQualificationMode(pin, GPIO_QUAL_ASYNC);
    }
    GPIO_setPinConfig(GPIO_16_SD1_D1);
    GPIO_setPinConfig(GPIO_17_SD1_C1);
#else
    for(pin = 24; pin <= 31; pin++)
    {
        GPIO_setDirectionMode(pin, GPIO_DIR_MODE_IN);
        GPIO_setMasterCore(pin, GPIO_CORE_CPU1);
        GPIO_setPadConfig(pin, GPIO_PIN_TYPE_STD);
        GPIO_setQualificationMode(pin, GPIO_QUAL_ASYNC);
    }

    //
    // Configure GPIO16-GPIO31 as SDFM pins
    //
    GPIO_setPinConfig(GPIO_24_SD_D1);
    GPIO_setPinConfig(GPIO_25_SD_C1);
    GPIO_setPinConfig(GPIO_26_SD_D2);
    GPIO_setPinConfig(GPIO_27_SD_C2);
    GPIO_setPinConfig(GPIO_28_SD_D3);
    GPIO_setPinConfig(GPIO_29_SD_C3);
    GPIO_setPinConfig(GPIO_30_SD_D4);
    GPIO_setPinConfig(GPIO_31_SD_C4);
#endif
}


//
// Configure DAC - Setup the reference voltage and output value for the DAC
//
void configureDAC(void)
{
    //
    // Set internal +1.65v as the DAC reference voltage.
    // Edit here to use ADC VREF as the reference voltage.
    //
    ADC_setVREF(ADCA_BASE, ADC_REFERENCE_INTERNAL, ADC_REFERENCE_3_3V);
    DAC_setReferenceVoltage(DACA_BASE, DAC_REF_ADC_VREFHI); // DAC_REF_VDAC
    DAC_setGainMode(DACA_BASE, DAC_GAIN_TWO);

    //
    // Enable the DAC output
    //
    DAC_enableOutput(DACA_BASE);

    //
    // Set the DAC shadow output to 0
    //
    DAC_setShadowValue(DACA_BASE, 0);

    //
    // Delay for buffered DAC to power up
    //
    DEVICE_DELAY_US(10);
}

//
// initEPWM - Initialize specified EPWM settings
//
void initEPWM(uint32_t epwmInstance)
{
    //
    // Disable sync(Freeze clock to PWM as well)
    //
    SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    EPWM_disableADCTrigger(epwmInstance, EPWM_SOC_A);

    //
    // Setup TBCLK: Configure timer period = 801 TBCLKs, phase = 0 &
    // clear counter
    //
    EPWM_setTimeBasePeriod(epwmInstance, 0xFFF0);
    EPWM_setPhaseShift(epwmInstance, 0U);
    EPWM_setTimeBaseCounter(epwmInstance, 0U);

    //
    // Set CMPA value
    //
    EPWM_setCounterCompareValue(epwmInstance, EPWM_COUNTER_COMPARE_A, 200U);

    //
    // Setup counter mode
    //
    EPWM_setTimeBaseCounterMode(epwmInstance, EPWM_COUNTER_MODE_UP);
    EPWM_setClockPrescaler(epwmInstance,
                           EPWM_CLOCK_DIVIDER_1,
                           EPWM_HSCLOCK_DIVIDER_1);

    //
    // Set actions:
    // Toggle PWMxA on event A, up-count
    // Toggle PWMxB on event A, up-count
    //
    GPIO_setPadConfig(0, GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(GPIO_0_EPWM1_A);
    GPIO_setPadConfig(1, GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(GPIO_1_EPWM1_B);
    EPWM_setTimeBasePeriod(EPWM1_BASE, 4);     // PWM1 period: 0.1us
    EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_UP);
    EPWM_setClockPrescaler(EPWM1_BASE,
                           EPWM_CLOCK_DIVIDER_1,
                           EPWM_HSCLOCK_DIVIDER_1);
    EPWM_setActionQualifierAction(EPWM1_BASE,
                                  EPWM_AQ_OUTPUT_A,
                                  EPWM_AQ_OUTPUT_TOGGLE,
                                  EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
//                                EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    EPWM_setActionQualifierAction(EPWM1_BASE,
                                  EPWM_AQ_OUTPUT_B,
                                  EPWM_AQ_OUTPUT_TOGGLE,
                                  EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
//                                EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);

//#ifndef JIAKAI
    //
    // Configure SOCA signal
    //
    //
    EPWM_setADCTriggerSource(epwmInstance, EPWM_SOC_A, EPWM_SOC_TBCTR_U_CMPA);
    EPWM_setADCTriggerEventPrescale(epwmInstance, EPWM_SOC_A, 1);
    EPWM_enableADCTrigger(epwmInstance, EPWM_SOC_A);
//#endif

    //
    // Enable sync and clock to PWM
    //
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
}

//
// End of file
//

运行代码后、我发现在准确的时间输入 ISR、但3个采集数据之间甚至不接近(见下文)。

期待 TI 技术人员或专家指出计划中的问题。

谢谢、

Jiakai

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

    Jiakai、

    在代码中、PWM8配置为每655.2us 生成一次到 SDFM 的同步脉冲。 因此、SDFM.filter1 (数据滤波器)将每655.2us 复位一次。 当 Sinc3滤波器复位后、前两个样本将不正确、且滤波器仅从第3个样本产生正确的滤波器输出。 这就是您看到两个错误样本的原因。 为避免此问题、请忽略前2个样本并从第3个样本开始记录。

    另一个建议是首先提供直流输入、而不是锯齿输入来调试此问题。

    此致、

    曼诺伊

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

    您好、Manoj、

    太棒了!

    你 是对的! 我已经确认了。

    非常感谢!

    Jiakai

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

    您好、Manoj、

    我已经尝试将 SDFM 结果从注册表值计算为电压值、如下所示(AMC1306EVM 输入来自 DACA

    DACA 输出信号是0至0.25V 的锯齿波形):

    buf[loopCounter1]= 0.25 *(SDFM_getFIFOData (SDFM1_base、SDFM_FILTER_1)>> 16U)/((1L*256*256*256)>> 10);

    在上面的语句中、0.25是 Vclping 值(250mV)。

    电压值被保存到 buf 数组中(我在28004x_sdfm_ram_lnk.cmd 中将 RAMLS6和 RAMLS7合并到 RAMLS5中)、  

    数组值显示如下:

    从上图中可以看出、最大值接近0.125v (仅为实际输入值的1/2)。

    我的计算是否有任何错误? 正确的计算方法是什么?

    源代码如下:

    //###########################################################################
    //
    // FILE:   sdfm_ex5_filter_sync_fifo_cpuread.c
    //
    // TITLE:  SDFM Type 1 Filter FIFO Example.
    //
    //! \addtogroup driver_example_list
    //! <h1> SDFM Type 1 Filter FIFO </h1>
    //!
    //! This example configures SDFM1 filter to demonstrate data read through
    //! CPU in FIFO & non-FIFO mode. Data filter is configured in mode 0
    //! to select SINC3 filter with OSR of 256. Filter output is configured
    //! for 16-bit format and data shift of 10 is used.
    //!
    //! This example demonstrates the FIFO usage if enabled. FIFO length is set
    //! at 16 and data ready interrupt is configured to be triggered when FIFO is
    //! full. In this example, SDFM filter data is read by CPU in SDFM Data Ready
    //! ISR routine.
    //!
    //! \b External \b Connections \n
    //!    Connect Sigma-Delta streams to (SD-D1, SD-C1 to SD-D4,SD-C4)
    //!    on GPIO24-GPIO31
    //!
    //! \b Watch \b Variables \n
    //! -  \b filter1Result - Output of filter 1
    //!
    //
    //###########################################################################
    // $TI Release: F28004x Support Library v1.09.00.00 $
    // $Release Date: Thu Mar 19 07:26:52 IST 2020 $
    // $Copyright:
    // Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
    //
    // Redistribution and use in source and binary forms, with or without 
    // modification, are permitted provided that the following conditions 
    // are met:
    // 
    //   Redistributions of source code must retain the above copyright 
    //   notice, this list of conditions and the following disclaimer.
    // 
    //   Redistributions in binary form must reproduce the above copyright
    //   notice, this list of conditions and the following disclaimer in the 
    //   documentation and/or other materials provided with the   
    //   distribution.
    // 
    //   Neither the name of Texas Instruments Incorporated nor the names of
    //   its contributors may be used to endorse or promote products derived
    //   from this software without specific prior written permission.
    // 
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    // $
    //###########################################################################
    
    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    #include <stdio.h>
    
    #define JIAKAI
    //
    // Defines
    //
    #define MAX_SAMPLES               1024
    #define FIFO_INT_NUM              7U
    #define SDFM_FILTER_ENABLE 0x2U
    
    //
    // Macro to enable FIFO mode. Make it zero to disable
    // FIFO mode.
    //
    #define ENABLE_FIFO               1
    
    //
    // Globals
    //
    #define BUF_SIZE    1024
    int16_t filter1Result[BUF_SIZE];
    float   buf[BUF_SIZE];
    //#pragma DATA_SECTION(filter1Result, "Filter1_RegsFile");
    
    //
    // Function Prototypes
    //
    void configureSDFMPins(void);
    void initEPWM(uint32_t epwmInstance);
    void configureDAC(void);
    //
    // ISRs
    //
    __interrupt void sdfmFIFO1ISR(void);
    __interrupt void sdfm1ErrorISR(void);
    
    //
    // Main
    //
    void main(void)
    {
        //
        // Initialize device clock and peripherals
        //
        Device_init();
    
        //
        // Setup GPIO by disabling pin locks and enabling pullups
        //
        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();
    
        //
        // Interrupts that are used in this example are re-mapped to
        // ISR functions found within this file.
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP5);
        Interrupt_register(INT_SDFM1DR1, sdfmFIFO1ISR);
        Interrupt_register(INT_SDFM1, sdfm1ErrorISR);
    
        //
        // Enable SDFM1 interrupts(Data Ready & Error interrupts)
        //
    #if (0) // need to move to the palce that all devices are initialized
        Interrupt_enableMaster();
        Interrupt_enable(INT_SDFM1DR1);
        Interrupt_enable(INT_SDFM1);
    #endif
        initEPWM(EPWM8_BASE);
    
        //
        // Configure GPIO pins as SDFM pins
        //
        configureSDFMPins();
    
        //
        // Input Control Unit
        //
        // Configure Input Control Unit: Modulator Clock rate = Modulator data rate
        //
        SDFM_setupModulatorClock(SDFM1_BASE, SDFM_FILTER_1,
                                 SDFM_MODULATOR_CLK_EQUAL_DATA_RATE);
    
        //
        // Data Filter Unit
        //
    
        // Configure Data Filter Unit - filter type, OSR value and
        // enable / disable data filter
        //
        SDFM_configDataFilter(SDFM1_BASE, (SDFM_FILTER_1 | SDFM_FILTER_SINC_3 |
               SDFM_SET_OSR(256)), (SDFM_DATA_FORMAT_16_BIT | SDFM_FILTER_ENABLE |
               SDFM_SHIFT_VALUE(0x000A)));
    
    #if (ENABLE_FIFO)
            //
            // Set data ready interrupt source as fifo interrupt
            //
            SDFM_setDataReadyInterruptSource(SDFM1_BASE, SDFM_FILTER_1,
                                             SDFM_DATA_READY_SOURCE_FIFO);
    
            //
            // Enable FIFO and set the FIFO interrupt level
            //
            SDFM_enableFIFOBuffer(SDFM1_BASE, SDFM_FILTER_1);
    
            SDFM_setFIFOInterruptLevel(SDFM1_BASE, SDFM_FILTER_1, FIFO_INT_NUM);
    
            SDFM_enableInterrupt(SDFM1_BASE, SDFM_FILTER_1,
                             (SDFM_FIFO_INTERRUPT | SDFM_FIFO_OVERFLOW_INTERRUPT));
    #else
            //
            // Set data ready interrupt source as fifo interrupt
            //
            SDFM_setDataReadyInterruptSource(SDFM1_BASE, SDFM_FILTER_1,
                                             SDFM_DATA_READY_SOURCE_DIRECT);
    
            SDFM_enableInterrupt(SDFM1_BASE, SDFM_FILTER_1,
                                 SDFM_DATA_FILTER_ACKNOWLEDGE_INTERRUPT);
    #endif
    
    
        //
        // Enable Master filter bit: Unless this bit is set none of the filter
        // modules can be enabled. All the filter modules are synchronized when
        // master filter bit is enabled after individual filter modules are enabled.
        //
        SDFM_enableMasterFilter(SDFM1_BASE);
    
        //
        // Use PWM8.CMPA signals to synchronize the filters.
        //
    #if (0)
        SDFM_disableExternalReset(SDFM1_BASE, SDFM_FILTER_1);
    #else
        SDFM_enableExternalReset(SDFM1_BASE, SDFM_FILTER_1);
        SDFM_setPWMSyncSource(SDFM1_BASE, SDFM_FILTER_1, SDFM_SYNC_PWM8_SOCA);
        SDFM_enableWaitForSync(SDFM1_BASE, SDFM_FILTER_1);
    #endif
    
        //
        // Enable modulator failure interrupt, disable threshold interrupts
        //
        SDFM_enableInterrupt(SDFM1_BASE, SDFM_FILTER_1,
                             SDFM_MODULATOR_FAILURE_INTERRUPT);
    
        SDFM_disableInterrupt(SDFM1_BASE, SDFM_FILTER_1,
                              (SDFM_HIGH_LEVEL_THRESHOLD_INTERRUPT |
                               SDFM_LOW_LEVEL_THRESHOLD_INTERRUPT));
    
        configureDAC();
    
    //    while((HWREGH(EPWM8_BASE + EPWM_O_TBCTR)) < 550);
    
        //
        // Enable master interrupt so that any of the filter interrupts can trigger
        // by SDFM interrupt to CPU
        //
        SDFM_enableMasterInterrupt(SDFM1_BASE);
    
    #if (1) // need to move to the palce that all devices are initialized
        Interrupt_enableMaster();
        Interrupt_enable(INT_SDFM1DR1);
        Interrupt_enable(INT_SDFM1);
    #endif
    
        //
        // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
        //
        EINT;
        ERTM;
    
        //
        // Wait for an interrupt
        //
        while(1);
    }
    
    //
    // sdfm1ErrorISR - SDFM1 Error ISR
    //
    unsigned long cntErr = 0;
    __interrupt void sdfm1ErrorISR(void)
    {
        //
        // Clear SDFM flag register (SDIFLG)
        //
        SDFM_clearInterruptFlag(SDFM1_BASE, SDFM_MASTER_INTERRUPT_FLAG |
                                0xFFFF);
        cntErr++;
    
        //
        // Acknowledge this interrupt to receive more interrupts from group 5
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP5);
    }
    
    #define PWM_TBCTR(_p)       *((uint16_t *)(0x3F04 + 0x100 * (_p)))
    unsigned long cntDat = 0;
    
    //
    // sdfmFIFO1ISR - SDFM FIFO1 ISR
    //
    float aryCoef[7] = {0.0, 0.0, 0.2, 0.2, 0.2, 0.2, 0.2};
    __interrupt void sdfmFIFO1ISR(void)
    {
        uint16_t i;
        static uint16_t loopCounter1 = 0;
    
    #if (0)
        SDFM_setOutputDataFormat(SDFM1_BASE, SDFM_FILTER_1,
                                 SDFM_DATA_FORMAT_16_BIT);
    #endif
    
        cntDat++;
        //
        // Read SDFM flag register (SDIFLG)
        //
        if(loopCounter1 >= MAX_SAMPLES)
        {
            loopCounter1 = 0;
            ESTOP0;
        } else if(SDFM_getFIFOISRStatus(SDFM1_BASE, SDFM_FILTER_1) == 0x1U)
        {
            buf[loopCounter1] = 0.0;
            filter1Result[loopCounter1] = PWM_TBCTR(8); ++loopCounter1;//if (++loopCounter1 >= BUF_SIZE) loopCounter1 = 0;
            for(i = 0; i < FIFO_INT_NUM; i++)
            {
                int16_t iVal = (int16_t)(SDFM_getFIFOData(SDFM1_BASE, SDFM_FILTER_1) >> 16U);
                filter1Result[loopCounter1] = iVal;
                buf[loopCounter1] = 0.25 * iVal / ((1L*256*256*256) >> 10);
                ++loopCounter1; // if (++loopCounter1 >= BUF_SIZE) loopCounter1 = 0;
            }
    
        }
        else if(SDFM_getNewFilterDataStatus(SDFM1_BASE, SDFM_FILTER_1) == 0x1U)
        {
            filter1Result[loopCounter1++] =
                   (int16_t)(SDFM_getFilterData(SDFM1_BASE, SDFM_FILTER_1) >> 16U);
            if (++loopCounter1 >= 200) loopCounter1 = 0;
        }
    
        {
            static int dacVal = 0, iDelta = 5;
            dacVal += iDelta; if (dacVal >= 250) dacVal = 0;
    
            DAC_setShadowValue(DACA_BASE, (int)(dacVal * 3300.0 / 4095.0));
        }
    
        //
        // Clear SDFM flag register (SDIFLG)
        //
        SDFM_clearInterruptFlag(SDFM1_BASE, SDFM_MASTER_INTERRUPT_FLAG |
                                SDFM_FILTER_1_FIFO_INTERRUPT_FLAG      |
                                SDFM_FILTER_1_NEW_DATA_FLAG            |
                                SDFM_FILTER_1_FIFO_OVERFLOW_FLAG);
    
        //
        // Acknowledge this interrupt to receive more interrupts from group 5
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP5);
    }
    
    //
    // configureSDFMPins - Configure SDFM GPIOs
    //
    void configureSDFMPins(void)
    {
        uint16_t pin;
    #ifdef JIAKAI
        for(pin = 16; pin <= 17; pin++)
        {
    //        GPIO_setDirectionMode(pin, GPIO_DIR_MODE_IN);
            GPIO_setMasterCore(pin, GPIO_CORE_CPU1);
            GPIO_setPadConfig(pin, GPIO_PIN_TYPE_STD);
            GPIO_setQualificationMode(pin, GPIO_QUAL_ASYNC);
        }
        GPIO_setPinConfig(GPIO_16_SD1_D1);
        GPIO_setPinConfig(GPIO_17_SD1_C1);
    #else
        for(pin = 24; pin <= 31; pin++)
        {
            GPIO_setDirectionMode(pin, GPIO_DIR_MODE_IN);
            GPIO_setMasterCore(pin, GPIO_CORE_CPU1);
            GPIO_setPadConfig(pin, GPIO_PIN_TYPE_STD);
            GPIO_setQualificationMode(pin, GPIO_QUAL_ASYNC);
        }
    
        //
        // Configure GPIO16-GPIO31 as SDFM pins
        //
        GPIO_setPinConfig(GPIO_24_SD_D1);
        GPIO_setPinConfig(GPIO_25_SD_C1);
        GPIO_setPinConfig(GPIO_26_SD_D2);
        GPIO_setPinConfig(GPIO_27_SD_C2);
        GPIO_setPinConfig(GPIO_28_SD_D3);
        GPIO_setPinConfig(GPIO_29_SD_C3);
        GPIO_setPinConfig(GPIO_30_SD_D4);
        GPIO_setPinConfig(GPIO_31_SD_C4);
    #endif
    }
    
    
    //
    // Configure DAC - Setup the reference voltage and output value for the DAC
    //
    void configureDAC(void)
    {
        //
        // Set internal +1.65v as the DAC reference voltage.
        // Edit here to use ADC VREF as the reference voltage.
        //
        ADC_setVREF(ADCA_BASE, ADC_REFERENCE_INTERNAL, ADC_REFERENCE_3_3V);
        DAC_setReferenceVoltage(DACA_BASE, DAC_REF_ADC_VREFHI); // DAC_REF_VDAC
        DAC_setGainMode(DACA_BASE, DAC_GAIN_TWO);
    
        //
        // Enable the DAC output
        //
        DAC_enableOutput(DACA_BASE);
    
        //
        // Set the DAC shadow output to 0
        //
        DAC_setShadowValue(DACA_BASE, 0);
    
        //
        // Delay for buffered DAC to power up
        //
        DEVICE_DELAY_US(10);
    }
    
    //
    // initEPWM - Initialize specified EPWM settings
    //
    void initEPWM(uint32_t epwmInstance)
    {
        //
        // Disable sync(Freeze clock to PWM as well)
        //
        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
        EPWM_disableADCTrigger(epwmInstance, EPWM_SOC_A);
    
        //
        // Setup TBCLK: Configure timer period = 801 TBCLKs, phase = 0 &
        // clear counter
        //
        EPWM_setTimeBasePeriod(epwmInstance, 0xFFF0);
        EPWM_setPhaseShift(epwmInstance, 0U);
        EPWM_setTimeBaseCounter(epwmInstance, 0U);
    
        //
        // Set CMPA value
        //
        EPWM_setCounterCompareValue(epwmInstance, EPWM_COUNTER_COMPARE_A, 200U);
    
        //
        // Setup counter mode
        //
        EPWM_setTimeBaseCounterMode(epwmInstance, EPWM_COUNTER_MODE_UP);
        EPWM_setClockPrescaler(epwmInstance,
                               EPWM_CLOCK_DIVIDER_1,
                               EPWM_HSCLOCK_DIVIDER_1);
    
        //
        // Set actions:
        // Toggle PWMxA on event A, up-count
        // Toggle PWMxB on event A, up-count
        //
        GPIO_setPadConfig(0, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_0_EPWM1_A);
        GPIO_setPadConfig(1, GPIO_PIN_TYPE_STD);
        GPIO_setPinConfig(GPIO_1_EPWM1_B);
        EPWM_setTimeBasePeriod(EPWM1_BASE, 4);     // PWM1 period: 0.1us
        EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_UP);
        EPWM_setClockPrescaler(EPWM1_BASE,
                               EPWM_CLOCK_DIVIDER_1,
                               EPWM_HSCLOCK_DIVIDER_1);
        EPWM_setActionQualifierAction(EPWM1_BASE,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_TOGGLE,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
    //                                EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
        EPWM_setActionQualifierAction(EPWM1_BASE,
                                      EPWM_AQ_OUTPUT_B,
                                      EPWM_AQ_OUTPUT_TOGGLE,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
    //                                EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
    
    //#ifndef JIAKAI
        //
        // Configure SOCA signal
        //
        //
        EPWM_setADCTriggerSource(epwmInstance, EPWM_SOC_A, EPWM_SOC_TBCTR_U_CMPA);
        EPWM_setADCTriggerEventPrescale(epwmInstance, EPWM_SOC_A, 1);
        EPWM_enableADCTrigger(epwmInstance, EPWM_SOC_A);
    //#endif
    
        //
        // Enable sync and clock to PWM
        //
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    }
    
    //
    // End of file
    //
    

    谢谢、

    Jiakai

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

    Jiakai、

    F28388D TRM 的"理论 SDFM 滤波器输出"部分中捕获了 SD 调制器的模拟输入与 SDFM 数字滤波器输出之间的相关性。

    此信息也适用于 F280049 SDFM、并将在下一版 TRM 中更新。

    此致、

    曼诺伊




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

    您好、Manoj、

    感谢你的答复。

    我在我的代码()中发现了错误:

    1.在第325行中,表达式错误,正确的语句如下:

         DAC_setShadowImage Value (DACA_base、(int)(dacVal * 4095.0 / 3300.0));

    2.在第309行中,Vcl削 被设定为0.25 (250mV),它应该为0.32 (320mV),正如手册中的那样)。

    谢谢、

    Jiakai