请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
器件型号: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); }