すでに作成した、赤外線受信機とオルゴールをまとめ、電池ケースにコンパックトに収納しました。使用した電池ケースは、単3が4本入りケース上部に電源SWが取り付けられている電池ケースです。電池は2本のみ使用し、残り2本のスペースにPIC16F18346、赤外線リモコンセンサー、LED、圧電スピーカーを組み込みました。
↓ 電池ケースの裏蓋を外した内部
LEDの点滅を制御する「LED」モードとオルゴール曲を演奏する「Song」モードがあります。
このプログラムは、main.c,config.c,config.h,gakufu.h,ir.c,ir.h,led.c,led.h,song.c,song.hの10本のファイルから構成されています。スペースの関係で、このページには、main..cのファイルだけ掲載します。他のファイルは、下のアイコンからダウンロードしてください。また、楽譜ファイル(gakufu.h)は、このホームページPIC16F18346のオルゴール項目にあるPCアプリで作成したものと同一の構成です。そのまま、使用することが可能です。PICkit3などですぐに書き込める box_orgel.hex も同梱しています。
Orgel ソースファイル B03_orgel.zip |
main.c
/* File: オルゴール main.c 8 MHz NCO PWM DSM * LED RC2-5 * SP RA4 * Ir RA5 * * Language: MPLABX XC8 * Target: PIC16F18346 */ // 音が減衰する程度 指定値(ms)で1/16減少 #define EnvelopeConst 50 // 音符と音符の間の無音時間(ms) #define Silent 30 #include <xc.h> #include <stdint.h> #include <stdlib.h> #include "config.h" #include "song.h" #include "led.h" #include "ir.h" #define _XTAL_FREQ 8000000 // 共通変数 ************************************************ uint8_t boxMode = mSong; // 0:Song 1:Steady 2:Flash 3:Randum uint8_t irState = 0; uint16_t revdData = 0; //---------------------- main ------------------------ void main(void) { uint16_t code; OSCFRQ = 0b00000110; // HFOSC 16MHz OSCCON1 = 0b01100001; // HFINT1 DIV 2 = 8MHz int_pins(); int_modules(); srand(10); // 乱数初期値 PEIE = 1; // 周辺機能割込みの使用許可 GIE = 1; // 全割込みの使用許可 TMR1IF = 1; // Gap フラグ セット while(1){ // 繰り返しループ ------------------ if(TMR1IF){ // Gap 検出で irState = leaderStart; // Ir受信リセットし TMR1IF = 0; // 次のIr信号受信まで if(boxMode == mSteady){ // Steady Modeなら // ------------ // ---------- SLEEP(); // Sleep // ------------ // ---------- } } if(revdData){ // IR受信した code = revdData; revdData = 0; // ---- 受信データーの処理 ----------------------------------- if(boxMode){ switch (code){ case 0xC0C8: modeSong(); break; // Key 切換 case 0xC084: steady(1); break; // Key 1 LED1 反転 case 0xC044: steady(2); break; // Key 2 LED2 反転 case 0xC0C4: steady(3); break; // Key 3 LED3 反転 case 0xC024: steady(4); break; // Key 4 LED4 反転 case 0xC0A4: steady(0); break; // Key 5 全消灯 case 0xC064: steady(9); break; // Key 6 全反転 case 0xC0E4: flash(0); break; // Key 7 点滅1 case 0xC014: flash(1); break; // Key 8 点滅2 case 0xC094: flash(2); break; // Key 9 点滅3 case 0xC054: flash(3); break; // Key 10 点滅4 case 0xC0D4: flash(4); break; // Key 11 点滅5 case 0xC034: random(); break; // Key 12 点滅6 case 0xC098: speed(inc); break; // Key + case 0xC018: speed(dec); break; // Key ー case 0xC078: dir(0); break; // Key 大 case 0xC0F8: dir(1); break; // Key 小 default: steady(0); break; // 他のKey 全消灯 } }else{ switch (code){ case 0xC0C8: modeLED(); break; // Key 切換 case 0xC084: playSong(1); break; // Key 1 LED1 反転 case 0xC044: playSong(2); break; // Key 2 LED2 反転 case 0xC0C4: playSong(3); break; // Key 3 LED3 反転 case 0xC024: playSong(4); break; // Key 4 LED4 反転 case 0xC0A4: playSong(5); break; // Key 5 全消灯 case 0xC064: playSong(6); break; // Key 6 全反転 case 0xC0E4: playSong(7); break; // Key 7 点滅1 case 0xC014: playSong(8); break; // Key 8 点滅2 case 0xC094: playSong(9); break; // Key 9 点滅3 case 0xC054: playSong(10); break; // Key 10 点滅4 case 0xC0D4: playSong(11); break; // Key 11 点滅5 case 0xC034: playSong(12); break; // Key 12 点滅6 default: LATC = 0; break; // 他のKey 全消灯 } } } } // while } //----------------------割込み処理------------------------ void interrupt isr(void){ // Ir信号がOnOffした --------------------------------- if(IOCIF){ //IRsencerからの割込みを確認 IOCAF = 0; // 割込みフラッグをクリア irRx(); // 受信処理 -----> } if(boxMode){ // LED Modeの時だけ // Timer0からの割り込み if(TMR0IF){ TMR0IF = 0; led_isr(); // 点滅制御 -----> } if(CCP4IF){ // Randum Mode で CCP4IF=0; // LEDを50mSで消灯 TMR5ON = 0; if(boxMode == mRandum)LATC=0; } } }