Ti DSP Cycle Count

http://hi.baidu.com/myyb/blog/item/e1071dce1878d032b700c8c7.html

 

TI C64x 可以有两种方法来得到程序的运行 cycle, 一个是Enable clock后调用 clock()( 这个在 VC 下是得到以 ms 为单位的时间,这里得到的是 cycle), 另一个就是 CSL Chip Support Library )提供的 timer

下面给出两种方法的程序段

 

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

/*                                                                                                                        */

/*      Auth:wb0330                                                                                              */

/*     Dest: used to measure cycle counts for TI C64x DSP                                    */

/*      Support by: http://hi.baidu.com/videocodec                                                   */

/*     or QQ group: 24960630, 10714050, 11216191                                            */

/*                                                                                                                        */

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

#include < stdio .h>

 

 

#include < time .h> /* need time.h in order to call clock()*/

 

int main ()

{

        unsigned int start , stop , overhead,cycles ;

 

 

/*––––––––––––––––––––––––––*/

/* The following example demonstrates how to include                            */

/* the clock() function in your C code.                                                          */

        /*––––––––––––––––––––––– – –*/

 

        start = clock (); /* Calculate overhead of calling clock*/

        stop = clock (); /* and subtract this value from The results*/

        overhead = stop - start ;

        start = clock ();

        /* ––––––––––––––––––––––––––*/

        /* Call a function here.                                                               */

        /* ––––––––––––––––––––––––––*/

        stop = clock ();

       cycles = stop - start - overhead;

        printf ( “cycles: %d   / n ” , cycles );

       printf ( "times: %.2f   s with cpu 600MHz, /n" ,(( float ) cycles /( float )600000000));

// clock()   end

return 0;

}

 

 

 

这里给出CSL_Timer 部分的

 

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

/*                                                                                                                        */

/*      Auth:wb0330                                                                                              */

/*     Dest: used to measure cycle counts for TI C64x DSP                                    */

/*      Support by: http://hi.baidu.com/videocodec                                                    */

/*     or QQ group:24960630, 10714050, 11216191                                            */

/*                                                                                                                         */

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

#include < stdio .h>

#include "csl.h"

#include "csl_timer.h"

int main ()

{

        TIMER_Handle hTimer ;

        unsigned int start , stop , overhead diff,cycles;

 

/*––––––––––––––––––––––––––––––––––*/

/* The following sample code shows how to set up the timer       */

/* and measure cycle counts with Chip Support Library (CSL)    */

        /*––––––––––––––––––––––––––––––––––*/

       

hTimer = TIMER_open (TIMER_DEVANY,0); /* open a timer */

        /*––––––––––––––––––––––––––––––––––*/

        /* Configure the timer. count corresponds to 8 CPU cycles in C64 */

        /*––––––––––––––––––––––––––––––––––*/

        /* control period initial value */

        TIMER_configArgs ( hTimer , 0x000002C0, 0xFFFFFFFF, 0x00000000);

        /* ––––––––––––––––––––––––––––––––––*/

        /* Compute the overhead of calling the timer. */

        /* ––––––––––––––––––––––––––––––––––*/

        start = TIMER_getCount ( hTimer ); /* to remove L1P miss overhead */

        start = TIMER_getCount ( hTimer );

        stop = TIMER_getCount ( hTimer );

        overhead = stop - start ;

        start = TIMER_getCount ( hTimer );

        /* ––––––––––––––––––––––––––––––––––*/

        /* Call a function here.                                        */

        /* ––––––––––––––––––––––––––––––––––*/

        diff = ( TIMER_getCount ( hTimer ) - start ) - overhead ;

        TIMER_close ( hTimer );

          cycles = diff*8;

        printf ( “cycles %d   / n”, cycles);      

printf ( "times: %.2f   s with cpu 600MHz, /n" ,(( float ) cycles /( float )600000000));

     // The maximum resolution of the timer is 8 CPU cycles, since the input clock to

     // the timer is fixed   to the CPU clock divided by eight

     // CSL_timer   end

 

return 0;

}

// TI File $Revision: /main/9 $ // Checkin $Date: August 10, 2007 09:05:08 $ //########################################################################### // // FILE: Example_EpwmSetup.c // // TITLE: Frequency measurement using EQEP peripheral // // DESCRIPTION: // // This file contains source for the ePWM initialization for the // freq calculation module // //########################################################################### // Original Author: SD // // $TI Release: DSP2833x Header Files V1.01 $ // $Release Date: September 26, 2007 $ //########################################################################### #include <stdint.h> #include "DSP2833x_Device.h" // DSP2833x Headerfile Include File #include "DSP2833x_Examples.h" // DSP2833x Examples Include File #if (CPU_FRQ_150MHZ) #define CPU_CLK 150e6 #endif #if (CPU_FRQ_100MHZ) #define CPU_CLK 100e6 #endif #define PWM_CLK 10e3 // If diff freq. desired, change freq here. #define SP CPU_CLK/(2*PWM_CLK) #define TBCTLVAL 0x200E // Up-down cnt, timebase = SYSCLKOUT volatile uint32_t timer0CycleCount = 0; extern void TIM0_IRQn(void); void EPwmSetup() { InitEPwm1Gpio(); EPwm1Regs.TBSTS.all=0; EPwm1Regs.TBPHS.half.TBPHS=0; EPwm1Regs.TBCTR=0; EPwm1Regs.CMPCTL.all=0x50; // Immediate mode for CMPA and CMPB EPwm1Regs.CMPA.half.CMPA =SP/2; EPwm1Regs.CMPB=SP/4; EPwm1Regs.AQCTLA.all=0x60; // EPWMxA = 1 when CTR=CMPA and counter inc // EPWMxA = 0 when CTR=CMPA and counter dec EPwm1Regs.AQCTLB.all=0x60; // EPwm1Regs.AQCTLB.all=0; EPwm1Regs.AQSFRC.all=0; EPwm1Regs.AQCSFRC.all=0; EPwm1Regs.DBCTL.all=0x23; // EPWMxB is inverted EPwm1Regs.DBRED=0; EPwm1Regs.DBFED=0; EPwm1Regs.TZSEL.all=0; EPwm1Regs.TZCTL.all=0; EPwm1Regs.TZEINT.all=0; EPwm1Regs.TZFLG.all=0; EPwm1Regs.TZCLR.all=0; EPwm1Regs.TZFRC.all=0; EPwm1Regs.ETSEL.all=0; // Interrupt when TBCTR = 0x0000 EPwm1Regs.ETFLG.all=0; EPwm1Regs.ETCLR.all=0; EPwm1Regs.ETFRC.all=0; EPwm1Regs.PCCTL.all=0; EPwm1Regs.TBCTL.all=0x0010+TBCTLVAL; // Enable Timer EPwm1Regs.TBPRD=SP; } void TIM0_Init(float Freq, float Period) { EALLOW; SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; //使能定时器timer0时钟 EDIS; EALLOW; PieVectTable.TINT0 = &TIM0_IRQn; //设置定时器0的中断服务函数 EDIS; //指向定时器0的寄存器地址 CpuTimer0.RegsAddr = &CpuTimer0Regs; //设置定时器0的周期寄存器值 CpuTimer0Regs.PRD.all = 7499; //设置定时器预定标计数器值为0 CpuTimer0Regs.TPR.all = 0; CpuTimer0Regs.TPRH.all = 0; //确保定时器0为停止状态 CpuTimer0Regs.TCR.bit.TSS = 1; //重载使能 CpuTimer0Regs.TCR.bit.TRB = 1; // Reset interrupt counters: CpuTimer0.InterruptCount = 0; /* 配置定时器Timer0 */ //ConfigCpuTimer(&CpuTimer0, Freq, Period); //开始定时器功能 CpuTimer0Regs.TCR.bit.TSS=0; //进行PIE中断配置 开启CPU第一组中断并使能第一组中断的第7个小中断,即定时器0 IER |= M_INT1; PieCtrlRegs.PIEIER1.bit.INTx7 = 1; //使能总中断 EINT; ERTM; } interrupt void TIM0_IRQn(void) { CpuTimer0Regs.TCR.bit.TIF = 1; PieCtrlRegs.PIEACK.bit.ACK1 = 1; timer0CycleCount++; if (timer0CycleCount >= 3) { timer0CycleCount = 0; EALLOW; EPwm1Regs.TBCTL.bit.CTRMODE = 3; // 停止模式(0x3) // 2. 强制输出低电平[3](@ref) EPwm1Regs.AQCSFRC.bit.CSFA = 2; // 强制ePWM1A输出低(10=强制低) EPwm1Regs.AQCSFRC.bit.CSFB = 2; // 强制ePWM1B输出低 // 3. 可选:完全关闭模块时钟(降低功耗) SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 0; // 关闭ePWM1时钟[2](@ref) EDIS; // 恢复寄存器保护 EDIS; } } 请帮我找出这段代码timer0CycleCount一直等于0的原因
06-08
<think>好的,用户的问题是关于如何使用DSP实现占空比可调的PWM波形。首先,我需要理解用户的需求。他们可能正在开发嵌入式系统或进行相关项目,需要调整PWM的占空比,可能用于电机控制、LED调光等应用。用户之前提到了使用定时器和按键调整频率和占空比的例子,现在想转向DSP实现,可能希望更高效或更精确的控制。 接下来,我得回忆DSP生成PWM的基本原理。通常,DSP有专门的PWM模块,比如TI的C2000系列中的ePWM模块。这些模块可以通过配置寄存器来设置周期和占空比。占空比调整通常涉及比较寄存器的值,当计数器达到比较值时,输出电平变化。 然后,需要考虑用户可能的开发环境。比如,他们是否使用特定的DSP型号,如TI的TMS320F28335,或者STM32系列?不同的DSP可能有不同的配置方法。但为了通用性,我应该给出一个比较通用的步骤,同时提到参考具体的数据手册。 另外,用户提到了使用定时器产生PWM时波形不稳定的问题,可能在高频时出现。这可能是因为中断处理延迟或计数器配置不当。在DSP中,由于专门的硬件支持,PWM生成更稳定,尤其是在高频率下。因此,需要强调DSP的硬件PWM模块的优势,比如无需CPU干预,自动重载等。 步骤方面,应该分几个关键点:初始化时钟和PWM模块、配置周期和占空比寄存器、设置计数模式、启用输出。可能还需要提到如何动态调整占空比,比如通过修改比较寄存器的值,或者使用中断和DMA传输。 用户还可能关心代码示例,但DSP的代码通常涉及寄存器操作,可能比较复杂。是否需要提供伪代码或基于特定型号的示例?考虑到用户之前有嵌入式开发经验,可能更倾向于具体的代码片段,比如使用TI的库函数或直接配置寄存器。 同时,需要引用用户提供的参考资料,特别是关于定时器配置的部分,但指出DSP的不同之处。例如,DSP的ePWM模块可能提供更灵活的死区控制和更高的分辨率。 最后,生成相关问题时要覆盖DSP的其他应用、优化方法、与普通MCU的区别、中断处理以及高精度控制技巧。这些问题有助于用户进一步探索DSP在PWM生成中的优势和应用场景。</think>[逐步解答] 如何使用DSP实现占空比可调的PWM波形: 1. **硬件配置基础** - DSP芯片(如TI TMS320F28335)内置增强型PWM模块(ePWM),包含时基模块$TB$、计数器比较模块$CC$和动作限定模块$AQ$ - 时钟基准配置公式: $$ f_{PWM} = \frac{f_{SYSCLK}}{(TBPRD + 1) \times 时钟分频系数} $$ 其中$TBPRD$为周期寄存器值[^1] 2. **寄存器配置步骤** - **初始化时基寄存器** ```c EPwm1Regs.TBPRD = 1500; // 设置PWM周期 EPwm1Regs.TBPHS.half.TBPHS = 0; // 相位清零 EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // 增减计数模式 ``` - **配置比较寄存器** ```c EPwm1Regs.CMPA.half.CMPA = 500; // 占空比= CMPA/TBPRD EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // 计数值等于CMPA时置高 EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR; // 计数值等于0时置低 ``` 3. **动态调整实现** - 通过修改CMPA寄存器实时改变占空比: ```c void UpdateDutyCycle(float duty_cycle) { if(duty_cycle > 1.0) duty_cycle = 1.0; if(duty_cycle < 0.0) duty_cycle = 0.0; EPwm1Regs.CMPA.half.CMPA = (uint16_t)(EPwm1Regs.TBPRD * duty_cycle); EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // 更新动作限定 } ``` 4. **关键参数关系** - 占空比计算式: $$ D = \frac{CMPA}{TBPRD} \times 100\% $$ - 分辨率限制: $$ 分辨率 = \frac{1}{TBPRD} \times 100\% $$ : 参考TI官方文档《TMS320x2833x, 2823x Enhanced Pulse Width Modulator (ePWM) Module Reference Guide》
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值