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.

[参考译文] CCS/LAUNCHXL-F2.8377万S:FIR_F32 FPU问题

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/575502/ccs-launchxl-f28377s-fir_f32-fpu-problem

部件号:LAUNCHXL-F2.8377万S

工具/软件:Code Composer Studio

大家好,

我在使用FPU FIR过滤器库时遇到了一些问题。

我遵循了"应用程序编程接口(FPU)"的示例(2015年6月2日PAG 78)

在我的代码中,我有 float32 RFFTin1Buff[RFFT_size]输入缓冲区(包含以伏特计的ADC样本)和 float32 sigOut[RFFT_size](过滤信号),其中RFFT_size为2048。

问题是sigOut始终为0向量。 有人遇到过类似问题?

FPU库的版本是:V1_50_00_00

非常感谢,

Paolo

//........ FIR滤波器设置..........
#define FIR_ORDER 511
#pragma DATA_SECection(firfp,"firfilt")
FIR_FP FIRFP = FIR_FP_DEFAULTS;

FIR_FP_HANDLE HND_FIRFP =&FIRFP;

#pragma DATA_SECection(dbuffer,"firldb")
float32 dbuffer[FIR_ORD+1];

//#pragma DATA_SECection(pragma
#pragma data_section(sigout,"sigout");
//float sigin[signal_length];-->我选择RFFTin1Buff[RFFT_size]作为我的输入缓冲
区flat32 sigOut[RFFT_size];

#pragma data_section(coeff,"coefffilt");








{ pfr_void_fr/fr_fr_1;{ pfrfi=512_feefr/fr_fi_fr_1){ p_fi_fr_fr_fr/ fe1...............fir {{



初始化系统控制:
// PLL,看门狗,启用外设时钟
//此示例功能可在F2837xS_sysctrl.c文件中找到。
InitSysCtrl();//

步骤2. 初始化GPIO:
//此示例函数可在F2837xS_GPIO .c文件中找到,
//说明了如何将GPIO设置为其默认状态。
此示例跳过InitGpio();//


//步骤3. 清除所有中断并初始化PIE矢量表:
//禁用CPU中断
dint;

//将PIE控制寄存器初始化为其默认状态。
//默认状态是禁用所有PIE中断,
并清除标志//。
//此函数位于F2837xS_PIECTRL.c文件中。
InitPieCtrl();

SetPinLCD();//setta i pin per il显示器
initialize_lcd();
HOME_LCD();//

禁用CPU中断并清除所有CPU中断标志:
IER = 0x0000;
IFR = 0x0000;

//使用指向shell Interrupt
//服务例程(ISR)的指针初始化PIE矢量表。
//这将填充整个表,即使在此
示例中未使用中断//。 这对于调试非常有用。
// shell ISR例程位于F2837xS_DefaultIsr.C.中
//此函数位于F2837xS_PieVect.C.中
InitPieVectorTable();





//Map ISR函数
EALLOW;
PieVectorTable.ADCA1_INT =&adca1_ISR;// ADCA中断1的函数
PieVectorTable.XINT3_INT =&xint3_isr;
EDIS;

//配置ADC并开机
ConfigureADC();//

配置ePWM
ConfigureEPWM();

//在通道0上设置ePWM触发转换的ADC
SetupADCEpwm(0);



//启用全局中断和较高优先级的实时调试事件:
IER || M_INT1;//启用组1中断
EINT;//启用全局中断INTM
ERTM;//启用全局实时中断DBGM


结果索引=0;
缓冲器全轮= 0;



hnd_rfft->FFTSize = RFFT_SIZE;//FFT大小
hnd_rfft->FFTStages = RFFT_stages;//FFT stages
hnd_rfft->InBuf =&RFFTin1Buff[0];//输入缓冲区(12位ADC)输入
hnd_rfft->OutBuf =&RFFToutBuff[0];//输出缓冲区
HND_rfft->CosSinBuf =&RFFTF32Coef[0];//twiddle因子
hnd_rfft->MagBuf =&RFFTmagBuff[0];//幅值输出缓冲区
RFFT_F32_Sincostable (HND_rfft);//计算宽度因子

/* FIR通用过滤器初始化*/
hnd_firfp->order = FIR_ORDER;
hnd_firfp->dbuffer_ptr = dbuffer;
hnd_firfp->coeff_ptr =(float *) coeff;
hnd_firfp->init(Hnd_firfp);


//在PIE中启用Xint3:组12中断1
PieCtrlRegs.PIECTRL.bit.ENPIE =1;//启用PIE块
PieCtrlRegs.PIEIER12.bit.INTx1= 1;//启用PIE组12 INTx1
IER || M_INT12;//启用CPU INT12
EINT;//启用全局中断


XintRegs.XINT3CR.bit.POLARITY = 2;//下降边缘
XintRegs.XINT3CR.bit.enable = 1;//XINT3 interrpt enable


GPIO_SetupXINT3Gpio(60);//GPIO60 SU XINT3



//启用PIE中断
PieCtrlRegs.PIEIER1.bit.INTx1 = 1;

//sync ePWM
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;


//无限循环转换
做

{

	AcquitreSignal();
FFT();

对于(i = 0;i < RFFT_SIZE;I++)
{
hnd_firfp->input = RFFTin1Buff[i];
hnd_firfp->calc (&firfp);
sigOut[i]= hnd_firfp->output;

}



ASM(" ESTOP0");
}While(1);


}

中断无效adca1_ISR(void)
{
	
	RFFTin1Buff[resultsIndex++]=(AddaResultRegs.ADCRESULT0)*((FLOW)3/SLL);
	IF(RFTB_size=){ resultsGroupCA=0;
	
		
		
	

	ft1.CT1; f1 =清除
	缓冲



区=1;缓冲区=1;缓冲区=1;缓冲区=1;缓冲区=1CA1= 1;缓冲区=1;缓冲区=1= 1= 1= 1= 1;缓冲区=1=缓冲区=1CA1= 1;缓冲区=1=缓冲区=1=缓冲区=1= 1= 1=缓冲区=1;缓冲区=1CAPEEPT1= 1= 1=缓冲区=1= 1= 1=缓冲区=1=缓冲区=1=缓冲区=1=缓冲区=1=缓冲区=1= 1=缓冲区=1=缓冲

	
	
	//取消冻结,进入上计数模式


	//等待,而ePWM导致ADC转换,然后导致中断,
	//填充结果缓冲区,最终设置缓冲区全
//flag
	while (!bufferFull);
	bufferFull = 0;//清除缓冲区全标志

	//停止ePWM
	EPwm1Regs.ETSEL.bit.SOCAEN = 0;//disable SOCA
	EPwm1Regs.TBCTL.bit.CTRMODE = 3;//freeze counter

} 

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

    您好,Paolo:

    能够逐步浏览FIR计算代码,并在计算时查看这些值。 由于代码在汇编中,您必须通过“拆分”窗口执行此操作。  

    另一个要检查的事情是,每次调用calc()时,最新的输入都放在dbuffer[0],而旧的输入向前移动一个,因此您应该能够通过内存浏览器查看dbuffer来检查这一点。

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

    您好,Vishal,

    非常感谢您的回答。

    我理解问题,程序仅在重置时正确运行(While循环的一次迭代)

    一旦程序进入DO-while无限循环,不再起作用:在sigOut向量被0值替换之前,则保留0值。

    可能解决方案总是在新采集前重复FIR初始化,但我觉得这个解决方案不是很好。

    你怎么看,Vishal?

    谢谢你

    Paolo。

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

    Paolo Marsilia 说:
    当然,解决方案总是在新收购前重复FIR初始化,但我觉得这个解决方案不是很好。[/QUOT]

    不能,只能在循环之外运行一次init。 init函数将把dbuffer归零。  

    原始ADC输入是否正确(如果删除了滤波和FFT)? 您收到的信号是什么?

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

    您好,Vishal,

    该问题与我在同一项目上遇到的另一个问题有关: https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/575005</s>57.5005万

    我使用了float32 RFFTinbuffer,但第一个样本总是错误的。 如果我使用UINT32或uint16_t,问题似乎消失了,但我希望看到更好的。

    我随时向你通报情况。

    非常感谢,

    Paolo

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

    您好,Paolo:

            AcquireSignal();
            FFT();
          for(i = 0; i < RFFT_SIZE; i++)
            {
               hnd_firFP->input = RFFTin1Buff[i];
               hnd_firFP->calc(&firFP);
               sigOut[i] = hnd_firFP->output;
            }
    您是否在过滤信号之前运行FFT? 请注意,运行RFFT将破坏RFFTin1Buff的原始内容
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,Vishal,
    是的,我在过滤之前运行FFT(),所以我正在处理损坏的RFFTinBuff...

    好的,我将在FFT子例程中使用RFFTinBuffr的副本,我只需要测量基本频率,而不是所有频谱。

    我将尽快修改代码并随时通知您。

    非常感谢,
    Paolo。