0

2 つの異なるアナログ値を 10 ビットの解像度で出力したいと考えています。つまり、dac_value の範囲は 0 ~ 1023 です。ATmega16 を外部水晶 4MHz で使用しています。出力に RC フィルターを接続してみましたが、何も変わりませんでした。私は常に出力がゼロになっています。誰か助けてもらえますか??

#include <avr/io.h>
#include <avr/interrupt.h>

void initPWM()
{
  TCCR1A |= (1<<WGM11) | (1<<WGM10) | (1<<COM1A1) | (1<<COM1A0) | (1<<COM1B1) | (1<<COM1B0) ;
  TCCR1B |= (1<<WGM12) | (1<<CS10);
}


    uint16_t dac_value1 = 100, dac_value2 = 200;
int main(void)
{
    initPWM();
      while(1) {
      OCR1A = dac_value1;
      OCR1B = dac_value2;
          }
     for (;;) {}

 }
4

1 に答える 1

1

間違ったビットを間違ったレジスタに割り当てています。明確にするために:PWMはアナログ出力ではありません。ハイまたはローの出力状態をすばやく変更します。PWM 値は、タイマー期間内に出力が各状態 (ハイまたはロー) にある時間を決定します。

「アナログ」出力を作成する場合は、出力信号をフィルタリングする必要があります。たとえば、RC フィルターを通過させる必要があります。また、出力をできるだけ高速にする必要があります。つまり、より低いプリスケーラーを選択する必要があります。高速 PWM モード。現在の構成では、1024 プリスケーラーで pwm が得られます。つまり、毎秒 4 周期未満のタイマーです。

したがって、プリスケーラ 1 (3906 Hz の出力が得られる) で高速 pwm を反転出力 (つまり、OCR1x 値が高いほど出力値が低くなる) に割り当てる場合、次のようになります。

void initPWM()
{
    TCCR1A = (1<<WGM11) | (1<<WGM10) | (1<<COM1A1) | (1<<COM1A0) | (1<<COM1B1) | (1<<COM1B0); 
    // here bits WGM10 WGM11 (with WGM12 in TCCR1B) will select the Fast PWM mode with 10 bit resolution; 
    // COM1A1 COM1A0 COM1B1 COM1B0 select an inverted PWM output on pins OC1A OC1B
    TCCR1B = (1<<WGM12) | (1<<CS10);
    // CS10 will select  1:1 prescaler (i.e. 4000000/1024 timer periods per second)

    // Also, your PWM output will not be visible on corresponding pins, unless you will configure an DDR bits for these pins to output. Those pins are PD5 and PD4 on ATmega16
    DDRD |= (1 << 4) | (1 << 5);
}

次に考慮する必要があるのは、アプリケーションの main()関数の実行が終了すると、リセット ベクターにジャンプすることです。したがって、空のループを main() の最後に置きます。

int main(void)
{
    uint16_t dac_value1, dac_value2;
    dac_value1 = 123; // do not forget to init variables!!!
    dac_value2 = 987; 
    initPWM();
    OCR1A = dac_value1;
    OCR1B = dac_value2;
    for(;;) {
        // main loop. Now it's empty
    } 
}
于 2015-06-04T22:14:00.357 に答える