我正在为 ATMega328P 编写一个程序,该程序将从多个 ADC 通道读取数据,将它们组合成一个信号并通过 PWM 输出该信号。
我已经使用单次转换模式成功地将我的 ADC 轮询回退到每通道 50Hz。我使用 Timer/Counter2 生成 PWM,使用 Timer/Counter1 进行计算,以便为 Timer/Counter2 设置比较值。这是定时器/计数器 1 的 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
并将另一个设置为从 ADC 读取,我会得到一个全幅分量波和一个调幅分量波。但是,如果我为硬编码的模拟幅度选择不同的值,我就不那么幸运了(例如)。任何其他值都不会给我 PWM 输出。如果我将两个s 设置为查看同一个 ADC 通道,我会期望两个分量波的幅度调制相同。相反,我没有得到 PWM 输出。对我来说最令人困惑的是,如果我为硬编码幅度选择一个正好是 2 的幂的值,那么一切都很好。sensor_value_1
1024
sensor_value_
1023
sensor_value_
整个二次幂的部分让我觉得这似乎是一个我没有看到的有点棘手的问题。你能看出我肯定错过了什么吗?我会很感激任何提示!
(我已经在这里发布了我的全部资源,以使 SO 上的内容尽可能整洁。)