---
---
赤外線リモコンの信号を受信しボードのLEDを点灯させるプログラムです。
リモコンの「1」ボタンを押すと「LED D1」 が点灯します。
再び「1」を押すとLEDは消灯します。
同様に、リモコンの「2」「3」「4」がそれぞれ LED「D2」「D3」「D4」に対応します。
PICのペリフェラルは以下の用途に使用しています。
この受信機は、JVCTVリモコンの使用を想定したプログラムになっています。JVCは、NECが設定した赤外線リモコン仕様に準拠しており、以下のフォーマット仕様です。
キャリア | 赤外線(λp = 940nm) | Data部 詳細 (T = 562μs) | |
サブキャリア | fsc = 38kHz, 1/3duty | Data の '1' | Mark 1T + Space 3T |
Leader 部 | Mark 9mSec Space 4.5mSec | Data の '0' | Mark 1T + Space 1T |
Data 部 | 固定長フレーム (16bit) 8bitのカスタマーコード + 8bitのコマンドデータ |
Stop bit | Mark 1T |
プロジェクト B08_irRxSimple.zip |
*注意*
MPLAB X プロジェクト には、PICkit3で書き込む仕様とブートローダで書き込む2通りの仕が設定されています。どちらを利用するかをメインメニューバーのIDE Configuration pull down で選んでください。
// ---------------------------------------------------------------- // NECタイプの赤外線リモコン受信 2017/1/14 OK // Notes: 250kHz 内部クロック // LED1 RC0, LED2 RC1, LED3 RC2, LED4 RC3 // Sencer RB7 // Language: MPLABX XC8 // Target: PIC16F1459 // Rev2 Freq 250k 16bit data // ---------------------------------------------------------------- #define _XTAL_FREQ 4000000/16 // delay_ms(x) のための定義 ==250k== #define L_ON_Min 5000/16 // 5msec リーダーの最小継続時間 #define DataTH 1000/16 // 1msec データの「1」「0」境界時間 #define D_Off_Max 2000/16 // 2msec データ「0」の最大継続時間 #define IrIN RB7 // 赤外線センサー入力 #define LED1 LATC0 #define LED2 LATC1 #define LED3 LATC2 #define LED4 LATC3 #include <xc.h> #pragma config FOSC = INTOSC, WDTE = OFF, PWRTE = OFF, MCLRE = OFF #pragma config CP = OFF, BOREN = ON, CLKOUTEN = OFF, IESO = OFF #pragma config FCMEN = OFF, WRT = OFF, CPUDIV = NOCLKDIV #pragma config USBLSCLK = 48MHz, PLLMULT = 3x, PLLEN = ENABLED #pragma config STVREN = ON, BORV = LO, LPBOR = OFF, LVP = OFF unsigned int IrCmdRcv(void); // MAIN ******************************************************** void main(void){ unsigned int revdData; OSCCON = 0b00011010; // 内部クロック250khz LATC = 0; // LED 初期化 TRISC&=0xF0; // Pin 状態変化 初期化 IOCBNbits.IOCBN7 = 1; // 負極性の変異でWake-up INTCONbits.IOCIE = 1; // Wake-up 許可 // Timer 1 設定 ------------------------------------------- // リモコンパルス幅の計測に使用する Timer は、1カウント 16uS T1CON = 0b00000000; // Timer 1 FOSC/4 1/1(66mSecx16ごと) T1GCON = 0b00000000; // Timer 1 Gate設定(使用せず) while(1){ // 繰り返しループ TMR1ON = 0; // Timer1 OFF IOCBFbits.IOCBF7 = 0; // 入力変位フラッグ クリア SLEEP(); // 無信号時はスリープ //-------------------- TMR1ON = 1; // Timer1 ON revdData = IrCmdRcv(); // データー取得 if(revdData == 0) continue; // データー無 // ---- 受信データーの処理 ----------------------------------- switch (revdData){ case 0xC084: LED1 = !LED1; break; // Key 1 LED1 反転 case 0xC044: LED2 = !LED2; break; // Key 2 LED2 反転 case 0xC0C4: LED3 = !LED3; break; // Key 3 LED3 反転 case 0xC024: LED4 = !LED4; break; // Key 4 LED4 反転 default: LATC = 0; break; // 他のKey 全消灯 } } } //*************** 赤外線データーを受信する ***************************** // 正常にデーターを受信したときは、そのデーターを返り値とし // 無信号、エラー時は、0を返す。 // ビクターの信号体系(NEC系)を受信 // リーダ受信確認、データ受信(16bits)する //******************************************************************* unsigned int IrCmdRcv(void){ unsigned int rcvData = 0; if(IrIN) return 0; // 無信号「1」時は復帰 // ------- Start Bit (リーダー)の確認 ----------------------------- //OnおよびOFFの時間を確認しノイズか有効データか判断する // --------------------------------------------------------------- TMR1 = 0; // -- リーダーのON 時間測定 while(TMR1 < L_ON_Min){ // リーダーの最小継続に達しないのに if(IrIN)return 0; // IR Space「1」無信号になったら } // ノイズと判断し復帰 while(!IrIN); // IR Space 待ち TMR1 = 0; // -- リーダーのOFF時間測定 while(IrIN){ // リーダーの終了時間を越えても待ち if(TMR1 > L_ON_Min)return 0; // data開始(IrON)しなければ復帰 } // ------- dataの確認 ----------------------------------- for(char i = 0; i < 16; i++){ // 1ビットずつ16回繰り返す rcvData <<= 1; while(!IrIN); // space 開始を待つ TMR1 = 0; // Bitのspace時間測定開始 while(IrIN) // space 終了を待つ if(TMR1 > D_Off_Max) // 2mS以上ならStopなので return 0; // 復帰 if(TMR1 > DataTH) // 時間取得「1」「0」判定 rcvData |= 1; // 「1」を立てる } return rcvData; // 受信データを持って復帰 }