写代码时,要注意各种类型的使用。
1.
int32_t adc_data[sam_nums];//存放adc数据
存储采样数据的变量是uint16类型的
2.
获取到采样数据后,构造fft函数输入数据,
因为是采样数据,所有只有实数.fft函数的数据的高16位是实数,低16位是虚数且都为int16_t类型.
adc_data[adc_idx] = ((int32_t)uiAdc_val) << 16;
执行fft函数
cr4_fft_256_stm32(fft_out,adc_data,256);
fft函数的输出类型为int32_t.且只有一般数据有用.因此定义数组fft_out
int32_t fft_out[sam_nums/2];//存放fft的结果,结果为复数
获取幅度谱, 因为官网的fft函数输出与输入没有n倍关系,所以使用下面函数后,就得到了时域正弦波的幅度
void GetPowerMag(void)
{
int16_t lX,lY;
float X,Y,Mag;
uint16_t i;
for(i=0; i<sam_nums/2; i++)
{
lX = (fft_out[i] << 16) >> 16; //获取复数的虚部
lY = (fft_out[i] >> 16); //获取复数的实部
//除以32768再乘65536是为了符合浮点数计算规律
X = sam_nums * ((float)lX) / 32768;
Y = sam_nums * ((float)lY) / 32768;
Mag = sqrt(X * X + Y * Y)*1.0/ sam_nums;
if(i == 0)
Magarray[i] = (unsigned long)(Mag * 32768);
else
Magarray[i] = (unsigned long)(Mag * 65536);
if(Magarray[i] > 2048) Magarray[i] = 2048; //限制幅度,避免超出显示范围,干扰其他波形
}
}
5.画出时域波形
//此函数只是用了LCD的高120行
void LCD_DrawWave_c(uint16_t x,uint16_t y)
{
uint16_t i;
static uint16_t bef;//存储上一数据的y坐标
x = 119 - x;
for(i = 0; i < 120; i++)//清除某一列的数据
{
LCD_SetCursor(i,y);
LCD_WriteRAM_Prepare();
LCD_WriteRAM(Black);
}
//当发生突变时,需要将突变轨迹画出来
if(bef > x)//下降
{
LCD_DrawLine(x,y,bef-x+1,Vertical);
}
else//上升
{
LCD_DrawLine(bef,y,x-bef+1,Vertical);
}
bef = x;
}
6.画出幅度谱
//此函数使用了LCD的低120行,且画出来是柱状图
void LCD_DrawWave_d(uint16_t x,uint16_t y)
{
uint16_t i;
for(i = 120; i < 240; i++)//清除某一列的数据
{
LCD_SetCursor(i,y);
LCD_WriteRAM_Prepare();
LCD_WriteRAM(Black);
}
LCD_DrawLine(239-x,y,x+1,Vertical);
}
坐标量化部分不算太难.若有需求可在下方评论区说出.