効果音を発生し、車両のさまざまな状態を音で通知します。
音源には、YAMAHAのYMZ294を使用しています。
コンパイラはCCS Cを使用しています。
#include <16f876.h> #fuses HS, NOWDT, NOPROTECT, PUT, BROWNOUT, NOLVP #use delay( Clock = 20000000 ) // クロック周波数指定 #use i2c( slave, SDA=PIN_C4, SCL=PIN_C3, ADDRESS=0x10, FAST, FORCE_HW ) // I2Cアドレス[ 0x10 ] // 入出力ピン定義(入出力モード固定) #use fixed_io( a_outputs=PIN_A0, PIN_A1, PIN_A2, PIN_A3, PIN_A5 ) #use fixed_io( b_outputs=PIN_B0, PIN_B1, PIN_B2, PIN_B3, PIN_B4, PIN_B5, PIN_B6, PIN_B7 ) // A0-A3:CPU Interface // B0-B7:Data Bus // C3:I2C_SCL(in) // C4:I2C_SDA(in) set_tris_a( 0b00010000 ); set_tris_b( 0b00000000 ); set_tris_c( 0b00011000 ); #define WR 0x04 // WriteEnable #define CS 0x02 // ChipSelect #define A0 0x01 // ModeSelect #define IC 0x08 // Reset #define LED PIN_C0 #define SwitchOn PIN_A4 // プロトタイプ宣言 void MixVol(); void mute(); void SoundTest(); void Sound( int Address, int Data ); void scale( int Part, int Octave, int Scale ); void Envel( long freq, int form ); void Melodious( int select ); // 音階周波数(イ長調) #define freq_C 440 #define freq_D 494 #define freq_E 554 #define freq_F 587 #define freq_G 659 #define freq_A 740 #define freq_B 831 // ft = fsc / (16 * tp) #define fsc 4000000 / 2 #define Scale_0C fsc / ( 16 * freq_C / 2 ) // ド #define Scale_0D fsc / ( 16 * freq_D / 2 ) // レ #define Scale_0E fsc / ( 16 * freq_E / 2 ) // ミ #define Scale_0F fsc / ( 16 * freq_F / 2 ) // ファ #define Scale_0G fsc / ( 16 * freq_G / 2 ) // ソ #define Scale_0A fsc / ( 16 * freq_A / 2 ) // ラ #define Scale_0B fsc / ( 16 * freq_B / 2 ) // シ #define Scale_1C fsc / ( 16 * freq_C ) // ド #define Scale_1D fsc / ( 16 * freq_D ) // レ #define Scale_1E fsc / ( 16 * freq_E ) // ミ #define Scale_1F fsc / ( 16 * freq_F ) // ファ #define Scale_1G fsc / ( 16 * freq_G ) // ソ #define Scale_1A fsc / ( 16 * freq_A ) // ラ #define Scale_1B fsc / ( 16 * freq_B ) // シ #define Scale_2C fsc / ( 16 * freq_C * 2 ) // ド #define Scale_2D fsc / ( 16 * freq_D * 2 ) // レ #define Scale_2E fsc / ( 16 * freq_E * 2 ) // ミ #define Scale_2F fsc / ( 16 * freq_F * 2 ) // ファ #define Scale_2G fsc / ( 16 * freq_G * 2 ) // ソ #define Scale_2A fsc / ( 16 * freq_A * 2 ) // ラ #define Scale_2B fsc / ( 16 * freq_B * 2 ) // シ struct ft_freq { int freq_low; int freq_high; }; struct ft_oct { struct ft_freq freq[ 7 ]; }; const struct ft_oct ft[ 3 ] = { { Scale_0C % 256, Scale_0C / 256, Scale_0D % 256, Scale_0D / 256, Scale_0E % 256, Scale_0E / 256, Scale_0F % 256, Scale_0F / 256, Scale_0G % 256, Scale_0G / 256, Scale_0A % 256, Scale_0A / 256, Scale_0B % 256, Scale_0B / 256 }, { Scale_1C % 256, Scale_1C / 256, Scale_1D % 256, Scale_1D / 256, Scale_1E % 256, Scale_1E / 256, Scale_1F % 256, Scale_1F / 256, Scale_1G % 256, Scale_1G / 256, Scale_1A % 256, Scale_1A / 256, Scale_1B % 256, Scale_1B / 256 }, { Scale_2C % 256, Scale_2C / 256, Scale_2D % 256, Scale_2D / 256, Scale_2E % 256, Scale_2E / 256, Scale_2F % 256, Scale_2F / 256, Scale_2G % 256, Scale_2G / 256, Scale_2A % 256, Scale_2A / 256, Scale_2B % 256, Scale_2B / 256 } }; // ===================================================================== // SSP割り込み処理 #int_ssp void ssp_interupt() { int Receive; if( i2c_poll() ) { // 受信 Receive = i2c_read(); Melodious( Receive ); } } // ===================================================================== // メイン関数 void main() { setup_adc_ports( NO_ANALOGS ); // A/D Converter - OFF setup_adc( ADC_OFF ); enable_interrupts( INT_SSP ); // SSP enable_interrupts( GLOBAL ); // グローバル割り込み許可 output_A( IC ); // (The 4th bit of PORTA Register must be High in Every time,) MixVol(); while( 1 ) { if( input( SwitchOn ) == FALSE ) { SoundTest(); } } } // ===================================================================== // ミキサー/ボリュームセッティング void MixVol() { Sound( 0x07, 0b00111000 ); // Mixer Settings Sound( 0x08, 0b00001111 ); // Ach Volume Setting Sound( 0x09, 0b00001111 ); // Bch Volume Setting Sound( 0x0A, 0b00001111 ); // Cch Volume Setting } // ミュート void mute() { Sound( 0, 0x00 ); Sound( 1, 0x00 ); Sound( 2, 0x00 ); Sound( 3, 0x00 ); Sound( 4, 0x00 ); Sound( 5, 0x00 ); } // サウンド テスト void SoundTest() { static int test; Melodious( test ); test++; if( test > 4 ) { test = 0; } } // ===================================================================== // アドレス/データセット void Sound( int Address, int Data ) { output_A( ( IC ) ); // Address write enabled output_B( Address ); // Address input output_A( ( IC | WR | CS ) ); // Address write disabled output_A( ( IC | A0 ) ); // Data write enabled output_B( Data ); // Data input output_A( ( IC | WR | CS | A0 ) ); // Data write disabled } // 単音の発生 void scale( int Part, int Octave, int Scale ) { Sound( ( Part * 2 ) - 2, ft[ Octave ].freq[ Scale ].freq_low ); Sound( ( Part * 2 ) - 1, ft[ Octave ].freq[ Scale ].freq_high ); } // エンベローブ設定 void Envel( long freq, int form ) { Sound( 0x0B, freq >> 8 ); Sound( 0x0C, freq ); Sound( 0x0D, form ); } // ===================================================================== // 効果音選択 void Melodious( int select ) { int i, k; output_high( LED ); switch( select ) { // ドレミ~♪ case 0: { for( k = 0; k < 3; k++ ) { for( i = 0; i < 7; i++ ) { scale( 1, k, i ); delay_ms( 200 ); } } mute(); } break; // ティロリー♪ case 1: { scale( 1, 1, 6 ); scale( 2, 1, 7 ); delay_ms( 40 ); scale( 1, 1, 3 ); delay_ms( 40 ); scale( 1, 1, 4 ); delay_ms( 40 ); scale( 1, 1, 5 ); delay_ms( 40 ); scale( 1, 1, 6 ); scale( 2, 1, 4 ); delay_ms( 200 ); mute(); } break; // ポーン♪ case 2: { Sound( 0x08, 0b00011111 ); // Ach Volume Setting scale( 1, 1, 0 ); Envel( 0x0050, 0b00001000 ); delay_ms( 500 ); mute(); } break; // ファーン♪ case 3: { Sound( 0x08, 0b00011111 ); // Ach Volume Setting Sound( 0x09, 0b00011111 ); // Bch Volume Setting scale( 1, 2, 0 ); scale( 2, 2, 2 ); Envel( 0x000A, 0b00001110 ); delay_ms( 500 ); mute(); } break; // ピーピッピッ♪ case 4: { Sound( 0x08, 0b00001111 ); // Ach Volume Setting scale( 1, 2, 4 ); delay_ms( 200 ); Sound( 0x08, 0b00000000 ); // Ach Volume Setting delay_ms( 100 ); Sound( 0x08, 0b00001111 ); // Ach Volume Setting scale( 1, 2, 4 ); delay_ms( 50 ); Sound( 0x08, 0b00000000 ); // Ach Volume Setting delay_ms( 50 ); Sound( 0x08, 0b00001111 ); // Ach Volume Setting scale( 1, 2, 4 ); delay_ms( 50 ); mute(); } break; default: } output_low( LED ); }