PR

ATtiny85での正弦波はきれい

ATtiny202で正弦波を作るとノイズが乗るので、問題の切り分けのためにATtiny85で同じことをやってみる。

ATtiny85はブレッドボードに差してワイヤで接続。

ATtiny85ではきれいな正弦波が得られる。アンプを通して聞いても澄んだ音に聞こえる。このことから、やり方に問題はないはず。

プログラムの内容はATtiny202で行ったものと、当然、同じ。タイマ/カウンタを二つ使い、一つをPWMの発生に、もう一つを周期割込みに。割込みハンドラで予め用意した正弦波のテーブルに従ってPWMのデューティ比を変えるだけ。

コードは例によってBingチャットで作ったもの(をベースにしている)。

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

#define F_CPU 8000000UL

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

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

volatile uint8_t pwm_value = 0;


void setup() {
	float unit_deg;
	int i;

	i_wave = 0;
	
	/* 正弦波テーブル作成 */
	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);
	}

	
	// タイマ/カウンタ0: 正弦波出力割込み周期設定 */
	TCCR0A = (1 << WGM01); // CTCモード
	TCCR0B = (1 << CS01); // プリスケーラ8でカウント開始
	OCR0A = 31; // 周期を設定(32kHz)
	TIMSK |= (1 << OCIE0A); // OCR0Aに一致したら割り込み発生

	// タイマ/カウンタ1: 正弦波用PWM周波数設定 */
	DDRB |= (1 << PB4); // PB4を出力に設定
	TCCR1 |= (1 << CTC1) | (1 << COM1B1) | (1 << PWM1B);
	GTCCR |= (1 << PWM1B) | (1 << COM1B0);
	OCR1C = 255; // PWMの分解能は256
	OCR1B = 127; // デューティ比50%
	TCCR1 |= (1 << CS10);	// タイマ/カウンタ1 を開始
	
}


/* 割込みハンドラ: 正弦波出力 */
ISR(TIM0_COMPA_vect) {
	OCR1B = wave[i_wave];

	i_wave++;
	
	if (i_wave >= N_WAVE) {
		i_wave = 0;
	}
}

void loop() {
}


int main() {
	setup();
	sei();

	while(1) {
		loop();
	}
}

うーん、ATtiny202では何がいけないんだろう?正弦波の下りカーブにだけノイズが乗るのは謎すぎる…。

コメント