基于STM32F4的电流检测 (其实就是对输入的电压信号进行FFT计算)
STM32F4 电流检测
1.FFT函数的运算数组定义
代码如下(示例):
//FFT定义
#define FFT_LENGTH 4096 //FFT长度,默认是1024点FFT但这里定义了4096
float fft_inputbuf[FFT_LENGTH*2]; //FFT输入数组
float fft_outputbuf[FFT_LENGTH]; //FFT输出数组
2.ADC读取数据
代码如下(示例): adc_bufmoni[i] 和 adc_bufmoni1[i] 都是4096位 用来存储ADC读取的数据
for(i=0;i<4096;i++)
{
adc_bufmoni[i] = (float)adc_buf[i]/4096*(float)3.3;
adc_bufmoni1[i] = (float)adc_buf[i]/4096*(float)3.3;
}
3.FFT的计算代码
代码如下(示例):
- fft_inputbuf之所以设定为数据长度的两倍是因为还可以输入虚部 但这里不需要 直接输入0
2.tim2用来计算FFT计算速度
3.arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,FFT_LENGTH); //把运算结果复数求模得幅值 在这个运算之后fft_outputbuf已经有了运算结果
arm_cfft_radix4_init_f32(&scfft,FFT_LENGTH,0,1);//初始化scfft结构体,设定FFT相关参
for(i=0;i<FFT_LENGTH;i++)//生成信号序列
{
fft_inputbuf[2*i]=adc_bufmoni[i];
fft_inputbuf[2*i+1]=0;//虚部全部为0
}
TIM_SetCounter(TIM2,0);//重设TIM3定时器的计数器值
timeout=0;
arm_cfft_radix4_f32(&scfft,fft_inputbuf); //FFT计算(基4)
time=TIM_GetCounter(TIM2)+(u32)timeout*65536; //计算所用时间
sprintf((char*)buf,"%0.3fms\r\n",time/1000);
LCD_ShowString(100+12*8,770,80,80,24,buf); //显示运行时间
arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,FFT_LENGTH); //把运算结果复数求模得幅值
4.FFT 的计算结果处理(冒泡排序)(其实还需要加权算法才能更精确)
代码如下(示例):
1.fft_outputbuf[i]是输入数据的一半 2048位。
2.shuju【】是之前定义的结构体用来对fft_outputbuf数据进行处理得到最大值的位置和大小。
3.我这样处理后数据体的num存储的是 频率信息(即fft_outputbuf数组中数的位置)数据体的am存储的是 幅值信息(即fft_outputbuf数组中数的大小)
for(i=0;i<2048;i++)
{
shuju[i].num=i;
shuju[i].am=fft_outputbuf[i];
}
bubble_sort(shuju,2048);
void bubble_sort(struct paixu arr[], int len)
{
int i, j;
float temp;
for (i = 1; i < len - 1; i++)
for (j = 1; j < len - 1 - i; j++)
if (arr[j].am < arr[j + 1].am) {
temp = arr[j].am;
arr[j] = arr[j + 1];
arr[j + 1].am = temp;
temp = arr[j].num;
arr[j].num = arr[j + 1].num;
arr[j + 1].num = temp;
}
}