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.

[参考译文] TMS320F28027:响应缓慢

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1332549/tms320f28027-slow-response

器件型号:TMS320F28027
主题中讨论的其他器件:MOTORWARE

您好、E:\ti\motorware\motorware_1_01_00_18\sw\solutions\instaspin_foc\boards\boostxldrv8305_revA\f28x\f2802xF\projects\ccs\proj_lab11a

使用官方的8305驱动板、捕获 PWM 波的输入、并控制速度。 发现速度只会在改变 PWM 达10ms 后才会改变、并且速度命令位于 while 循环中。 事实上、while 循环应该在不到1ms 的时间内结束、所以为什么它只在10ms 后才起作用呢? 输入捕获可以更改时钟。

//###########################################################################
//
// FILE:    Example_2802xECap_Capture_Pwm.c
//
// TITLE:   Capture EPwm3.
//
// ASSUMPTIONS:
//
//    This program requires the f2802x header files.
//
//    Make the following external connection:
//    EPWM3 on GPIO4 should be connected to ECAP1 on GPIO5.
//
//    As supplied, this project is configured for "boot to SARAM"
//    operation.  The 2802x Boot Mode table is shown below.
//    For information on configuring the boot mode of an eZdsp,
//    please refer to the documentation included with the eZdsp,
//
//    $Boot_Table
//    While an emulator is connected to your device, the TRSTn pin = 1,
//    which sets the device into EMU_BOOT boot mode. In this mode, the
//    peripheral boot modes are as follows:
//
//      Boot Mode:   EMU_KEY        EMU_BMODE
//                   (0xD00)	     (0xD01)
//      ---------------------------------------
//      Wait		 !=0x55AA        X
//      I/O		     0x55AA	         0x0000
//      SCI		     0x55AA	         0x0001
//      Wait 	     0x55AA	         0x0002
//      Get_Mode	 0x55AA	         0x0003
//      SPI		     0x55AA	         0x0004
//      I2C		     0x55AA	         0x0005
//      OTP		     0x55AA	         0x0006
//      Wait		 0x55AA	         0x0007
//      Wait		 0x55AA	         0x0008
//      SARAM		 0x55AA	         0x000A	  <-- "Boot to SARAM"
//      Flash		 0x55AA	         0x000B
//	    Wait		 0x55AA          Other
//
//   Write EMU_KEY to 0xD00 and EMU_BMODE to 0xD01 via the debugger
//   according to the Boot Mode Table above. Build/Load project,
//   Reset the device, and Run example
//
//   $End_Boot_Table
//
//
//
// DESCRIPTION:
//
//    This example configures EPWM3A for:
//    - Up count
//    - Period starts at 2 and goes up to 1000
//    - Toggle output on PRD
//
//    eCAP1 is configured to capture the time between rising
//    and falling edge of the PWM3A output.
//
//###########################################################################
// $TI Release:  $
// $Release Date:  $
// $Copyright:
// Copyright (C) 2009-2023 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 "DSP28x_Project.h"     // Device Headerfile and Examples Include File
#include"protect.h"
//
// Defines that configure the start/end period for the timer
//
#define PWM3_TIMER_MIN     10
#define PWM3_TIMER_MAX     8000

#define ASSERT(expr)
#define HWREG(x)  (*((volatile uint32_t *)(x)))

#define ECAP_O_TSCTR    0x0U    // Time-Stamp Counter
#define ECAP_O_CTRPHS   0x2U    // Counter Phase Offset Value Register
#define ECAP_O_CAP1     0x4U    // Capture 1 Register
#define ECAP_O_CAP2     0x6U    // Capture 2 Register
#define ECAP_O_CAP3     0x8U    // Capture 3 Register
#define ECAP_O_CAP4     0xAU    // Capture 4 Register
#define ECAP_O_ECCTL1   0x14U   // Capture Control Register 1
#define ECAP_O_ECCTL2   0x15U   // Capture Control Register 2
#define ECAP_O_ECEINT   0x16U   // Capture Interrupt Enable Register
#define ECAP_O_ECFLG    0x17U   // Capture Interrupt Flag Register
#define ECAP_O_ECCLR    0x18U   // Capture Interrupt Clear Register
#define ECAP_O_ECFRC    0x19U   // Capture Interrupt Force Register

#define FILTER_N  11

//#define ECAP1_BASE                0x00005000U
#define ECAP1_BASE                0x00006A00U
typedef enum
{
    ECAP_EVENT_1 = 0U,   //!< eCAP event 1
    ECAP_EVENT_2 = 1U,   //!< eCAP event 2
    ECAP_EVENT_3 = 2U,   //!< eCAP event 3
    ECAP_EVENT_4 = 3U    //!< eCAP event 4
}ECAP_Events;

float dutyCycle;
float dutyCycle1;

float duty_frequency;
volatile float dutyCyclewide= 0.2;

float dutyCycle_D_value=0;
/****************** user***/
extern Variable_flag  mcflagbit;


/*********************/

//
// Function Prototypes
//

static inline uint32_t ECAP_getEventTimeStamp(uint32_t base, ECAP_Events event);
__interrupt void ecap1_isr(void);
void InitECapture(void);
void InitEPwmTimer(void);
void Fail(void);

float Winows_speed_Filter(uint16_t type,float InData);
//
// Globals
//
uint32_t  ECap1IntCount;
uint32_t  ECap1PassCount;
uint32_t  EPwm3TimerDirection;
float PwmSpeed_filter_buf[FILTER_N+1]={1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0};

//float PWM_command_speed=0;
uint32_t PWM_command_speed_old=0;

volatile uint32_t cap1Count;
uint32_t cap2Count;
uint32_t cap3Count;
uint32_t cap4Count;
//
// Defines that keep track of which way the timer value is moving
//
#define EPwm_TIMER_UP   1
#define EPwm_TIMER_DOWN 0

//
// Main
//
void user_main_Capture(void)
{
    //
    // WARNING: Always ensure you call memcpy before running any functions from
    // RAM InitSysCtrl includes a call to a RAM based function and without a 
    // call to memcpy first, the processor will go "into the weeds"
    //
#ifdef _FLASH
    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
#endif

    //
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the f2802x_SysCtrl.c file.
    //
 //   InitSysCtrl();

    //
    // Step 2. Initialize GPIO:
    // This example function is found in the f2802x_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    //
    //InitGpio();  // Skipped for this example
   // InitEPwm3Gpio();
    InitECap1Gpio();

    //
    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
    //
    // DINT;

    //
    // Initialize the PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the f2802x_PieCtrl.c file.
    //
   //  InitPieCtrl();

    //
    // Disable CPU interrupts and clear all CPU interrupt flags
    //
//       IER = 0x0000;
//       IFR = 0x0000;

    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in f2802x_DefaultIsr.c.
    // This function is found in f2802x_PieVect.c.
    //
    //    InitPieVectTable();

    //
    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
    //
    EALLOW;            // This is needed to write to EALLOW protected registers
    PieVectTable.ECAP1_INT = &ecap1_isr;
    EDIS;      // This is needed to disable write to EALLOW protected registers

    //
    // Step 4. Initialize all the Device Peripherals
    //
   // InitEPwmTimer();       // For this example, only initialize the EPwm Timers
    InitECapture();

    //
    // Step 5. User specific code, enable interrupts
    //

    //
    // Initialize counters
    //
    ECap1IntCount = 0;
    ECap1PassCount = 0;

    //
    // Enable CPU INT4 which is connected to ECAP1-4 INT
    //
    IER |= M_INT4;

    //
    // Enable eCAP INTn in the PIE: Group 3 interrupt 1-6
    //
    PieCtrlRegs.PIEIER4.bit.INTx1 = 1;

    //
    // Enable global Interrupts and higher priority real-time debug events
    //
    // EINT;               // Enable Global interrupt INTM
     ERTM;               // Enable Global realtime interrupt DBGM

    //
    // Step 6. IDLE loop. Just sit and loop forever (optional)
    //
//    for(;;)
//    {
//        __asm("          NOP");
//    }
}

//
// InitEPwmTimer - 
//
void
InitEPwmTimer()
{
    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
    EDIS;

    EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;  // Count up
    EPwm3Regs.TBPRD = PWM3_TIMER_MIN;
    EPwm3Regs.TBPHS.all = 0x00000000;
    EPwm3Regs.AQCTLA.bit.PRD = AQ_TOGGLE;       // Toggle on PRD

    //
    // TBCLK = SYSCLKOUT
    //
    EPwm3Regs.TBCTL.bit.HSPCLKDIV = 1;
    EPwm3Regs.TBCTL.bit.CLKDIV = 0;

    EPwm3TimerDirection = EPwm_TIMER_UP;

    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
    EDIS;
}

//
// InitECapture - 
//
void
InitECapture()
{
    ECap1Regs.ECEINT.all = 0x0000;        // Disable all capture interrupts
    ECap1Regs.ECCLR.all = 0xFFFF;         // Clear all CAP interrupt flags
    ECap1Regs.ECCTL1.bit.CAPLDEN = 0;     // Disable CAP1-CAP4 register loads
    ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0;   // Make sure the counter is stopped

    //
    // Configure peripheral registers
    //
    ECap1Regs.ECCTL2.bit.CONT_ONESHT = 1;    // One-shot
    ECap1Regs.ECCTL2.bit.STOP_WRAP = 3;      // Stop at 4 events
    ECap1Regs.ECCTL1.bit.CAP1POL = 1;        // Falling edge
    ECap1Regs.ECCTL1.bit.CAP2POL = 0;        // Rising edge
    ECap1Regs.ECCTL1.bit.CAP3POL = 1;        // Falling edge
    ECap1Regs.ECCTL1.bit.CAP4POL = 0;        // Rising edge
    ECap1Regs.ECCTL1.bit.CTRRST1 = 1;        // Difference operation
    ECap1Regs.ECCTL1.bit.CTRRST2 = 1;        // Difference operation
    ECap1Regs.ECCTL1.bit.CTRRST3 = 1;        // Difference operation
    ECap1Regs.ECCTL1.bit.CTRRST4 = 1;        // Difference operation
    ECap1Regs.ECCTL2.bit.SYNCI_EN = 1;       // Enable sync in
    ECap1Regs.ECCTL2.bit.SYNCO_SEL = 0;      // Pass through
    ECap1Regs.ECCTL1.bit.CAPLDEN = 1;        // Enable capture units

    ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1;      // Start Counter
    ECap1Regs.ECCTL2.bit.REARM = 1;          // arm one-shot
    ECap1Regs.ECCTL1.bit.CAPLDEN = 1;        // Enable CAP1-CAP4 register loads
    ECap1Regs.ECEINT.bit.CEVT4 = 1;          // 4 events = interrupt
}

//
// ecap1_isr -
//

float Winows_speed_Filter(uint16_t type,float InData)
{
tU8 i;/*230118 [19] MISRAC2012 不应使用基本数字类型*/

float PwmSpeed_filter_sum = 0;
float filter_sum;
    switch(type)
        {
            default://230131'default' 标签(如果存在)应显示为 switch 语句的第一个或最后一个 switch 标签 [MISRAC2012-RULE_16_1-g]
            case 0:

                PwmSpeed_filter_buf[FILTER_N] = InData;
                for(i = 0; i < FILTER_N; i++)
                {
                   PwmSpeed_filter_buf[i] = PwmSpeed_filter_buf[i + 1u];
                   PwmSpeed_filter_sum += PwmSpeed_filter_buf[i];
                }
                filter_sum = PwmSpeed_filter_sum;
                break;
        }
    return (float)(filter_sum / FILTER_N);

}



__interrupt void
ecap1_isr(void)
{
    //
    // Cap input is syc'ed to SYSCLKOUT so there may be
    // a +/- 1 cycle variation
    //

   cap1Count = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_1);//下降沿 算的是高电平时间
   cap2Count = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_2);
   cap3Count = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_3);//下降沿 算的是高电平时间
   cap4Count = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_4);

//
//
//   dutyCycle = (float)(cap1Count*100.0/(cap1Count+cap2Count));
//   dutyCycle1 = (float)(cap3Count*100.0/(cap3Count+cap4Count));
//   duty_frequency=(float)(60000000/(cap3Count+cap4Count)+1);            //获取频率,对pwm 占空比补偿
  //dutyCycle_D_value=dutyCycle1-dutyCycle;
   mcflagbit.PWM_command_flag=1;


    ECap1Regs.ECCLR.bit.CEVT4 = 1;
    ECap1Regs.ECCLR.bit.INT = 1;
    ECap1Regs.ECCTL2.bit.REARM = 1;

    //
    // Acknowledge this interrupt to receive more interrupts from group 4
    //
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;

  //  ECap1Regs.ECCLR.all = 0xFFFF;         // Clear all CAP interrupt flags
}

//
// Fail - 
//
void
Fail()
{
    __asm("   ESTOP0");
}

//
// End of File
//


static inline uint32_t ECAP_getEventTimeStamp(uint32_t base, ECAP_Events event)
{
    uint32_t count;

    ASSERT(ECAP_isBaseValid(base));


    switch(event)
    {
        case ECAP_EVENT_1:

            //
            // Read CAP1 register
            //
            count = HWREG(base + ECAP_O_CAP1);
        break;

        case ECAP_EVENT_2:
            //
            // Read CAP2 register
            //
            count = HWREG(base + ECAP_O_CAP2);
        break;

        case ECAP_EVENT_3:

            //
            // Read CAP3 register
            //
            count = HWREG(base + ECAP_O_CAP3);
        break;

        case ECAP_EVENT_4:

            //
            // Read CAP4 register
            //
            count = HWREG(base + ECAP_O_CAP4);
        break;

        default:

            //
            // Invalid event parameter
            //
            count = 0U;
        break;
    }

    return(count);
}


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [quote userid="586261" url="~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1332549/tms320f28027-slow-response 通过将 PWM 改变10ms 后、速度才会改变、并且 speed 命令位于 while 循环中。 事实上,while 循环应该在不到1毫秒内结束,所以为什么它只在10毫秒后才起作用?

    有任何波形可以显示这一点吗? 您是如何更改目标控制速度的? 您使用的 PWM 和控制频率是多少?

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

    大家好、PWM 通信是400Hz、我已经测量出每次捕捉中断的时间是5ms。 您可以增加进入中断的频率吗?我该如何更改它?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您能提高输入中断的频率吗?我该如何更改它吗?

    这话什么意思? 您可以使用 eCAP 来捕获信号并增加测量频率以减少延迟。