方法一:使用CCS软件的clock功能。
使用步骤:首先打开clock功能,Run->Clock>Enable;
左下角有个小图标出现
,双击可以清零。
在要测试的代码上打两个断点,分别运行到两个断点处,就可以看到运行的周期了。
使用公式 time = 1/CLK可以算得程序运行时间。(CLK为时钟主频,28335是 150M,28377是200M;或者28335直接周期*6.67ns,28377直接周期*5ns)。
例如时钟周期为150MHz,测得数据为1000,则代码运行时间
time = 1000 * (1/150,000,000) = 6.67 μs。
方法二:在测试程序的开始时和结束时加一个GPIO口,开始让其置位,结束让其复位,用示波器量波形时间。
如何验证定时器中断时间是否准确?
1、在中断程序中,翻转一个GPIO口的输出电平,用示波器观察波形。
2、还有一种方法就是在中断程序里第一条指令打个断点,使能ccs的clock功能,看每进一次中断用了多少clock。
实测数据:28335开发板为例
定时器设置为 ConfigCpuTimer(&CpuTimer0, 150, 1000000); //1S,在定时器中断打断点,进一次中断周期数为150_000_000,计算可得:150_000_000*(1/150_000_000) = 1s。
PWM中断:TBPRD = 100,f = 375kHz,T = 2.67us,2.67us/6.67ns=400 ,实测394,401,399;
TBPRD = 50, f = 750kHz,T =1.33us,1.33us/6.67ns=200,第一次实测194,进第80次中断时,实测为15894,与理论值200*80=16000相差106个系统时钟周期,约707ns,随着程序运行,偏差会越来越大。到第1373862次中断,即1.8秒左右,实测系统周期数274779506,理论274772400,偏差7106个系统时钟周期,约7106*6.67ns=47us。
测试:28335的PWM中断TBPRD = 25时 ,75M/2 = 37.5M,37.5M/25=1.5M,即中断频率
f = 1.5M,系统时钟为
,与理论值150_000_000不符,每秒比实际慢8992542*6.67ns=0.06s。(不可用,在中断时间内执行不完中断程序,比如中断周期800ns,中断程序所需时间700ns或更长)
PWM中断空程序,执行一次需要12个系统时钟周期,约12*6.67ns = 80ns;
TBPRB = 15, f= 2,5M, T =400ns,程序所需时间36*6.67ns = 240ns,正常进中断;
TBPRB = 10, f= 3.75M, T =266ns,程序所需时间36*6.67ns = 240ns,中断实际用时210_000_000*6.67ns = 1.4s;程序执行不完,程序用时和T太接近了,可能还有其他芯片内置程序,需预留时间。
程序运行时间缩短为180ns,还是执行不完,系统周期由210_000_000缩短为176_250_032。
TBPRB = 12, f= 3.125M, T =320ns,程序所需时间27*6.67ns = 180ns,程序正常执行;
TBPRB = 11, f= 3.41M, T =293ns,程序所需时间27*6.67ns = 180ns,中断实际用时160_227_327*6.67ns = 1.069s;程序执行不完,程序用时和T太接近了,可能还有其他芯片内置程序,需预留时间。
PWM配置程序:
void ConfigureEPWM()
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; //禁止EPWM时钟
// SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1; // ePWM6
//TBPRD=100 f=375k T=2.67us 2.67us/6.67ns=400
//TBPRD=50 f=750k T=1.33us 1.33us/6.67ns=200
EPwm1Regs.TBPRD = 25; // 频率为10kHz,周期是100us 1.875M
EPwm1Regs.TBPHS.half.TBPHS = 0x0000; // 相位为0
EPwm1Regs.TBCTR = 0x0000; // 清除计数器的值
EPwm1Regs.TBSTS.all = 0;
// Setup TBCLK
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // 增减计数
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV2; // 高速基准时钟分频
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1; // 基准时钟分频 TBCLK=150/2*1=75M
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_IMMEDIATE; //CMPA寄存器采用直接模式
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_IMMEDIATE; //CMPB寄存器采用直接模式
// Setup compare
EPwm1Regs.CMPA.half.CMPA = 0; //初始占空比为50%
EPwm1Regs.CMPB = 0;
// Set actions
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; //当CTR=CMPA且增计数时,EPWMA输出高电平
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR; //当CTR=CMPA且减计数时,EPWMA输出低电平
EPwm1Regs.AQCTLB.bit.CAU = AQ_SET; //当CTR=CMPA且增计数时,EPWMB输出高电平
EPwm1Regs.AQCTLB.bit.CAD = AQ_CLEAR; //当CTR=CMPA且减计数时,EPWMB输出低电平
EPwm1Regs.AQSFRC.all = 0; //动作限定软件强制寄存器
EPwm1Regs.AQCSFRC.all = 0; //动作限定软件连续强制寄存器
//Active Low PWMs - Setup Deadband
EPwm1Regs.DBCTL.bit.OUT_MODE = DBB_ALL; //使能上升沿和下降沿
EPwm1Regs.DBCTL.bit.IN_MODE = DBB_ENABLE; //EPWMA作为上升沿延时,EPWMB作为下降沿延时
EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; //EPWMB反转极性
EPwm1Regs.DBRED = 75; //死区时间1us
EPwm1Regs.DBFED = 75;
// Interrupt where we will change the Deadband
EPwm1Regs.ETSEL.bit.INTEN = 1; // EPWM中断使能
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_PRD; // 中断事件:TBCTR=TBPRD
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; // 每发生一次事件,产生一次中断
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;
}
PWM中断程序:
interrupt void EPWM_INT(void)
{
state_cnt++;
if(state_cnt == 1500000) //1S计时
{
min_cnt++;
state_cnt = 0;
}
if(min_cnt == 20) //20S计时
{
min_cnt = 0;
}
EPwm1Regs.ETCLR.bit.INT = 1; //清除中断标志位
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; //响应同组中断
}
PWM中断空程序,需要时间80ns,预留150ns,150ns+80ns = 230ns,用200ns算,
极限:TBCTR = 8, f = 4.687M,T = 213ns。(实际使用没有意义)
结论:
- 程序运行时间与T相差最少为150ns,才能保证程序的正常运行。
- DSP28335空程序极限时钟频率4.687M。
妙啊!!!