#define F_CPU 16000000UL //16MHz動作
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
/*
* 音階データの定義(PWM値)
* 16000000Hz / 256 / 周波数
*/
#define C0 478
#define C0S 451
#define D0 426
#define D0S 402
#define E0 379
#define F0 358
#define F0S 338
#define G0 319
#define G0S 301
#define A0 284
#define A0S 268
#define B0 253
#define C1 239
#define C1S 225
#define D1 213
#define D1S 201
#define E1 190
#define F1 179
#define F1S 169
#define G1 159
#define G1S 150
#define A1 142
#define A1S 134
#define B1 127
#define C2 119
#define C2S 113
#define D2 106
#define D2S 100
#define E2 95
#define F2 89
#define F2S 84
#define G2 80
#define G2S 75
#define A2 71
#define A2S 67
#define B2 63
#define P 0 // 休符
/*
* 音符の長さ
*/
#define T16 80
#define T8 160
#define T4 320
#define T2 640
#define T1 1280
void hw_init()
{
// PWM
DDRD |= 0b00000001; //PD0を出力に(OC0B)
DDRB |= 0b10000000; //PB7を出力に(OC0A)
PORTD = 0b00000001;
PORTB = 0b10000000;
TCCR0A = 3; // 高速PWMモード(モード7)に設定
TCCR0B |= _BV(WGM02); // TOPをOCR0Aの値 (モード7)
TCCR0A |= _BV(COM0B1); // OC0Bを出力
TCCR0B |= _BV(CS02) ; // 周波数設定(PWMの一周期) (TCNT:8bit)
//
システムクロックが16MHzでTCNTがリセットされる値がOCR0A(上限値)であるため、
// 16000000 / 分周比 / OCR0AがPWMの一周期となる。
// (分周比が1なら62500Hz→16uS)
}
//int doremi[] = {B0,C1,C1S, D1, D1S, E1, F1, F1S, G1, G1S, A1, A1S, B1, C2,
C2S, D2, D2S,
// E2, F2, F2S, G2, G2S, A2, A2S, B2};
/*
* 楽譜データ ~君をのせて(天空の城ラピュタ)~
*/
int doremi[][2] = {
{E1,T8}, {F1S,T8},
{G1,T4+T8}, {F1S, T8}, {G1, T4}, {B1, T4},
{F1S, T2}, {P, T4}, {B0, T4},
{E1, T4+T8}, {D1, T8}, {E1, T4}, {G1, T4},
{D1, T2}, {P, T4}, {B0, T8}, {B0, T8},
{C1, T4+T8}, {B0, T8}, {C1, T8}, {G1, T4+T8},
{B0, T2}, {P, T8}, {G1, T8}, {G1, T8}, {G1, T8},
{F1S, T4+T8}, {C1S, T8}, {C1S, T4}, {F1S, T4},//
{F1S, T2}, {P, T4}, {E1, T8}, {F1S, T8},
{G1, T4+T8}, {F1S, T8}, {G1, T4}, {B1, T4},
{F1S, T2}, {P, T4}, {B0, T8}, {B0, T8},
{E1, T4+T8}, {D1, T8}, {E1, T4}, {G1, T4},
{D1, T2}, {P, T4}, {P, T8}, {B0, T8},
{C1, T4}, {G1, T8}, {F1S, T8}, {F1S, T4}, {G1, T4},
{A1, T8}, {A1, T8}, {B1, T4}, {G1, T4}, {P, T4}, // 5?
{G1, T8}, {F1S, T8}, {E1, T8}, {E1, T8}, {F1S, T4}, {D1S,
T4},
{E1, T2}, {P, T4}, {G1, T8}, {A1, T8},
{B1, T4+T8}, {A1, T8}, {B1, T4}, {D2, T4},
{A1, T2}, {P, T4}, {D1, T8}, {D1, T8},
{G1, T4+T8}, {F1S, T8}, {G1, T4}, {B1, T4},
{B1, T2+T4}, {P, T4},
{E1, T8}, {F1S, T8}, {G1, T4}, {F1S, T8}, {G1, T8}, {A1, T8},
{A1, T8},
{G1, T4+T8} , {D1, T8}, {D1, T4}, {P, T4},
{C2, T4}, {B1, T4}, {A1, T4}, {G1, T4},
{B1, T1},
{B1, T2}, {P, T4}, {B1, T4},
{E2, T2}, {D2, T4+T8}, {D2, T8},
{B1, T8}, {A1, T8}, {G1, T2}, {P, T8}, {G1, T8},
{A1, T4}, {G1, T8}, {A1, T8}, {A1, T8}, {D2, T4+T8},
{B1, T2}, {P, T4}, {B1, T4},
{E2, T2}, {D2, T2},
{B1, T8}, {A1, T8}, {G1, T2}, {P, T8}, {G1, T8},
{A1, T4}, {G1, T8}, {A1, T8}, {A1, T4}, {F1S, T4},
{E1, T2}, {P, T4}
};
// PWMの切り替えと音の長さ
void sound(int f, int t)
{
OCR0A = f;
OCR0B = f >> 1; // デューティを1/2に設定
_delay_ms(t); // 音符の長さ
OCR0A = 0; // 音符の区切り
OCR0A = 0;
_delay_ms(3);
}
int main()
{
int i;
CLKPR = 0x80; CLKPR = 0; // 16MHz動作のための設定
hw_init(); // PWMの設定
DDRB = 0b11111111; // デバッグ用の設定(無くて良し)
while(1) {
for (i=0; i < sizeof(doremi)/4; i++) {
PORTB = i; // デバッグ用の設定(無くて良し)
sound(doremi[i][0], doremi[i][1]);
}
}
}
|