【发布时间】:2011-10-22 20:47:28
【问题描述】:
我正在为 ATMega328P 编写一个程序,该程序将从多个 ADC 通道读取读数,将它们组合成一个信号并通过 PWM 输出该信号。
我已使用单次转换模式成功地将我的 ADC 轮询回退到每通道 50Hz。我使用 Timer/Counter2 生成 PWM,使用 Timer/Counter1 进行计算,以便为 Timer/Counter2 设置比较值。这是 Timer/Counter1 的 ISR:
// Interrupt service routine called to generate PWM compare values
ISR(TIMER1_COMPA_vect)
{
// Grab most recent ADC reading for ADC0
uint32_t sensor_value_0 = adc_readings[0];
// Get current value for base waveform from wavetable stored in sinewave_data
uint32_t sample_value_0 = pgm_read_byte(&sinewave_data[sample_0]);
// Multiply these two values together
// In other words, use the ADC reading to modulate the amplitude of base wave
uint32_t sine_0 = (sample_value_0 * sensor_value_0) >> 10;
// Do the same thing for ADC2
uint32_t sensor_value_1 = adc_readings[1];
uint32_t sample_value_1 = pgm_read_byte(&sinewave_data[sample_1]);
uint32_t sine_1 = (sample_value_1 * sensor_value_1) >> 10;
// Add channels together, divide by two, set compare register for PWM
OCR2A = (sine_0 + sine_1) >> 1;
// Move successive ADC base waves through wavetable at integral increments
// i.e., ADC0 is carried by a 200Hz sine wave, ADC1 at 300Hz, etc.
sample_0 += 2;
sample_1 += 3;
// Wrap back to front of wavetable, if necessary
if (sample_0 >= sinewave_length) {
sample_0 = 0;
}
if (sample_1 >= sinewave_length) {
sample_1 = 0;
}
} // END - Interrupt service routine called to generate PWM compare values
我的问题是我没有得到 PWM 输出。如果我将sensor_value_0 或sensor_value_1 设置为1024 并将另一个sensor_value_ 设置为从ADC 读取,我会得到一个全幅度分量波和一个幅度调制分量波。但是,如果我为硬编码的模拟幅度选择不同的值,我就没有那么幸运了(例如,1023)。任何其他值都不会给我 PWM 输出。如果我将 both sensor_value_s 设置为查看同一个 ADC 通道,我会期望两个分量波的幅度调制相同。相反,我没有得到 PWM 输出。最让我困惑的是,如果我为硬编码幅度选择一个正好是 2 的幂的值,那么一切都很好。
整个二次幂部分让我觉得这是一个我没有看到的有点棘手的问题。你能看出我肯定错过了什么吗?如果有任何提示,我将不胜感激!
(我已经发布了我的整个源代码 here 以使 SO 上的内容尽可能整洁。)
【问题讨论】:
标签: c bit-manipulation arduino avr avr-gcc