【PIC】16F18313 I2C通信テスト

 最近暑すぎるのでやはりエアコンをネット経由で遠隔操作したいと思い,エアコン遠隔操作の計画が再開しています.現在の計画では

 PC,スマホ

  ↓ (Ethernet)

 ラズパイ

  ↓ (I2C)

 PIC 16F18313

  ↓

 赤外線LED点滅回路 

で考えています.PC-ラズパイ間の通信はどうとでもなるのでとりあえずI2Cでラズパイから一方通行のデータを送るPICプログラムを作って試してみました.

 

1.ソースコード

    #include < pic.h >
/*
 * RA0:out
 * RA1:I2C
 * RA2:I2C
 * RA3:nc
 * RA4:nc
 * RA5:nc
 */
//コンフィグ1
#pragma  config FEXTOSC = OFF
#pragma  config RSTOSC  = HFINT32
#pragma  config CLKOUTEN = OFF
#pragma  config CSWEN   = ON
#pragma  config FCMEN   = OFF   // 外部クロック監視しない(FCMEN_OFF)

// コンフィギュレーション2の設定
#pragma config WDTE = OFF       // ウオッチドッグタイマー無し(OFF)
#pragma config PWRTE = ON       // 電源ONから64ms後にプログラムを開始する(ON)
#pragma config MCLRE = OFF      // 外部リセット信号は使用せずにデジタル入力(RA3)ピンとする(OFF)
#pragma config CP = OFF         // プログラムメモリーを保護しない(OFF)
#pragma config CPD = OFF        // データメモリーを保護しない(OFF)
#pragma config BOREN = ON       // 電源電圧降下常時監視機能ON(ON)
#pragma config CLKOUTEN = OFF   // CLKOUTピンをRA6ピンで使用する(OFF)
#pragma config PPS1WAY = OFF    // PPS設定をロックしない
#pragma config STVREN = ON      // スタックがオーバフローやアンダーフローしたらリセットをする(ON)
#pragma config BORV = HIGH      // 電源電圧降下常時監視電圧(2.5V)設定(HI)

// コンフィギュレーション3の設定
#pragma config WRT = OFF        // Flashメモリーを保護しない(OFF)
#pragma config LVP = OFF        // 低電圧プログラミング機能使用しない(OFF)

#define _XTAL_FREQ 4000000

static unsigned char RData;

void __interrupt() InterI2C(void)
{
    char temp;

    if (SSP1IF == 1 && !((SSP1STAT&0x04)==0x04)){  //I2C割込(受信のみ)
        if (SSP1STAT & 0x20){       //受信バイトがデータ D/A = 0
            RData = SSP1BUF;            //データ読込
        }
        else{                       //受信バイトがアドレス D/A =1
            temp = SSP1BUF;             //アドレスデータ空読み
        }
        SSP1IF = 0;                     //割込みフラグリセット
        SSP1CON1 = SSP1CON1 | 0x10;     //SCLライン開放 CKP = 1
    }
    else
        SSP1IF = 0;                     //割込みフラグリセット
}

void main(void)
{
    OSCFRQ  =  0xf3;    // (HFFRQ = 0b0011)4MHzx2で8MHzの周波数生成
    OSCCON1 =  0xf1;    // (NDIV = 0b0001)分周比1:2でFOSC=4MHz
    TRISA   =  0x0e;    //[RA5:RA0] 0b001110
    ANSELA  =  0x00;    //アナログ入力ナシ
    
    RA1PPS = 0x19;      //RA1(out)にSDAを指定
    SSP1DATPPS = 0x01;  //SDA(in)にRA1を指定
    SSP1CLKPPS = 0x02;  //SCL(in)にRA2を指定
    
    SSP1STAT= 0b10000000 ;   // 標準速度モードに設定する(100kHz)
    SSP1CON1= 0b00100110 ;   // SDA/SCLピンはI2Cで使用し、スレーブモードとする
    SSP1CON2bits.SEN = 1 ;   // SCL制御(クロックストレッチ)を行う
    SSP1ADD = 8 << 1     ;   // マイアドレス(8)の設定
    SSP1MSK = 0b11111110 ;   // アドレス比較用マスクデータ
    SSP1IE = 1 ;             // SSP(I2C)割り込みを許可する
    BCL1IE = 1 ;             // MSSP(I2C)バス衝突割り込みを許可する
    PEIE   = 1 ;             // 周辺装置割り込みを許可する
    GIE    = 1 ;             // 全割り込み処理を許可する 
    SSP1IF = 0 ;             // SSP(I2C)割り込みフラグをクリアする
    BCL1IF = 0 ;             // MSSP(I2C)バス衝突割り込みフラグをクリアする
    
    while(1){
        if(RData == 0x00)
            RA0 = 1;
        else
            RA0 = 0;
    }
}

 

2.参考文献

http://zattouka.net/GarageHouse/micon/MPLAB/16F18313/memo.htm

http://zattouka.net/GarageHouse/micon/I2C/I2C_1.htm