#include <math.h>
// PS: 采集的最高频率为10k,所以采集频率是20k, 然后是左右交替采集, 所以定时器触发周期是40k
// ---------------------------------------------------------------------------
typedef struct
{
// 采集到的数据
uint16_t m_adc_buffer[256*2];
// 零值(初始化时默认为2048)
int m_adc_zero[2];
// ADC最大幅度
int m_adc_max[2];
// fft输入
int m_fft_src[256];
// fft输出
int m_fft_dst[256];
// 通过fft输出得到的等级 0~8
uint8_t m_level[16];
// 最终等级 0~8 (合并两个通道)
uint8_t m_final_level[16];
// 顶部,用于显示下落效果 0~8
uint8_t m_level_top[16];
uint8_t m_level_down_cnt[16];
} fft_t;
fft_t g_fft;
// 获取fft输入
// ---------------------------------------------------------------------------
static void fft_get_src(uint8_t channel)
{
uint16_t pos = channel;
int min = 65536;
int max = 0;
// m_adc_buffer是两个通道交替采集的数据
while (pos < 512)
{
if (g_fft.m_adc_buffer[pos] < min)
{
min = g_fft.m_adc_buffer[pos];
}
if (g_fft.m_adc_buffer[pos] > max)
{
max = g_fft.m_adc_buffer[pos];
}
g_fft.m_fft_src[pos/2] = g_fft.m_adc_buffer[pos];
pos += 2;
}
// 更新零值
if (max - min < 50)
{
g_fft.m_adc_zero[channel] = (max+min)/2;
}
// 减去零值得到正负值,并移动到高16位
for (pos = 0; pos < 256; pos++)
{
g_fft.m_fft_src[pos] = (g_fft.m_fft_src[pos] - g_fft.m_adc_zero[channel]) << 16;
}
// 更新ADC最大幅度
max = max - min;
if (g_fft.m_adc_max[channel] > max)
{
// 20根据实际效果调整
g_fft.m_adc_max[channel] -= (g_fft.m_adc_max[channel] - max)/20;
}
else
{
g_fft.m_adc_max[channel] = max;
}
}
// 获取最大的模
// ---------------------------------------------------------------------------
static int fft_get_max_mag(uint8_t offset, uint8_t size)
{
int max = 0;
for (uint8_t i = 0; i < size; i++)
{
int16_t real = g_fft.m_fft_dst[offset+i]>>16;
int16_t img = (g_fft.m_fft_dst[offset+i]<<16)>>16;
int mag = (int)sqrt(real*real + img*img);
if (mag > max)
{
max = mag;
}
}
return max;
}
// ---------------------------------------------------------------------------
static const uint8_t s_offsets[17] =
{
0, 1, 2, 3,
5, 8, 11, 14,
19, 26, 34, 42,
50, 65, 80, 100,
128
};
// 获取level
// ---------------------------------------------------------------------------
static void fft_get_level(uint8_t channel)
{
int max_adc = g_fft.m_adc_max[channel];
cr4_fft_256_stm32((void*)g_fft.m_fft_dst, (void*)g_fft.m_fft_src, 256);
for (uint8_t i = 0; i < 16; i++)
{
// 电压过低
if (max_adc < 60)
{
g_fft.m_level[i] = 0;
}
else
{
g_fft.m_level[i] = 16*fft_get_max_mag(s_offsets[i], s_offsets[i+1]-s_offsets[i])/max_adc;
}
if (g_fft.m_level[i] > 8)
{
g_fft.m_level[i] = 8;
}
}
if (channel == 0)
{
for (uint8_t i = 0; i < 16; i++)
{
g_fft.m_final_level[i] = g_fft.m_level[i];
}
}
else
{
for (uint8_t i = 0; i < 16; i++)
{
if (g_fft.m_final_level[i] < g_fft.m_level[i])
{
g_fft.m_final_level[i] = g_fft.m_level[i];
}
}
}
}
// 获取level的顶部
// ---------------------------------------------------------------------------
static void fft_get_level_top(void)
{
for (uint8_t i = 0; i < 16; i++)
{
// 上升
if (g_fft.m_level_top[i] < g_fft.m_final_level[i])
{
g_fft.m_level_down_cnt[i] = 0;
g_fft.m_level_top[i] = g_fft.m_final_level[i];
}
// 下降(15代表先停止一段时间,后面匀速下降)
else if (++g_fft.m_level_down_cnt[i] > 15)
{
g_fft.m_level_down_cnt[i] = 10;
if (g_fft.m_level_top[i] > 0)
{
g_fft.m_level_top[i]--;
}
}
}
}
// 初始化
// ---------------------------------------------------------------------------
void fft_init(void)
{
g_fft.m_adc_zero[0] = 2048;
g_fft.m_adc_zero[1] = 2048;
}
// FFT处理(先决条件是先40k定时触发采集完毕adc数据,然后处理,然后刷LED, 可以通过20ms~25ms(50HZ~40HZ刷新率)定时触发下一次的采集)
// ---------------------------------------------------------------------------
void fft_process(void)
{
fft_get_src(0);
fft_get_level(0);
fft_get_src(1);
fft_get_level(1);
fft_get_level_top();
}
#if 0
0: 78
1: 156
2: 234
3: 312
4: 390
5: 468
6: 546
7: 624
8: 703
9: 781
10: 859
11: 937
12: 1015
13: 1093
14: 1171
15: 1249
16: 1328
17: 1406
18: 1484
19: 1562
20: 1640
21: 1718
22: 1796
23: 1874
24: 1953
25: 2031
26: 2109
27: 2187
28: 2265
29: 2343
30: 2421
31: 2499
32: 2578
33: 2656
34: 2734
35: 2812
36: 2890
37: 2968
38: 3046
39: 3124
40: 3203
41: 3281
42: 3359
43: 3437
44: 3515
45: 3593
46: 3671
47: 3749
48: 3828
49: 3906
50: 3984
51: 4062
52: 4140
53: 4218
54: 4296
55: 4374
56: 4453
57: 4531
58: 4609
59: 4687
60: 4765
61: 4843
62: 4921
63: 4999
64: 5078
65: 5156
66: 5234
67: 5312
68: 5390
69: 5468
70: 5546
71: 5624
72: 5703
73: 5781
74: 5859
75: 5937
76: 6015
77: 6093
78: 6171
79: 6249
80: 6328
81: 6406
82: 6484
83: 6562
84: 6640
85: 6718
86: 6796
87: 6874
88: 6953
89: 7031
90: 7109
91: 7187
92: 7265
93: 7343
94: 7421
95: 7499
96: 7578
97: 7656
98: 7734
99: 7812
100: 7890
101: 7968
102: 8046
103: 8124
104: 8203
105: 8281
106: 8359
107: 8437
108: 8515
109: 8593
110: 8671
111: 8749
112: 8828
113: 8906
114: 8984
115: 9062
116: 9140
117: 9218
118: 9296
119: 9374
120: 9453
121: 9531
122: 9609
123: 9687
124: 9765
125: 9843
126: 9921
127: 9999
#endif