PR

ATtiny202による正弦波でのノイズ、TCAでも発生

先日の実験では、TCAをPWM、TCBを周期割込みに使った。

今度は、それを逆にしてTCAで周期割込み、TCBでPWMにしてみた。

しかし、これでも前回と同じく、正弦波の下りカーブにノイズが乗る。

TCAとTCBとではPWM出力に使えるピンが違うので、ATtiny202をワイヤ接続。波形が全体的にノイズっぽいのはそのせいか?ATtiny202の電源パスコンはSOP-DIP変換基板上に乗せてある(0.1μF)。アンプを通した聴感上の濁りは前回と同じ。

うーん、なんだろう…?

コード作成には、今回もBingチャットを使った。

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

#define F_CPU 20000000UL

#define N_WAVE  32  /* 正弦波テーブルの数(一周期分) */

unsigned char wave[N_WAVE];  		// 正弦波テーブル
volatile unsigned char i_wave;   // 正弦波テーブルの参照ポインタ


void setup() {
	float unit_deg;
	int i;

	i_wave = 0;
	
	ccp_write_io((void*)&(CLKCTRL.MCLKCTRLB), 0x00);	// クロックプリスケーラ禁止
	
	/* 正弦波テーブル作成 */
	unit_deg = (2.0 * 3.141592) / (float)(N_WAVE);

	for (i = 0; i < N_WAVE; i++) {
		wave[i] = (unsigned int)((((sin(unit_deg * (float)i) + 1.0) / 2.0) * 255.0) + 0.5);
	}

	/* TCA0: 正弦波用PWM周波数設定 */
	TCA0.SINGLE.PER = 255; // PWMの分解能は256
	TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV1_gc | TCA_SINGLE_ENABLE_bm; // プリスケーラは1
	TCA0.SINGLE.CTRLB = TCA_SINGLE_WGMODE_SINGLESLOPE_gc | TCA_SINGLE_CMP0EN_bm; // WG0設定
	TCA0.SINGLE.CMP0 = 127; // PWMのデューティ比は50%
	PORTA.DIRSET = PIN3_bm; // PA3(WG0)を出力に設定


	/* TCB0: 正弦波出力割込み周期設定 */
	TCB0.CCMP = F_CPU / 32000 - 1; // 割り込み周期は32kHz
	TCB0.INTCTRL = TCB_CAPT_bm; // 割り込みを有効にする
	TCB0.CTRLA = TCB_CLKSEL_CLKDIV1_gc | TCB_ENABLE_bm;
	sei();
}


/* 割込みハンドラ: 正弦波出力 */
ISR(TCB0_INT_vect) {
	TCA0.SINGLE.CMP0 = wave[i_wave];

	i_wave++;
	
	if (i_wave >= N_WAVE) {
		i_wave = 0;
	}
	
	TCB0.INTFLAGS = TCB_CAPT_bm; // 割込み要求フラグ解除
}



void loop() {
}


int main() {
	setup();

	while(1) {
		loop();
	}
}

問題切り分けのためにATtiny85で同じことをやってみた。それだと問題なし。

コメント

  1. かまなし より:

    はじめまして.

    ふとこの記事を見かけて&思い当たる節もあり気になったのでこちらでも確認してみました(すでに解決済みかもしれませんが…).

    実験してみたところ,こちらの記事のようにTCA0をPWM波形生成に,TCB0を周期割り込み(PWM波形のDutyを変化させる割り込みの生成)に使う場合,ISR(TCB0_INT_vect)内の
    TCA0.SINGLE.CMP0 = wave[i_wave];

    TCA0.SINGLE.CMP0BUF = wave[i_wave];
    と変更すれば下りカーブで波形が歪むことはなくなるようです.

    下りカーブだけで波形が歪んでいたのは,比較レジスタ(CMP0)を今より小さい値に直接書き換えると,その書き換える瞬間のカウント値によっては一致が起こらなくなりそのPWMの周期中ずっとH出力になってしまうからで,CMP0の代わりにCMP0BUFに書き込むようにするとカウント値がTOP→BOTTOMに戻る瞬間にCMP0が書き換えられるようになりおかしくならない(データシート20.3.3.2節),と思います.

    • jh4vaj より:

      ありがとうございます。
      解決せずに諦めていました。当時の実験機が今はすぐには出てこないのですが、いずれ試してみたいと思います。