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

ホーム
16F18313
16F18325
16F18346
16F1619
Curiosity
---
---
    
12F1822
16F1455
16F1459
18F14K50
18F26J50
dsPIC
その他
赤外線信号受信器

18F14K50のBootLoader基本ボードを使い、赤外線リモコンの受信機を作成しました。

基本ボードのコネクタにに赤外線リモコン受光モジュールを接続すれば、テレビリモコンのチャンネル「1」を押せば、端のLEDが。 テレビリモコンのチャンネル「2」を押せば、隣のLED点灯し、「1」-「4」までのリモコンボタンに4つのLEDが対応して点灯します。 

赤外線リモコンが大量生産されるようになったため、高機能な赤外線リモコン受光モジュールも安価で入手できるようになりました。今回使用したPL-IRM2161-C438には、赤外線を受けるフォトダイオード、アンプ、フィルター、検波回路などが6mm角の小さな樹脂容器に納められています。使い方は簡単です。モジュールに+5V電源を接続すれば、赤外線入力に対応したロジック出力が得られます。ただし、基板のコネクタPIN配列とモジュールのPIN配列が異なるためモジュールの足を多少無理してコネクター配列に合わせ挿入しています。

プログラム

main.c

//***************************************************************
//    PIC18F14K50
//    赤外線リモコンを受信しLEDに表示
//     1)Define I/O PORT
//         PORTA(3)pin 4    :  PushSW
//         PORTC(0)pin16    :  LED
//         PORTC(1)pin15    :  LED
//         PORTC(2)pin14    :  LED
//         PORTC(3)pin 7    :  LED
//         PORTC(4)pin 6    :  Ir入力
//     2)OSC
//         48MHz (12MHz Xtal)
//***************************************************************/

#include <p18f14k50.h>
#include <delays.h>
#include <timers.h>

#define ctmCode     0x0055  // 赤外線カスタマーコード(現在は無効)
#define L_ON_Min    234     // 5msec リーダーの最小継続時間
#define DataTH      47      // 1msec データの「1」「0」境界時間
#define D_Off_Max   94      // 2msec データ「0」の最大継続時間
#define IrIN PORTCbits.RC4
#define T0IF INTCONbits.TMR0IF
#define LED1 LATCbits.LATC0
#define LED2 LATCbits.LATC1
#define LED3 LATCbits.LATC2
#define LED4 LATCbits.LATC3

//------------ リセット  ベクトルの移動-----------------------
#define REMAPPED_RESET_VECTOR_ADDRESS    0x1000
extern void _startup (void);
#pragma code reset_vect = REMAPPED_RESET_VECTOR_ADDRESS
void _reset (void){_asm goto _startup _endasm}
//------------------------------------------------------------

// ----- 関数プロトタイピング -----
int irRcv(void);

#pragma code
//****** メイン  ************************
void main(void){
    int rcvData;
    unsigned char cmd,n_cmd;

    PORTA = 0x00;
    PORTB = 0x00;
    PORTC = 0x00;
    TRISA = 0b11111111;   //PortA すべて入力
    TRISB = 0b11111111;   //PortB すべて入力
    TRISC = 0b11110000;   //PortC 0-3出力
    ANSEL  = 0b00000000;  //すべてデジタル
    ANSELH = 0b00000000;

    OpenTimer0(           // Timer0を初期化
        TIMER_INT_OFF &
        T0_8BIT &
        T0_SOURCE_INT &
        T0_PS_1_256 );

    //        --- 以下は受信の繰り返し ---
    while(1){
        // ------- Start Bit (リーダー)の確認 ---------------
        //OnおよびOFFの時間を確認しノイズか有効データか判断する
        // -----------------------------------------
        while(1){
            while(IrIN);             // 信号 待ち
            TMR0L = 0;               // -- リーダーのON 時間測定
            T0IF = 0;                //
            while(!IrIN);            // IrOFF 待ち
            if((TMR0L < L_ON_Min)    // リーダーの最小継続時間以下
                 && !T0IF)continue;  //   ならノイズなので戻る
            TMR0L = 0;               // -- リーダーのOFF時間測定
            T0IF = 0;                //
            while(IrIN && !T0IF);    // IrON 待ち
            if(!T0IF) break;         // 5.5mS以下ならOK(受信開始)
        }
        // ------- カスタムコードの確認 -------------------
        // 受信が16ビット未満、または、カスタムコードが異なれば  再受信
        // -----------------------------------------
        rcvData=irRcv();                              //8ビット受信
        if((rcvData & 0xFF00) != 0x0800)continue;       //受信ビット数確認
//        if((rcvData & 0x00FF) != ctmCode>>8)continue; //カスタマコード確認
        rcvData=irRcv();
        if((rcvData & 0xFF00) != 0x0800)continue;
//        if((rcvData & 0x00FF) != ctmCode & 0xFF)continue;
        // ------- コマンドコードの確認 --------------------
        // コマンドおよび反転コマンドを受信して比較異なれば  再受信
        // -----------------------------------------
        rcvData=irRcv();
        if((rcvData & 0xFF00) != 0x0800)continue;
        cmd = rcvData & 0x00FF;
        rcvData=irRcv();
        if((rcvData & 0xFF00) != 0x0800)continue;
        n_cmd = rcvData & 0x00FF;
        if(cmd != ~n_cmd)continue;
        // ---- 受信コマンドの処理 -------------------
        switch (cmd){
        case 1:  // コマンドが「1」ならLED1を点灯
            LED1 = 1;LED2 = 0; LED3 = 0; LED4 = 0;
            break;
        case 2:
            LED1 = 0; LED2 = 1; LED3 = 0; LED4 = 0;
            break;
        case 3:
            LED1 = 0; LED2 = 0; LED3 = 1; LED4 = 0;
            break;
        case 4:
            LED1 = 0; LED2 = 0; LED3 = 0; LED4 = 1;
            break;
         default:
            LED1 = 0; LED2 = 0; LED3 = 0; LED4 = 0;
            break;
        }
    }
}
//****** 1Byteを受信する *******************************
//  8ビット受信する。
//  受信したビット数を上位8ビット
//  受信データを    下位8ビットに組み合わせて  戻る
//         「1「0」判定は「0」の時間を DataTH と比較する
//******************************************************
int irRcv(void){
    unsigned char i,period,data;
    data = 0;
    for(i = 0; i < 8; i++){
        data >>= 1;         // 1ビットずつ8回繰り返す
        while(!IrIN);            // IrOFF 待ち
        TMR0L = 0;               // -- BitのOFF時間測定
        T0IF = 0;                //
        while(IrIN && TMR0L < D_Off_Max); // IrON 待ち
        period = TMR0L;                   // 時間取得
        if(period > DataTH)               // 「1「0」判定
            data += 0x80;                 // 「1」を立てる
        if(period>= D_Off_Max) break;     // 2mS以上ならStop
    }
    return (int)i * 256 + data;           // 受信Bit数と内容合成
}