void process_samples(void) {
// 循環讀取 ADC 緩存中的數據,存儲到樣本緩存中
unsigned int i;
for (i = 0; i < SAMPLE_BUFFER_SIZE; i++) {
// 等待 ADC 轉換完成
while (!ADC_OUTPUT_BUFFER);
// 計算樣本緩存中的平均值
unsigned long sum = 0;
for (i = 0; i < SAMPLE_BUFFER_SIZE; i++) {
sum += sample_buffer[i];
}
unsigned int average = sum / SAMPLE_BUFFER_SIZE;
// 將樣本緩存中的數據減去平均值,並將其存儲到 FFT 緩存中
for (i = 0; i < SAMPLE_BUFFER_SIZE; i++) {
fft_buffer[i] = sample_buffer[i] - average;
}
}
// FFT 函數的實現
void fft(unsigned int *data, unsigned int n, unsigned char *window) {
unsigned int i;
unsigned char j, k, m;
unsigned int n1, n2;
unsigned int t1, t2;
unsigned int c1, c2;
unsigned int xt, yt, xp, yp;
unsigned int id, id1, id2;
unsigned int rad;
unsigned int tr, ti;
// 對數據應用漢明窗
for (i = 0; i < n; i++) {
data[i] = data[i] * window[i];
}
// 執行快速傅里葉變換
j = 0;
n2 = n / 2;
for (i = 0; i < n - 1; i++) {
if (i < j) {
xt = data[j];
data[j] = data[i];
data[i] = xt;
}
k = n2;
while (k <= j) {
j -= k;
k /= 2;
}
j += k;
}
n1 = 0;
n2 = 1;
for (i = 0; i < log(n) / log(2); i++) {
n1 = n2;
n2 = n2 * 2;
rad = 0x4000 / n1;
for (j = 0; j < n1; j++) {
c1 = cos_fixed_point(rad * j);
c2 = sin_fixed_point(rad * j);
for (k = j; k < n; k += n2) {
id = k + n1;
xt = mul_fixed_point(c1, data[id]) - mul_fixed_point(c2, data[id + 1]);
yt = mul_fixed_point(c2, data[id]) + mul_fixed_point(c1, data[id + 1]);
data[id] = data[k] - xt;
data[id + 1] = data[k + 1] - yt;
data[k] = data[k] + xt;
data[k + 1] = data[k + 1] + yt;
}
}
}
}
// 固定小數點乘法的實現
unsigned int mul_fixed_point(unsigned int a, unsigned int b) {
unsigned long c = (unsigned long)a * b;
return (unsigned int)(c >> 15);
}