---------------------------------------------------------------------
#include <pic.h>
#include <htc.h> // delay用に必要
#define _XTAL_FREQ 8000000 // delay用に必要(クロック8MHzを指定)
#define BZ_PIN RA1 // ブザーを出力するピンを指定
#define TEMPO 60 // 4分音符=60bpm (4分音符の音価で入力)
long NOTE ;
long I ;
long LEN ;
// デバッグしない(DEBUGDIS):低電圧プログラミング機能使用しない(LVPDIS)
// メモリを保護しない(UNPROTECT):外部リセット信号は使用せずにデジタル入力(RA5)ピンとする(MCLRDIS)
// 電源電圧降下常時監視機能ON(BOREN):電源ONから72ms後にプログラムを開始する(PWRTEN)
// ウオッチドックタイマ無し(WDTDIS):内部クロックを使用する(INTIO)
__CONFIG(DEBUGDIS & LVPDIS & UNPROTECT & MCLRDIS & BOREN & PWRTEN & WDTDIS & INTIO) ;
// EEPROMにメロディデータを書込む
__EEPROM_DATA(0x58,0x58,0x88,0x98,0xa8,0x98,0x84,0x68);
__EEPROM_DATA(0x68,0x58,0x48,0x58,0x04,0x00,0x00,0x00);
/* 休符 */
void kyufu()
{
LEN = NOTE / 2272 ;
// ラ音と同じ長さのパルス(1サイクル)を繰返す
for (I = 0; I < LEN ; I++) {
__delay_us(2272) ;
}
}
/* ドの音を出す */
void C4()
{
LEN = NOTE / 3816 ;
// 同じ長さのパルス(1サイクル)を繰返す
for (I = 0; I < LEN ; I++) {
BZ_PIN = 1 ;
__delay_us(1908) ;
BZ_PIN = 0 ;
__delay_us(1908) ;
}
}
/* レの音を出す */
void D4()
{
LEN = NOTE / 3401 ;
// 同じ長さのパルス(1サイクル)を繰返す
for (I = 0; I < LEN ; I++) {
BZ_PIN = 1 ;
__delay_us(1700) ;
BZ_PIN = 0 ;
__delay_us(1700) ;
}
}
/* ミの音を出す */
void E4()
{
LEN = NOTE / 3030 ;
// 同じ長さのパルス(1サイクル)を繰返す
for (I = 0; I < LEN ; I++) {
BZ_PIN = 1 ;
__delay_us(1515) ;
BZ_PIN = 0 ;
__delay_us(1515) ;
}
}
/* ファの音を出す */
void F4()
{
LEN = NOTE / 2865 ;
// 同じ長さのパルス(1サイクル)を繰返す
for (I = 0; I < LEN ; I++) {
BZ_PIN = 1 ;
__delay_us(1432) ;
BZ_PIN = 0 ;
__delay_us(1432) ;
}
}
/* ソの音を出す */
void G4()
{
LEN = NOTE / 2551 ;
// 同じ長さのパルス(1サイクル)を繰返す
for (I = 0; I < LEN ; I++) {
BZ_PIN = 1 ;
__delay_us(1275) ;
BZ_PIN = 0 ;
__delay_us(1275) ;
}
}
/* ラの音を出す */
void A4()
{
LEN = NOTE / 2272 ;
// 同じ長さのパルス(1サイクル)を繰返す
for (I = 0; I < LEN ; I++) {
BZ_PIN = 1 ;
__delay_us(1136) ;
BZ_PIN = 0 ;
__delay_us(1136) ;
}
}
/* シの音を出す */
void B4()
{
LEN = NOTE / 2024 ;
// 同じ長さのパルス(1サイクル)を繰返す
for (I = 0; I < LEN ; I++) {
BZ_PIN = 1 ;
__delay_us(1012) ;
BZ_PIN = 0 ;
__delay_us(1012) ;
}
}
/* ド(1高)の音を出す */
void C5()
{
LEN = NOTE / 1912 ;
// 同じ長さのパルス(1サイクル)を繰返す
for (I = 0; I < LEN ; I++) {
BZ_PIN = 1 ;
__delay_us(956) ;
BZ_PIN = 0 ;
__delay_us(956) ;
}
}
/* レ(1高)の音を出す */
void D5()
{
LEN = NOTE / 1703 ;
// 同じ長さのパルス(1サイクル)を繰返す
for (I = 0; I < LEN ; I++) {
BZ_PIN = 1 ;
__delay_us(851) ;
BZ_PIN = 0 ;
__delay_us(851) ;
}
}
/* メインの処理 */
void main()
{
int i , dt , scale ;
OSCCON = 0b01110100 ; // 内部クロックは8MHzとする
ADCON1 = 0b00000110 ; // アナログは使用しない、RA0-RA4をデジタルI/Oに割当
TRISA = 0b00000000 ; // 1で入力 0で出力 RA0-RA7全て出力に設定(RA5は入力専用)
TRISB = 0b00000000 ; // RB0-RB7全て出力に設定
while(1) {
// EEPROMから0x00を読み出すまで繰り返す
for (i=0 ; i < _EEPROMSIZE ; i++) {
dt = eeprom_read(i) ; // EEPROMからデータを読込む
if (dt == 0) break ; // データ0で終了
NOTE = 0xf & dt ; // 読込みデータから音符を取出す
if (NOTE == 0) NOTE = 16 ;
NOTE = ((60000000L/TEMPO)*4) / NOTE ;
scale = (dt >> 4) ; // 読込みデータから音階を取出す
if (scale == 0) kyufu() ; // 休符
if (scale == 2) C4() ; // ド
if (scale == 3) D4() ; // レ
if (scale == 4) E4() ; // ミ
if (scale == 5) F4() ; // ファ
if (scale == 6) G4() ; // ソ
if (scale == 7) A4() ; // ラ
if (scale == 8) B4() ; // シ
if (scale == 9) C5() ; // ド(1高)
if (scale ==10) D5() ; // レ(1高)
}
// 3秒後に繰り返す
for (i=0 ; i < 300 ; i++) {
__delay_ms(10) ;
}
}
}
---------------------------------------------------------------------
void D5()
{
LEN = NOTE / 1703 ; ← 上の計算1から1703か1704にします(ここが音符の長さです)
for (I = 0; I < LEN ; I++) {
BZ_PIN = 1 ;
__delay_us(851) ; ← 上の計算2から851か852にします(ここが音階に影響します)
BZ_PIN = 0 ; (どちらを選択するかは耳で聴き比べて下さい)
__delay_us(851) ; ← (同上)
}
}
メロディを何曲か登録してスイッチの切替えで曲を選んだりの改造もたぶんOKでしょう。
| ピン番号 | 16 | 15 | 4 | 3 | 2 | 1 | 18 | 17 |
| デジタル入出力ビット名 | RA7 | RA6 | RA5 | RA4 | RA3 | RA2 | RA1 | RA0 |
| ピン番号 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 |
| デジタル入出力ビット名 | RB7 | RB6 | RB5 | RB4 | RB3 | RB2 | RB1 | RB0 |
【きむ茶工房ガレージハウス】
Copyright (C) 2006-2011 Shigehiro Kimura All Rights Reserved.