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.
工具/软件:Code Composer Studio
我正在尝试在 TMS320f28377S 上获取50Hz 的实时256点 FFT 信号。 采样频率为1.6KHz。 频率分辨率为6.25Hz。 因此、在 FFT 输出(RFFToutBuff)中、8号样本应提供50Hz 信号的脉冲性质、但我获得的 FFT 输出的所有256个样本值都在[2、-2]范围内。
我也不能检查天气,我的 epwm1给了我频率为1.6KHz 的时钟。
请指导我检查 epwm1以及更好的 FFT 输出所需的更改。
谢谢你
Bhavesh
FFT 代码:-
//文件:adc_soc_ePWM_cpu01.c
//文件:Voltmeto_FFT.c
//标题:针对 F2837xS 通过 ePWM 触发 ADC。
//
//! addtogroup cpu01_example_list
//!
#include "F28x_Project.h"//器件头文件和示例 include 文件
#include
#include
#include
#include
#include
#include
#include
#include
#include "fpu_rfft.h"
#include "FPU_FFT_Hann.h"
#include "FPU_FFT_hamming.h"
#include "FPU_FFT_flattop.h"
#include "FPU_FFT_Blackman.h"
#include "FPU_FFT_blackmanharris.h"
#include "FPU_FFT_rect.h"
#define RFFT_STACages 8.
#define RFFT_SIZE (1 << RFFT_STOPENAINSages)
#define NPP 16.
#define UART0_BASE 0x7200
//RFFT_ADC_F32_struct rfft_ADC;
//RFFT_ADC_F32_struct_handle HND_rfft_ADC =&rfft_ADC;
RFFT_F32_struct rfft;
RFFT_F32_struct_Handle HND_rfft =&rfft;
#pragma DATA_SECTION (RFFTin1Buff、"RFFTdata1");
float32 RFFTin1Buff[RFFT_SIZE];
#pragma DATA_SECTION (RFFToutBuff、"RFFTdata2");
float32 RFFToutBuff[RFFT_SIZE];
#pragma DATA_SECTION (RFFTmagBuff、"RFFTdata3");
float32 RFFTmagBuff[RFFT_SIZE/2];
#pragma DATA_SECTION (RFFTF32Coef、"RFFTdata4");
float32 RFFTF32Coef[RFFT_SIZE];
#pragma DATA_SECTION (Power、"RFFTdata5");
float32 Power[RFFT_SIZE/2];
//#pragma DATA_SECTION (PeakValueFFT、"RFFTdata6");
//float32 PeakValueFFT[RFFT_SIZE/2];
//#pragma DATA_SECTION (ADCin1Buff、"RFFTdata7");
//float32 Buffer_Signal_Scaled[RFFT_SIZE];
#pragma DATA_SECTION (ADCin1Buff、"RFFTdata7");
uint16_t ADCin1Buff[RFFT_SIZE];
#pragma DATA_SECTION (Buffer_Signal_Scaled、"RFFTdata8");
float32 Buffer_Signal_Scaled[RFFT_SIZE];
//const float RFFTWindow[RFFT_SIZE/2]= RECT2048;
void ConfigureADC (void);//ADC、PWM
void ConfigureEPWM (void);
void SetupADCepwm (uint16通道);
//void RFFT_F32_win (float * pbuffer、float * pWindow、uint16_t size);//fdt
//void RFFT_F32_MAG (RFFT_F32_struct*);
//void PowerSpectrumCompute (void);
void FFT (void);
//void useuart (void);//uart
中断 void adca1_ISR (void);//ADC ISR
void Set_Sample_Frequency (float FS);//获取并详细说明
//静态浮点真有效值(浮点信号[]、常量 int dim、浮点频率、浮点 FS);
void PeakValueCompute (void);
//静态浮点 Frequency_Compute (const float Power_Spectrum[]、const float fs、const int FFT_size、const unsigned int Max_Index);
void AcquireSignal (void);
void scale_input_buffer (void);
uint16结果索引;
易失性 uint16 bufferFull;
float RMS_value = 0;
浮点频率;
浮点 FSample、FSample_default;
unsigned int Max_Index = 0;
volatile char state = 0;
//unsigned int msg1len;//= strlen (msg1);
//初始化 UART。 设置波特率、数据位数、关闭奇偶校验、停止位数和记忆棒模式。
//uint32_t param1 =(uint32_t)&SciaRegs;// 0x00007210;
//uint32_t 参数2 =(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_LEON);
//uint32_t PARAM3 = 50000000;
//UARTConfigSetExpClk (param1、paramM3、10000、param2);
//启用 UART。
void main (void)
{
//步骤1. 初始化系统控制:
// PLL、安全装置、启用外设时钟
//此示例函数位于 F2837xS_SYSCTRL.c 文件中。
InitSysCtrl();
//步骤2. 初始化 GPIO:
//此示例函数位于 F2837xS_GPIO.c 文件和中
//说明了如何将 GPIO 设置为其默认状态。
InitGpio();//针对此示例跳过
//步骤3. 清除所有中断并初始化 PIE 矢量表:
//禁用 CPU 中断
Dint;
//将 PIE 控制寄存器初始化为默认状态。
//默认状态为禁用所有 PIE 中断和标志
//被清除。
//此函数位于 F2837xS_PIECTRL.c 文件中。
InitPieCtrl();
//禁用 CPU 中断并清除所有 CPU 中断标志:
IER = 0x0000;
IFR = 0x0000;
//使用指向 shell 中断的指针初始化 PIE 矢量表
//服务例程(ISR)。
//这将填充整个表,即使是中断也是如此
//在本例中未使用。 这对于调试很有用。
//可以在 F2837xS_DefaultIsr.c 中找到 shell ISR 例程
//此函数可在 F2837xS_PieVect.c 中找到
InitPieVectTable();
//映射 ISR 函数
EALLOW;
PieVectTable.ADCA1_INT =&adca1_ISR;//针对 ADCA 中断1的函数
//PieVectTable.XINT3_INT =&xint3_ISR;
EDIS;
//配置 ADC 并为其加电
ConfigureADC();
//配置 ePWM
ConfigureEPWM();
//Setup the ADC for ePWM triggered Conversions on channel 0
SetupADCepwm (4);
//启用全局中断和更高优先级的实时调试事件:
IER |= M_INT1;//启用组1中断
EINT;//启用全局中断 INTM
ERTM;//启用全局实时中断 DBGM
resultsIndex = 0;
bufferFull = 0;
//hnd_rfft_adc->尾线=&(hnd_rfft->OutBuf);
hnd_rfft->FFTize = RFFT_SIZE;//FFT 大小
hnd_rfft->FFTStage = RFFT_STA期;//FFT 级
hnd_rfft->InBuf =&RFFTin1Buff[0];//输入缓冲器(12位 ADC)输入
hnd_rfft->OutBuf =&RFFToutBuff[0];//输出缓冲区
hnd_rfft->CosSinBuf =&RFFTF32Coef[0];//Twiddle 因子
hnd_rfft->MagBuf =&RFFTmagBuff[0];//幅度输出缓冲区
//在 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交叉点使能
PieCtrlRegs.PIEIER1.bit.INTx1 = 1;//启用 PIE 中断
//SYNC ePWM
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC=1;
//循环无限地进行转换
操作
{
DELAY_US (10000);//原始延迟10000
AcquireSignal();//获取信号
scale_input_buffer();
memcpy_fast (Buffer_Signal_Scaled、RFFTin1Buff、RFFT_SIZE* sizeof (float));
FFT();//FFT 计算
//PowerSpectrumCompute ();//Power spectrum
//Freq =频率计算(功率、FSample、RFFT_SIZE、Max_Index);
//RMS_value =真有效值(Buffer_Signal_Scaled、RFFT_Size、Freq、FSample);
//中断;
//asm (" ESTOP0");
} while (1);
}
//写入 ADC 配置并为 ADC A 和 ADC B 加电
空配置 ADC (空)
{
EALLOW;
//写入配置
AdcaRegs.ADCCTL2.bit.prescale = 6;//将 ADCCLK 分频器设置为/4
//AdcSetMode (ADC_ADCA、ADC_Resolution 12位、ADC_SIGNALMODE_SINGLE);
AdcaRegs.ADCCTL2.bit.resolution = 0;// 12位分辨率
AdcaRegs.ADCCTL2.bit.SIGNALMODE = 0;//单端通道转换(仅12位模式)
AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;//将脉冲位置设置为晚期
AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;//为 ADC 加电
DELAY_US (1000);//延迟1ms 以允许 ADC 加电时间
EDIS;
}
空配置 EPWM (空)
{
EALLOW;
//假设 ePWM 时钟已启用
EPwm1Regs.ETSEL.bit.SOCAEN = 0;//禁用组上的 SOC
EPwm1Regs.ETSEL.bit.SOCASEL = 4;//在递增计数时选择 SOC
EPwm1Regs.ETPS.bit.SOCAPRD = 1;//在发生第一个事件时生成脉冲
EPwm1Regs.CMPA.bit.CMPA = 781;
EPwm1Regs.TBPRD = 1562;
EPwm1Regs.TBCTL.bit.CTRMODE = 2;//加减计数器
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0;
EPwm1Regs.TBCTL.bit.CLKDIV = 2;
EDIS;
}
void SetupADCepwm (uint16通道)
{
//选择要转换的通道和转换结束标志
EALLOW;
AdcaRegs.ADCSOC0CTL.bit.CHSEL = 1;//SOC0将转换引脚 A0 //引脚29 adcA1
AdcaRegs.ADCSOC0CTL.bit.ACQPS = 14;//采样窗口为100个 SYSCLK 周期
AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5;// ePWM1 SOCA/C 上的触发
AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0;// SOC0结束将设置 INT1标志
AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;//启用 INT1标志
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//确保 INT1标志被清除
}
中断 void adca1_ISR (void)
{
ADCin1Buff[resultsIndex++]=(AdcResultRegs.ADCRESULT0);
if (RFFT_SIZE<=结果索引)
{
resultsIndex = 0;
bufferFull = 1;
}
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//清除 INT1标志
PieCtrlRegs.PIEACX.ALL = PIEACK_Group1;
}
无效电爆信号(空)
{
//启动 ePWM
EPwm1Regs.ETSEL.bit.SOCAEN = 1;//启用 SOCA
EPwm1Regs.TBCTL.bit.CTRMODE = 2;//取消冻结,并进入向上计数模式//原始=0
//等待、而 ePWM 导致 ADC 转换、然后导致中断、
//填充结果缓冲区,最终设置 bufferFull
//flag
while (!bufferFull);
bufferFull = 0;//清除缓冲区已满标志
//停止 ePWM
EPwm1Regs.ETSEL.bit.SOCAEN = 0;//禁用 SOCA
EPwm1Regs.TBCTL.bit.CTRMODE = 2;//冻结计数器(3)//递增/递减计数器(2)
}
void FFT (void)
{
RFFT_f32u (HND_rfft);
RFFT_F32_MAG_TMU0 (HND_RFFT);
}
void Set_Sample_Frequency (float FS)
{
unsigned int TBPRD = 0;
unsigned int CMPA = 0;
//TBPRD =(unsigned int)((rnd_sp_RS (200000000.0/(4*FS)-1)));
// CMPA =(unsigned int)((rnd_sp_RS (((TBPRD/2.0)-1)));
EPwm1Regs.CMPA.bit.CMPA = 781;
EPwm1Regs.TBPRD = 1562;
EPwm1Regs.TBCTL.bit.CTRMODE = 2;//加减计数器
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0;
EPwm1Regs.TBCTL.bit.CLKDIV = 2;
}
void scale_input_buffer (void)
{
size_t k;
对于(k = 0;k <(RFFT_SIZE);k = k+2)
{
RFFTin1Buff[k]= 0.000732421875*ADCin1Buff[k]-1.5;
RFFTin1Buff[k+1]= 0.000732421875*ADCin1Buff[k+1]-1.5;
}// 0.000732421875 = 3/4096 (3V ADC 基准)
}