【发布时间】:2019-05-20 20:44:42
【问题描述】:
我正在为我大学的第二个项目设计一个通过 atmel mega16 处理器和 CodeVisionAVR 的吉他调音器。我已将单声道插孔连接到处理器的 PINA.7(ADC 转换器)和 GND。我有 7 个 LED (PORTB.0..6),它们应该根据信号基频的频率通过一系列 if/elseif 来打开。
我正在通过 800 个样本的 DFT(我知道有更快的 FT,但我们的大学告诉我们应该使用 DFT,他们知道原因)来获取信号的基本原理。在选择的 800 个样本中,它计算频谱。然后用next for来计算每个频率的绝对值,取最大的一个,可以作为吉他调音师的一个很好的参考点。
Momentairly,我在主函数中只包含了一个大频率条件,以查看 LED 是否亮起,但它没有。
我尝试在整个代码中将 LED 从 0 切换到 6,它似乎停止在 F = computeDft();,所以我删除了变量,让 computeDft(); 运行,但下一个 LED 没有亮起。函数永远不会被调用吗?我已经在 Visual Studio 中使用生成的余弦函数尝试了该函数,并且效果很好。它总是检测基本面。为什么它在 CVAVR 中不起作用?
#define M_PI 3.1415926f
#define N 800
unsigned char read_adc(void)
{
ADCSRA |= 0x40; //start conversion;
while (ADCSRA&(0x40)); //wait conversion end
return (float)ADCH;
}
typedef struct
{
float re;
float im;
} Complex;
float computeDft()
{
unsigned char x[N] = {0};
float max = 0;
float maxi = 0;
float magnitude = 0;
Complex X1[N] = {0};
int n = N;
int k;
for (n = 0; n < N; ++n)
{
for (k = 0; k < n; k++)
{
x[k] = read_adc();
X1[n].re += x[k] * cos(n * k * M_PI / N);
X1[n].im -= x[k] * sin(n * k * M_PI / N);
}
}
for (k = 0; k < n; k++)
{
magnitude = sqrt(X1[k].re * X1[k].re + X1[k].im * X1[k].im);
if (magnitude > maxi)
{
maxi = magnitude;
max = k;
}
}
return max;
}
/*
* main function of program
*/
void main (void)
{
float F = 0;
Init_initController(); // this must be the first "init" action/call!
#asm("sei") // enable interrupts
LED1 = 1; // initial state, will be changed by timer 1
L0 = 0;
L1 = 0;
L2 = 0;
L3 = 0;
L4 = 0;
L5 = 0;
L6 = 0;
ADMUX = 0b10100111; // set ADC0
ADCSRA = 0b10000111; //set ADEN, precale by 128
while(TRUE)
{
wdogtrig(); // call often else processor will reset ;
F = computeDft();
if (F > 50 && F < 200)
{
L3 = 1;
}
}
}// end main loop
我试图实现的结果是来自电话或计算机的信号(可能是一个人调整吉他的 YouTube 视频)通过插孔发送到 AD 转换器 (PINA.7) 中的处理器。主函数调用computeDft; 函数,它将要求read_adc(); 将通过电缆发送的电压值添加到x[k],然后计算它的Dft。然后相同的函数选择基波的频率(具有最高绝对值的频率),然后返回它。在 main 函数内部,一个变量将被分配基频的值,并通过一系列 if 将其值与标准吉他弦频率 82.6、110 等进行比较......
【问题讨论】:
-
computeDft可能需要 7K+ 的堆栈。你有多少堆栈空间? -
1016 字节,我意识到这是问题之一,所以我删除了向量的初始化,现在它占用了 5K,但仍然太多了。我不知道如何制作一个只有 1016 字节的 DFT 调谐器
标签: c avr atmega16 tuner codevisionavr