PIC16F1619の基本動作から応用プログラムまでを学びます。

ホーム
12F1822
16F1455
16F1459
18F14K50
18F26J50
dsPIC
その他
    
16F18313
16F18325
16F18346
16F1619
Curiosity
---
---
赤外線リモコン受信機
2020-11-01

赤外線リモコンの信号を受信しLEDを点灯させるプログラムです。

リモコンの「1」ボタンを押すと「LED4(RA5)」 が点灯します。再び「1」を押すとLEDは消灯します。

同様に、リモコンの「2」「3」「4」が
それぞれ LED5(RA1)」「LED6(RA2)」「LED7(RC5)」に対応します。

PICのペリフェラルは以下の用途に使用しています。

Timer1
信号の継続時間測定に使用
1MHzをカウントするので、1us単位となる。Timer ゲート制御機能を使用している
赤外線センサー (OSRB38C9AA)
RC7に接続してTMR1ゲート入力でモニタしている。赤外線信号を受信すると出力が LOW になる負論理出力のセンサー

赤外線リモコンの波形

この受信機は、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
 
 

下の波形は、リモコンのチャンネル1Keyを押し、赤外線受信モジュールの出力波形をロジックアナライザーで測定したものです。リーダー部に続き 16 ビットのデータが観測できます。


ロジックアナライザーの時間軸を長くとると、下図のようにデータ部の後に20ms程度の間隔を開けて、データ部が再送されているのがわかります。この例では、データ部は合計3回送信されていました。


JVCの汎用リモコンをビクターに設定した時のキーと出力される16ビットコードの関係を示します。

出力される16bitコード
入力切換C0C8  大 C078  1 C084  7 C0E4
電源C0E8 C0F8 2C044 8C014
タイマーC0C0 消音C038 3C0C4 9C094
BS/e2C030 C098 4C024 10C054
地デジF0A8 C018 5C0A4 11C0D4
機能赤外線の出力なし 6C064 12C034

プログラム

プログラム例を示します。
赤外線送信が終了するまで、赤外線センサーのSpace信号(赤外線を送っていない時間)をTimer1で計測します。
Spaceが 65msを超えると送信が終了したと判断し、最後の4バイト分だけを取得し、Keyコードと比較し該当のLEDを点灯させます。

/*************************************************
 * NECタイプの赤外線リモコン受信
        Device         :  PIC16F1619 on Curiosity
        XC8 Version    :  2.20
***************************************************/

#include <xc.h>
#include <stdint.h>
#define _XTAL_FREQ 4000000

// CONFIG
#pragma config FOSC = INTOSC, PWRTE = OFF, MCLRE = ON, CP = OFF
#pragma config BOREN = ON, CLKOUTEN = OFF, IESO = ON, FCMEN = ON
#pragma config WRT = OFF, PPS1WAY = ON, ZCD = OFF, PLLEN = OFF
#pragma config STVREN = ON, BORV = LO, LPBOR = OFF, LVP = ON
#pragma config WDTCPS = WDTCPS1F, WDTE = OFF, WDTCWS = WDTCWSSW, WDTCCS = SWC

/*********************************************************
                         Main application
 *********************************************************/
void main(void)
{
    uint16_t ircode = 0;
    OSCCON = 0b01101000;	// PLL disabled; 4MHz_HF; FOSC;
    LATA = 0;               // LED 消灯
    LATC = 0;               //
    TRISA = 0b11011001;     // LED接続Pinは出力
    TRISC = 0b11011111;     //
    ANSC7 = 0;              // センサーPinはデジタル入力
    T1CON = 0;              // Fosc/4 pre 1:1
    T1GCON = 0xC0;          // Gateenable Gatepin負極性
    TMR1  = 0;              // Eimer値 0 リセット
    T1GPPS = 0x17;          // GatepinをRC7に指定

    while(1){
        while(RC7);                 // 赤外線信号を待つ
        TMR1ON = 1;                 // Timer ON
        TMR1GIF = 0;                // Gate flag OFF
        TMR1IF = 0;                 // TMR1 flag OFF
        while(1){                   // Data bit毎の繰り返し
            if(TMR1GIF){                    // Space終了なら
                TMR1GIF = 0;                //   Gate flag OFF
                ircode <<= 1;               //   1 bitシフト
                if(TMR1H > 4)ircode |= 1;   //   長いSpaceなら"1"
                TMR1 = 0;                   //   Timerクリア
            }
            if(TMR1IF) break;               // Gap(65msec以上)なら
        }                                   // Data収集終了
        TMR1ON = 0;                 // Timer OFF
        TMR1 = 0;                   // Timer 0 にリセット

        switch (ircode){            // 受信コードによりLED制御
            case 0xC084: LATA5 ^= 1; break;  // Key 1 LED4 反転
            case 0xC044: LATA1 ^= 1; break;  // Key 2 LED5 反転
            case 0xC0C4: LATA2 ^= 1; break;  // Key 3 LED6 反転
            case 0xC024: LATC5 ^= 1; break;  // Key 4 LED7 反転
			default:     LATA = 0;
                         LATC = 0;  break;  // 他のKey 全消灯
        }
    }
}
/** End of File **/