SSブログ

I2C Color Sensor S11059 02DT

他力本願C言語シリーズ、カラーセンサ
CPU = PIC16F886
LCD = AQM1602XA スレーブアドレス 0x7C(W)  READ不可
カラーセンサ = S-5851A  スレーブアドレス 0x90(W)  0x91(R)

以前の記事で製作したものはアセンブラでしたので今回はC言語での制御です
正直言うとアセンブラの方が楽で確実でした、なにせど素人プログラムなので
C言語で制御すると文字化けが止まりません、5桁書くと6桁表示されて最後の
数字が6桁目にコピーされる、や、ちょっと長い文字列を書くと全部文字化け
するなど悪戦苦闘しました、結果的に出来た物は R / G / B / IR の表示が出来ず
得られたデータの羅列と成っています。

勉強に成ったのは1バイトが二個のデータをどうやって1つの固まりにするのか
全く概念が掴めなかったのですが、何の事は無い、上位バイトを八回左シフト
して下位バイトとの論理和にすれば良いんですね、まぁその程度なんですよ
だからど素人なのです。

動画の数字ですが・・・・
RED     GREEN
BLUE   IR
・・・・という並びに成っています。


ソースファイルです、相変わらず他のデバイスの関数がありまして何でもアリ
のプログラムです、そういうゴミは消せば良いのですが何でLCDが文字化けを
起こすのか未だに原因不明です、うーーん、気持ちがスッキリしない・・・


/*
 * File:   main.c
 * Author: maru
 * I2C_Color Sensor_S11059-02DT_v000
 * Created on 2019/01/22(火)
 * 
 */

//******************************************************************************
//コンフィギュレーション
// CONFIG1 MPLAB XIDEの Production -> Set Configration bits で設定してもこのプログラムでの宣言が優先される
//#pragma config FOSC = INTRC_NOCLKOUT //RA6 = I/O          //デフォルトではRA6 = fosc/4 output
// CONFIG1
#pragma config FOSC = INTRC_NOCLKOUT// Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = ON      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // RE3/MCLR pin function select bit (RE3/MCLR pin function is MCLR)電源オン時、要リセット、しないとBootしない
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown Out Reset Selection bits (BOR enabled)
#pragma config IESO = ON       // Internal External Switchover bit (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
#pragma config LVP = ON         // Low Voltage Programming Enable bit (RB3/PGM pin has PGM function, low voltage programming enabled)

// CONFIG2
#pragma config BOR4V = BOR40V   // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF        // Flash Program Memory Self Write Enable bits (Write protection off)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

//******************************************************************************
//コンパイラ
#include 
#include 
#include 
#include 
//******************************************************************************
//外部自作ファイル



//******************************************************************************
//マクロ
#define _XTAL_FREQ 8000000      //PIC16F886はINTOSC時最高8MHzまでしか出ない下のOSCCON = 0x70;と矛盾しては成らない
#define LCD_ADD 0x7C            //LCDスレーブアドレス W
#define S5851A_ADR 0x90         //温度センサースレーブアドレス W
#define PCF8574AN_ADR 0x70      //Extentioned IO スレーブアドレス W
#define PCF8574AN_ADR_R 0x73      //Extentioned IO スレーブアドレス W
#define ToHome 0b00000010
#define shiftLeft 0b00011000
#define shiftRight 0b00011100
#define clear 0b00000001
//--------------------------

//******************************************************************************
static unsigned char I2C_rcv();
static void I2C_nacksnd();
static unsigned char I2C_ackchk();

char moji[] = " ";
char moji2[] = "Celsius ";
char moji3[] = "Thermal S-5851A SII"; //この文字列を長くするとカウントアップがバグる、原因不明
char moji4[] = "      "; //空白を書く、前の文字が残って邪魔をするから
char moji5[] = "."; //
char moji6[] = "C";

char moji10[] = "0000"; //温度計少数以下
char moji11[] = "0625"; //温度計少数以下
char moji12[] = "1250"; //温度計少数以下
char moji13[] = "1875"; //温度計少数以下
char moji14[] = "2500"; //温度計少数以下

char moji15[] = "3125"; //温度計少数以下
char moji16[] = "3750"; //温度計少数以下
char moji17[] = "4375"; //温度計少数以下
char moji18[] = "5000"; //温度計少数以下
char moji19[] = "5625"; //温度計少数以下

char moji20[] = "6250"; //温度計少数以下
char moji21[] = "6875"; //温度計少数以下
char moji22[] = "7500"; //温度計少数以下
char moji23[] = "8125"; //温度計少数以下
char moji24[] = "8750"; //温度計少数以下
char moji25[] = "9375"; //温度計少数以下

char moji30[] = "EEPROM bank="; //EEPROM
char moji31[] = "W="; //EEPROM
char moji32[] = "R="; //EEPROM

unsigned char k; // k = PCF8574ANから読み込んだデータ、char型 保存できる値は-127?127  //unsigned char型 保存できる値は 0-255です
unsigned char k2; // k2 = MCP23017から読み込んだデータ、char型 保存できる値は-127?127  //unsigned char型 保存できる値は 0-255です
unsigned char k3; // k3 = 温度センサーから読み込んだデータ、MSB  char型 保存できる値は-127?127  //unsigned char型 保存できる値は 0-255です
unsigned char k4; // k4 = 温度センサーから読み込んだデータ、LSB  但し上位4bitのみ、下位4bitはゼロ、char型 保存できる値は-127?127  //unsigned char型 保存できる値は 0-255です
unsigned char k5;
unsigned char LED;

//---------------------------------
//for EEPROM
int HADR; //EEPROM High address
int LADR; //EEPROM Low address
int ROMDATA_W; //EEPROM write data
int ROMDATA_R; //EEPROM read data

//---------------------------------
//for cplor sensor S11059-02DT
int RGB_R_MSB; //RGB
int RGB_R_LSB; //RGB
int RGB_G_MSB; //RGB
int RGB_G_LSB; //RGB
int RGB_B_MSB; //RGB
int RGB_B_LSB; //RGB
int IR_MSB; //IR
int IR_LSB; //IR
int RGB_R; //RED
int RGB_G; //GREEN
int RGB_B; //BLUE
int IR; //Infra red

//******************************************************************************

void TRIGGER() {
    PORTAbits.RA0 = 1; //for debug オシロスコープ・トリガ用 PORTA-RA0
    __delay_us(10);
    PORTAbits.RA0 = 0;
}
//-------------------------------

void I2C_Master_Init(const unsigned long c) {
    SSPCON = 0b00101000; //RC3/SCK/SCL  RC4/SDI/SDA として使用宣言
    SSPCON2 = 0;
    SSPADD = (_XTAL_FREQ / (4 * c)) - 1;
    SSPSTAT = 0b00000000; // 標準速度モードに設定する(100kHz)
}
//-------------------------------   

void I2C_Init() {
    SSPCON = 0x28; //RC3/SCK/SCL  RC4/SDI/SDA として使用宣言
    SMP = 1;
    CKE = 0;
    SSPADD = 0x13; //
}
//-------------------------------

void I2C_Master_Wait() {
    while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F));
}
//-------------------------------

void I2C_Master_Start() {
    I2C_Master_Wait();
    SEN = 1;
}
//-------------------------------

void I2C_Master_RepeatedStart() {
    I2C_Master_Wait();
    RSEN = 1;
}
//-------------------------------
//    void I2C_Master_Stop()
//    {
//      I2C_Master_Wait();
//      PEN = 1;
//    }

// ストップコンディション生成 ↑代替 maru

void I2C_Master_Stop() {

    // SSP1CON2レジスタのPENビットを1に設定すると
    // ストップコンディションが生成される
    // 発行が完了するとSSP1IFが1になるのでwhile文で待つ
    SSPIF = 0;
    SSPCON2bits.PEN = 1;
    while (SSPIF == 0) {
    }
    SSPIF = 0;

    return;
}
//-------------------------------    

//    void I2C_Master_Write(unsigned d)
//    {
//      I2C_Master_Wait();
//      SSPBUF = d;
//    }

//代替↑

void I2C_Master_Write(unsigned d)
// SSP1BUFに送信したいデータをセットすると、そのデータが送信される
// 発行が完了するとSSP1IFが1になるのでwhile文で待つ
// ACK 待ちは無い、https://tool-lab.com/make/pic-practice-40/
{
    I2C_Master_Wait(); //これが無いと全く出鱈目に成る 
    __delay_us(10); //add maru 20190125 18:15
    SSPIF = 0;
    SSPBUF = d;
    while (SSPIF == 0) {
    }
    SSPIF = 0;
    
    //   return;
}
//-------------------------------
// I2C ACK check

static unsigned char I2C_ackchk() {
    unsigned char i2c_data;

    if (ACKSTAT) {
        i2c_data = 0xFF;
    } else {
        i2c_data = 0x00;
    }

    return (i2c_data);
}
//-------------------------------
// I2C Recive 
//static unsigned char I2C_rcv() {
//	SSPIF = 0;
//	RCEN = 1;
//	while (RCEN) {}

//	return(SSPBUF);
//}

static unsigned char I2C_rcv() {
    SSPIF = 0;
    SSPCON2bits.RCEN = 1;
    while (SSPIF == 0) {
    }
    SSPIF = 0;

    return SSPBUF;
}
//-------------------------------
// I2C NACK send 
//static void I2C_nacksnd() {
//	ACKDT = 1;
//	ACKEN = 1;
//	while (ACKEN) {}

//	return;
//}
//-------------------------------

static void I2C_nacksnd() {
    // ACKDTにNACKをセット(負論理なので1を設定)
    SSPCON2bits.ACKDT = 1;
    // NACK信号生成
    SSPCON2bits.ACKEN = 1;
    while (SSPCON2bits.ACKEN) {
    }
    return;
}
//-------------------------------

static void I2C_acksnd() {
    // ACKDTにACKをセット
    SSPCON2bits.ACKDT = 0;
    // NACK信号生成
    SSPCON2bits.ACKEN = 1;
    while (SSPCON2bits.ACKEN) {
    }
    return;
}
//-------------------------------

void writeData(char t_data) {
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(LCD_ADD); //0x7C スレーブアドレス
    I2C_Master_Write(0x40); //0x40  キャラクタを書くよって宣言
    I2C_Master_Write(t_data); //キャラクタの送信
    I2C_Master_Stop(); //ストップ・コンディション
    __delay_ms(10);
}
//-------------------------------

void writeCommand(char t_command) {
    I2C_Master_Start();
    I2C_Master_Write(LCD_ADD);
    I2C_Master_Write(0x00);
    I2C_Master_Write(t_command);
    I2C_Master_Stop();
    __delay_ms(10);
}
//-------------------------------

void PICinit() {
    OSCCON = 0x70; //0x70=8MHz PIC16F886はINTOSC時最高8MHzまでしか出ない上の#define _XTAL_FREQ 8000000;と矛盾しては成らない
    ANSEL = 0b00000000;
    ANSELH = 0b00000000;
    TRISA = 0b00000000;
    TRISB = 0b00000000;
    TRISC = 0b00011000;
    PORTA = 0b00000000; //2進数で書いた場合
    PORTB = 0x00; //16進数で書いた場合
}
//******************************************************************************

void LCD_Init() { //LCDの初期化、秋月のマニュアル通り
    //TRIGGER();                //for debug オシロスコープ・トリガ用 PORTA-RA0  
    I2C_Master_Init(100000);
    __delay_ms(400);
    //TRIGGER();                //for debug オシロスコープ・トリガ用 PORTA-RA0
    writeCommand(0x38); //このプロトコルは S 0x7C 0x00 0x38 A P と成っているから下のプロトコルも全部一個ずつ送信している
    __delay_ms(20);
    writeCommand(0x39);
    __delay_ms(20);
    writeCommand(0x14);
    __delay_ms(20);
    writeCommand(0x73);
    __delay_ms(20);
    writeCommand(0x52);
    __delay_ms(20);
    writeCommand(0x6C);
    __delay_ms(250);
    writeCommand(0x38);
    __delay_ms(20);
    writeCommand(0x01);
    __delay_ms(20);
    writeCommand(0x0C);
    __delay_ms(20);
}
//-------------------------------

void LCD_str2(char *c) { //LCDに配列の文字を表示
    unsigned char i, wk;
    for (i = 0; i < 5; i++) {
        wk = c[i];
        //__delay_us(30);
        if (wk == 0x00) {
            break;
        }
        writeData(wk);

    }
}

void LCD_str(char *c) { //LCDに配列の文字を表示
    unsigned char i, wk;
    for (i = 0;; i++) {
        wk = c[i];
        if (wk == 0x00) {
            break;
        }
        writeData(wk);
    }
}
//******************************************************************************    
//S5851A_ADR 温度センサー部分

void S5851A_W(char t_data) {
    I2C_Master_Init(100000);
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(S5851A_ADR); //スレーブアドレス
    I2C_Master_Write(0x01); //
    I2C_Master_Write(t_data); //キャラクタの送信
    I2C_Master_Stop(); //ストップ・コンディション
    __delay_ms(10);
}
//******************************************************************************    
//PCF8574AN Extentioned IO 部分

void PCF8574AN_W() { //PCF8574AN Extentioned IO WRITE
    I2C_Master_Init(100000);
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(PCF8574AN_ADR); //スレーブアドレス
    I2C_Master_Write(0xAA); //データ送信
    I2C_Master_Stop(); //ストップ・コンディション
    __delay_ms(10);
}

void PCF8574AN_W2(char LED) { //PCF8574AN Extentioned IO WRITE
    I2C_Master_Init(100000);
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(PCF8574AN_ADR); //スレーブアドレス
    I2C_Master_Write(LED); //データ送信
    I2C_Master_Stop(); //ストップ・コンディション
    __delay_ms(10);
}

void PCF8574AN_R() { //PCF8574AN Extentioned IO READ
    //    I2C_Master_Init(100000);              //これだと遅い
    I2C_Init(); //これだと速い
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(PCF8574AN_ADR_R); //スレーブアドレス read
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    k = I2C_rcv(); //スレーブアドレス側からのデータを受信する
    //    I2C_rcv(k);                           //この文法では読めない
    //    PORTA = (k);                          //ここに入れるのもOK
    I2C_nacksnd(); //NACk送信
    I2C_Master_Stop(); //ストップ・コンディション
    __delay_ms(10);
}
//******************************************************************************
// MCP23017 16bit IO 部分
int GPA_LED;
int GPB_IN_DATA;

void MCP23017_GPA_INIT() {
    //MCP23017_GPAイニシャライズ
    I2C_Init(); //これだと速い
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(0x40); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Write(0x00); //レジスタ・ナンバー
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Write(0x00); //全入力設定 write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Stop(); //ストップ・コンディション
}

void MCP23017_GPB_INIT() {
    //MCP23017_GPイニシャライズ 
    I2C_Init(); //これだと速い
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(0x40); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Write(0x01); //レジスタ・ナンバー
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Write(0xFF); //全出力設定 write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Stop(); //ストップ・コンディション
}

void MCP23017_GPA_OUT(GPA_LED) {
    //MCP23017_GPAにデータ出力させる、Lチカ 
    I2C_Init(); //これだと速い
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(0x40); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Write(0x14); //レジスタ・ナンバー
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Write(GPA_LED); //LED表示 write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Stop(); //ストップ・コンディション
}

void MCP23017_GPB_IN() {
    //MCP23017_GPBのデータを読み込む、ディップスイッチ8bit 
    I2C_Init(); //これだと速い
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(0x40); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Write(0x13); //レジスタ・ナンバー
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_RepeatedStart(); //SR = RepeatedStart
    I2C_Master_Write(0x41); //スレーブアドレス READ
    I2C_Master_Wait();
    I2C_ackchk();
    k2 = I2C_rcv(); //スレーブアドレス側からのデータを受信する = k2
    I2C_nacksnd(); //NACk送信
    I2C_Master_Stop(); //ストップ・コンディション
    __delay_ms(10);

}

//******************************************************************************
//I2C 温度センサー SII S-5851A 部分

void s5851a_init() //温度センサー初期化
{
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(0x90); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする 
    I2C_Master_Write(0x01); //コンフィギュレーション・レジスタ
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Write(0x00); //常温設定
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする 
    I2C_Master_Stop(); //ストップ・コンディション
}

void s5851a_me1() //温度測定一回目のみ、二回目からはカレントリードと云う簡略化したプロトコルで良い
{
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(0x90); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする 
    I2C_Master_Write(0x00); //ダミー
    I2C_Master_Wait();
    I2C_ackchk();
    I2C_Master_RepeatedStart(); //リスタート
    I2C_Master_Write(0x91); //スレーブアドレス Read
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする 
    k3 = I2C_rcv(); //スレーブアドレス側からのデータを受信するMSB
    I2C_acksnd(); //ACK送信
    k4 = I2C_rcv(); //スレーブアドレス側からのデータを受信するLSB 但し上位4bitのみ下位4bitはゼロ
    I2C_nacksnd(); //NACK送信
    I2C_Master_Stop(); //ストップ・コンディション
}

void s5851a_me2() //温度測定一回目のみ、二回目からはカレントリードと云う簡略化したプロトコルで良い
{
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(0x91); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする 
    k3 = I2C_rcv(); //スレーブアドレス側からのデータを受信するMSB
    I2C_acksnd(); //ACK送信
    k4 = I2C_rcv(); //スレーブアドレス側からのデータを受信するLSB 但し上位4bitのみ下位4bitはゼロ
    I2C_nacksnd(); //NACK送信
    I2C_Master_Stop(); //ストップ・コンディション
}

void hairetsu() {
    if (k4 == 0) {
        LCD_str(moji10);
    } else if (k4 == 1) {
        LCD_str(moji11);
    } else if (k4 == 2) {
        LCD_str(moji12);
    } else if (k4 == 3) {
        LCD_str(moji13);
    } else if (k4 == 4) {
        LCD_str(moji14);

    } else if (k4 == 5) {
        LCD_str(moji15);
    } else if (k4 == 6) {
        LCD_str(moji16);
    } else if (k4 == 7) {
        LCD_str(moji17);
    } else if (k4 == 8) {
        LCD_str(moji18);
    } else if (k4 == 9) {
        LCD_str(moji19);

    } else if (k4 == 0x0A) {
        LCD_str(moji20);
    } else if (k4 == 0x0B) {
        LCD_str(moji21);
    } else if (k4 == 0x0C) {
        LCD_str(moji22);
    } else if (k4 == 0x0D) {
        LCD_str(moji23);
    } else if (k4 == 0x0E) {
        LCD_str(moji24);
    } else if (k4 == 0x0F) {
        LCD_str(moji25);
    }
    return;
}
//******************************************************************************
//I2C EEPROM 24LC64 部分  

void EEPROM_W() //EEPROM 1 byte write routin 2019/01/22
{
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(0xA0); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする 
    I2C_Master_Write(HADR); //EEPROM High address
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Write(LADR); //EEPROM Low address
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする 
    I2C_Master_Write(ROMDATA_W); //EEPROM Low address
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Stop(); //ストップ・コンディション
}

void EEPROM_R() //温度測定一回目のみ、二回目からはカレントリードと云う簡略化したプロトコルで良い
{
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(0xA0); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Write(HADR); //EEPROM High address
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Write(LADR); //EEPROM Low address
    I2C_Master_Wait();
    I2C_ackchk();
    I2C_Master_RepeatedStart(); //リスタート
    I2C_Master_Write(0xA1); //スレーブアドレス Read
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする 
    ROMDATA_R = I2C_rcv(); //スレーブアドレス側からのデータを受信するMSB
    I2C_nacksnd(); //NACK送信
    I2C_Master_Stop(); //ストップ・コンディション
}

//******************************************************************************
//I2C color srnsor S11059-02DT 部分

void COLOR_S() //I2C color srnsor S11059-02DT読み出し、イニシャライズは無い
{
    //TRIGGER();

    I2C_Master_Start(); //スタート・コンディション

    I2C_Master_Write(0x54); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする

    I2C_Master_Write(0x00); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする

    I2C_Master_Write(0x89); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする

    I2C_Master_RepeatedStart(); //リスタート

    I2C_Master_Write(0x54); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする

    I2C_Master_Write(0x00); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする

    I2C_Master_Write(0x09); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする

    __delay_ms(10);
    //TRIGGER();

    I2C_Master_Start(); //スタート・コンディション

    I2C_Master_Write(0x54); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする

    I2C_Master_Write(0x03); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする

    I2C_Master_RepeatedStart(); //リスタート

    I2C_Master_Write(0x55); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする

    RGB_R_MSB = I2C_rcv(); //スレーブアドレス側からのデータを受信する
    I2C_acksnd(); //マスターから送信するack

    RGB_R_LSB = I2C_rcv(); //スレーブアドレス側からのデータを受信する
    I2C_acksnd(); //マスターから送信するack

    RGB_G_MSB = I2C_rcv(); //スレーブアドレス側からのデータを受信する
    I2C_acksnd(); //マスターから送信するack

    RGB_G_LSB = I2C_rcv(); //スレーブアドレス側からのデータを受信する
    I2C_acksnd(); //マスターから送信するack

    RGB_B_MSB = I2C_rcv(); //スレーブアドレス側からのデータを受信する
    I2C_acksnd(); //マスターから送信するack

    RGB_B_LSB = I2C_rcv(); //スレーブアドレス側からのデータを受信する
    I2C_acksnd(); //マスターから送信するack

    IR_MSB = I2C_rcv(); //スレーブアドレス側からのデータを受信する
    I2C_acksnd(); //マスターから送信するack

    IR_LSB = I2C_rcv(); //スレーブアドレス側からのデータを受信する

    I2C_nacksnd(); //NACK送信
    I2C_Master_Stop(); //ストップ・コンディション
}

//******************************************************************************

int main(void) {
    PICinit(); //PICを初期化
    //-----------
    I2C_Init(); //これだと速い
    //-----------
    LCD_Init(); //LCD初期化
    __delay_ms(2);
    //-----------
    writeCommand(0x01); //画面をクリア
    __delay_ms(10);
    writeCommand(0x02); //ホームへカーソル移動
    __delay_ms(2); // LCD側の処理待ち、LCDは全く読み込めないので見込み時間

    //-------------------------------
    /*
        writeCommand(0x85); //2列目へ移動
        LCD_str2(moji32);
        writeCommand(0x8D); //2列目へ移動
        LCD_str2(moji32);
        writeCommand(0x85 + 0x40); //2列目へ移動
        LCD_str2(moji32);
        writeCommand(0x8D + 0x40); //2列目へ移動
        LCD_str2(moji32);
        __delay_ms(10);
     */
    //-------------------------------
    while (1) //Loop
    {

        COLOR_S(); //I2C color srnsor S11059-02DT読み出し
        //-------------------------------
        RGB_R_MSB = RGB_R_MSB << 8; //shift 8bit to left
        RGB_R = RGB_R_MSB | RGB_R_LSB; // make 2 byte

        RGB_G_MSB = RGB_G_MSB << 8; //shift 8bit to left
        RGB_G = RGB_G_MSB | RGB_G_LSB; // make 2 byte

        RGB_B_MSB = RGB_B_MSB << 8; //shift 8bit to left
        RGB_B = RGB_B_MSB | RGB_B_LSB; // make 2 byte

        IR_MSB = IR_MSB << 8; //shift 8bit to left
        IR = IR_MSB | IR_LSB; // make 2 byte

        writeCommand(0x80); //1列目へ移動
        __delay_ms(10);
        sprintf(moji, "%05d", RGB_R); //左寄せしない5桁
        LCD_str2(moji);
        __delay_ms(10);

        writeCommand(0x88); //1列目へ移動
        __delay_ms(10);
        sprintf(moji, "%05d", RGB_G); //左寄せしない5桁
        LCD_str2(moji);
        __delay_ms(10);

        writeCommand(0x80 + 0x40); //2列目へ移動
        __delay_ms(10);
        sprintf(moji, "%05d", RGB_B); //左寄せしない5桁
        LCD_str2(moji);
        __delay_ms(10);

        writeCommand(0x88 + 0x40); //2列目へ移動
        __delay_ms(10);
        sprintf(moji, "%05d", IR); //左寄せしない5桁
        TRIGGER();
        LCD_str2(moji);
        __delay_ms(3);

        //------------------------------- 
        __delay_ms(333);

    }
    return 0; //Loop
    //-------------------------------
}

-----------------------------------------------------------------
追記 2019/02/07(木)
前作のLCD文字化け問題を改善するためまた余所から
関数を拾ってきました、部分的に書き直して文字化け
が消えました。

ゼロサプレスですが前作はゼロ埋めして表示しましたが
今回は桁数が変化するとLCDの表示が残ってしまう事で
例えば12345と表示した後に12と表示しても前の345が

残る事で結果的に12345と何も変わらないのでは話に
成らないですよね、なので "            " という感じで
スペースを書いて事実上画面の部分的クリアを行って
上書きしています、なので表示が若干ぎごちなく感じます。


参考にしたのは 趣味を楽しむ Enjoy your hobby さんです
他にも LCD イニシャライズもI2C連続書き込みとし、前作の
ブロック毎の書き込みをやめました、最速の方法です。

ソースファイル、相変わらず他のデバイスの関数だらけです
ど素人なので動作も含め責任も権利も放棄致します。


/*
 * File:   main.c
 * Author: maru
 * I2C_Color Sensor_S11059-02DT_v001
 * Created on 2019/02/07(木)
 * 
 */

//******************************************************************************
//コンフィギュレーション
// CONFIG1 MPLAB XIDEの Production -> Set Configration bits で設定してもこのプログラムでの宣言が優先される
//#pragma config FOSC = INTRC_NOCLKOUT //RA6 = I/O          //デフォルトではRA6 = fosc/4 output
// CONFIG1
#pragma config FOSC = INTRC_NOCLKOUT// Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = ON      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // RE3/MCLR pin function select bit (RE3/MCLR pin function is MCLR)電源オン時、要リセット、しないとBootしない
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown Out Reset Selection bits (BOR enabled)
#pragma config IESO = ON       // Internal External Switchover bit (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
#pragma config LVP = ON         // Low Voltage Programming Enable bit (RB3/PGM pin has PGM function, low voltage programming enabled)

// CONFIG2
#pragma config BOR4V = BOR40V   // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF        // Flash Program Memory Self Write Enable bits (Write protection off)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

//******************************************************************************
//コンパイラ
#include 
#include 
#include 
#include 
//******************************************************************************
//外部自作ファイル



//******************************************************************************
//マクロ
#define _XTAL_FREQ 8000000      //PIC16F886はINTOSC時最高8MHzまでしか出ない下のOSCCON = 0x70;と矛盾しては成らない
#define LCD_ADD 0x7C            //LCDスレーブアドレス W
#define S5851A_ADR 0x90         //温度センサースレーブアドレス W
#define PCF8574AN_ADR 0x70      //Extentioned IO スレーブアドレス W
#define PCF8574AN_ADR_R 0x73      //Extentioned IO スレーブアドレス W
#define ToHome 0b00000010
#define shiftLeft 0b00011000
#define shiftRight 0b00011100
#define clear 0b00000001
//--------------------------

//******************************************************************************
static unsigned char I2C_rcv();
static void I2C_nacksnd();
static unsigned char I2C_ackchk();

char moji[] = " ";
char moji2[] = "Celsius ";
char moji3[] = "Thermal S-5851A SII"; //この文字列を長くするとカウントアップがバグる、原因不明
char moji4[] = "      "; //空白を書く、前の文字が残って邪魔をするから
char moji5[] = "."; //
char moji6[] = "C";

char moji10[] = "0000"; //温度計少数以下
char moji11[] = "0625"; //温度計少数以下
char moji12[] = "1250"; //温度計少数以下
char moji13[] = "1875"; //温度計少数以下
char moji14[] = "2500"; //温度計少数以下

char moji15[] = "3125"; //温度計少数以下
char moji16[] = "3750"; //温度計少数以下
char moji17[] = "4375"; //温度計少数以下
char moji18[] = "5000"; //温度計少数以下
char moji19[] = "5625"; //温度計少数以下

char moji20[] = "6250"; //温度計少数以下
char moji21[] = "6875"; //温度計少数以下
char moji22[] = "7500"; //温度計少数以下
char moji23[] = "8125"; //温度計少数以下
char moji24[] = "8750"; //温度計少数以下
char moji25[] = "9375"; //温度計少数以下

char moji30[] = "EEPROM bank="; //EEPROM
char moji31[] = "W="; //EEPROM
char moji32[] = "R="; //EEPROM

unsigned char k; // k = PCF8574ANから読み込んだデータ、char型 保存できる値は-127?127  //unsigned char型 保存できる値は 0-255です
unsigned char k2; // k2 = MCP23017から読み込んだデータ、char型 保存できる値は-127?127  //unsigned char型 保存できる値は 0-255です
unsigned char k3; // k3 = 温度センサーから読み込んだデータ、MSB  char型 保存できる値は-127?127  //unsigned char型 保存できる値は 0-255です
unsigned char k4; // k4 = 温度センサーから読み込んだデータ、LSB  但し上位4bitのみ、下位4bitはゼロ、char型 保存できる値は-127?127  //unsigned char型 保存できる値は 0-255です
unsigned char k5;
unsigned char LED;

//---------------------------------
//for EEPROM
int HADR; //EEPROM High address
int LADR; //EEPROM Low address
int ROMDATA_W; //EEPROM write data
int ROMDATA_R; //EEPROM read data

//---------------------------------
//for cplor sensor S11059-02DT
int RGB_R_MSB; //RGB
int RGB_R_LSB; //RGB
int RGB_G_MSB; //RGB
int RGB_G_LSB; //RGB
int RGB_B_MSB; //RGB
int RGB_B_LSB; //RGB
int IR_MSB; //IR
int IR_LSB; //IR
int RGB_R; //RED
int RGB_G; //GREEN
int RGB_B; //BLUE
int IR; //Infra red

//******************************************************************************

void TRIGGER() {
    PORTAbits.RA0 = 1; //for debug オシロスコープ・トリガ用 PORTA-RA0
    __delay_us(10);
    PORTAbits.RA0 = 0;
}
//-------------------------------

void I2C_Master_Init(const unsigned long c) {
    SSPCON = 0b00101000; //RC3/SCK/SCL  RC4/SDI/SDA として使用宣言
    SSPCON2 = 0;
    SSPADD = (_XTAL_FREQ / (4 * c)) - 1;
    SSPSTAT = 0b00000000; // 標準速度モードに設定する(100kHz)
}
//-------------------------------   

void I2C_Init() {
    SSPCON = 0x28; //RC3/SCK/SCL  RC4/SDI/SDA として使用宣言
    SMP = 1;
    CKE = 0;
    SSPADD = 0x13; //
}
//-------------------------------

void I2C_Master_Wait() {
    while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F));
}
//-------------------------------

void I2C_Master_Start() {
    I2C_Master_Wait();
    SEN = 1;
}
//-------------------------------

void I2C_Master_RepeatedStart() {
    I2C_Master_Wait();
    RSEN = 1;
}
//-------------------------------
//    void I2C_Master_Stop()
//    {
//      I2C_Master_Wait();
//      PEN = 1;
//    }

// ストップコンディション生成 ↑代替 maru

void I2C_Master_Stop() {

    // SSP1CON2レジスタのPENビットを1に設定すると
    // ストップコンディションが生成される
    // 発行が完了するとSSP1IFが1になるのでwhile文で待つ
    SSPIF = 0;
    SSPCON2bits.PEN = 1;
    while (SSPIF == 0) {
    }
    SSPIF = 0;

    return;
}
//-------------------------------    

//    void I2C_Master_Write(unsigned d)
//    {
//      I2C_Master_Wait();
//      SSPBUF = d;
//    }

//代替↑

void I2C_Master_Write(unsigned d)
// SSP1BUFに送信したいデータをセットすると、そのデータが送信される
// 発行が完了するとSSP1IFが1になるのでwhile文で待つ
// ACK 待ちは無い、https://tool-lab.com/make/pic-practice-40/
{
    I2C_Master_Wait(); //これが無いと全く出鱈目に成る 
    __delay_us(10); //add maru 20190125 18:15
    SSPIF = 0;
    SSPBUF = d;
    while (SSPIF == 0) {
    }
    SSPIF = 0;

    //   return;
}
//-------------------------------
// I2C ACK check

static unsigned char I2C_ackchk() {
    unsigned char i2c_data;

    if (ACKSTAT) {
        i2c_data = 0xFF;
    } else {
        i2c_data = 0x00;
    }

    return (i2c_data);
}
//-------------------------------
// I2C Recive 
//static unsigned char I2C_rcv() {
//	SSPIF = 0;
//	RCEN = 1;
//	while (RCEN) {}

//	return(SSPBUF);
//}

static unsigned char I2C_rcv() {
    SSPIF = 0;
    SSPCON2bits.RCEN = 1;
    while (SSPIF == 0) {
    }
    SSPIF = 0;

    return SSPBUF;
}
//-------------------------------
// I2C NACK send 
//static void I2C_nacksnd() {
//	ACKDT = 1;
//	ACKEN = 1;
//	while (ACKEN) {}

//	return;
//}
//-------------------------------

static void I2C_nacksnd() {
    // ACKDTにNACKをセット(負論理なので1を設定)
    SSPCON2bits.ACKDT = 1;
    // NACK信号生成
    SSPCON2bits.ACKEN = 1;
    while (SSPCON2bits.ACKEN) {
    }
    return;
}
//-------------------------------

static void I2C_acksnd() {
    // ACKDTにACKをセット
    SSPCON2bits.ACKDT = 0;
    // NACK信号生成
    SSPCON2bits.ACKEN = 1;
    while (SSPCON2bits.ACKEN) {
    }
    return;
}
//-------------------------------

void writeData(char t_data) {
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(LCD_ADD); //0x7C スレーブアドレス
    I2C_Master_Write(0x40); //0x40  キャラクタを書くよって宣言
    I2C_Master_Write(t_data); //キャラクタの送信
    I2C_Master_Stop(); //ストップ・コンディション
    __delay_ms(10);
}
//-------------------------------

void writeCommand(char t_command) {
    I2C_Master_Start();
    I2C_Master_Write(LCD_ADD);
    I2C_Master_Write(0x00);
    I2C_Master_Write(t_command);
    I2C_Master_Stop();
    __delay_ms(10);
}
//-------------------------------

void PICinit() {
    OSCCON = 0x70; //0x70=8MHz PIC16F886はINTOSC時最高8MHzまでしか出ない上の#define _XTAL_FREQ 8000000;と矛盾しては成らない
    ANSEL = 0b00000000;
    ANSELH = 0b00000000;
    TRISA = 0b00000000;
    TRISB = 0b00000000;
    TRISC = 0b00011000;
    PORTA = 0b00000000; //2進数で書いた場合
    PORTB = 0x00; //16進数で書いた場合
}
//******************************************************************************

void LCD_Init() { //LCDの初期化、秋月のマニュアル通り
    //TRIGGER();                //for debug オシロスコープ・トリガ用 PORTA-RA0  
    I2C_Master_Init(100000);
    __delay_ms(400);
    //TRIGGER();                //for debug オシロスコープ・トリガ用 PORTA-RA0
    writeCommand(0x38); //このプロトコルは S 0x7C 0x00 0x38 A P と成っているから下のプロトコルも全部一個ずつ送信している
    __delay_ms(20);
    writeCommand(0x39);
    __delay_ms(20);
    writeCommand(0x14);
    __delay_ms(20);
    writeCommand(0x73);
    __delay_ms(20);
    writeCommand(0x52);
    __delay_ms(20);
    writeCommand(0x6C);
    __delay_ms(250);
    writeCommand(0x38);
    __delay_ms(20);
    writeCommand(0x01);
    __delay_ms(20);
    writeCommand(0x0C);
    __delay_ms(20);
}

void LCD_Init3() {
    I2C_Master_Init(100000);
    I2C_Master_Start();
    I2C_Master_Write(0x7C);
    I2C_ackchk();
    I2C_Master_Write(0x80);
    I2C_ackchk();
    I2C_Master_Write(0x38);
    I2C_ackchk();
    __delay_us(30);
    I2C_Master_Write(0x80);
    I2C_ackchk();
    I2C_Master_Write(0x39);
    I2C_ackchk();
    __delay_us(30);
    I2C_Master_Write(0x80);
    I2C_ackchk();
    I2C_Master_Write(0x14);
    I2C_ackchk();
    __delay_us(30);
    I2C_Master_Write(0x80);
    I2C_ackchk();
    I2C_Master_Write(0x73);
    I2C_ackchk();
    __delay_us(30);
    I2C_Master_Write(0x80);
    I2C_ackchk();
    I2C_Master_Write(0x52);
    I2C_ackchk();
    __delay_us(30);
    I2C_Master_Write(0x80);
    I2C_ackchk();
    I2C_Master_Write(0x6C);
    I2C_ackchk();
    __delay_ms(200);
    I2C_Master_Write(0x80);
    I2C_ackchk();
    I2C_Master_Write(0x38);
    I2C_ackchk();
    __delay_us(30);
    I2C_Master_Write(0x80);
    I2C_ackchk();
    I2C_Master_Write(0x0C);
    I2C_ackchk();
    __delay_us(30);
    I2C_Master_Write(0x00);
    I2C_ackchk();
    I2C_Master_Write(0x01);
    I2C_nacksnd();
    I2C_Master_Stop();

}
//-------------------------------

void LCD_str2(char *c) { //LCDに配列の文字を表示
    unsigned char i, wk;
    for (i = 0; i < 5; i++) {
        wk = c[i];
        //__delay_us(30);
        if (wk == 0x00) {
            break;
        }
        writeData(wk);

    }
}

void LCD_str(char *c) { //LCDに配列の文字を表示
    unsigned char i, wk;
    for (i = 0;; i++) {
        wk = c[i];
        if (wk == 0x00) {
            break;
        }
        writeData(wk);
    }
}
//******************************************************************************    
//S5851A_ADR 温度センサー部分

void S5851A_W(char t_data) {
    I2C_Master_Init(100000);
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(S5851A_ADR); //スレーブアドレス
    I2C_Master_Write(0x01); //
    I2C_Master_Write(t_data); //キャラクタの送信
    I2C_Master_Stop(); //ストップ・コンディション
    __delay_ms(10);
}
//******************************************************************************    
//PCF8574AN Extentioned IO 部分

void PCF8574AN_W() { //PCF8574AN Extentioned IO WRITE
    I2C_Master_Init(100000);
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(PCF8574AN_ADR); //スレーブアドレス
    I2C_Master_Write(0xAA); //データ送信
    I2C_Master_Stop(); //ストップ・コンディション
    __delay_ms(10);
}

void PCF8574AN_W2(char LED) { //PCF8574AN Extentioned IO WRITE
    I2C_Master_Init(100000);
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(PCF8574AN_ADR); //スレーブアドレス
    I2C_Master_Write(LED); //データ送信
    I2C_Master_Stop(); //ストップ・コンディション
    __delay_ms(10);
}

void PCF8574AN_R() { //PCF8574AN Extentioned IO READ
    //    I2C_Master_Init(100000);              //これだと遅い
    I2C_Init(); //これだと速い
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(PCF8574AN_ADR_R); //スレーブアドレス read
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    k = I2C_rcv(); //スレーブアドレス側からのデータを受信する
    //    I2C_rcv(k);                           //この文法では読めない
    //    PORTA = (k);                          //ここに入れるのもOK
    I2C_nacksnd(); //NACk送信
    I2C_Master_Stop(); //ストップ・コンディション
    __delay_ms(10);
}
//******************************************************************************
// MCP23017 16bit IO 部分
int GPA_LED;
int GPB_IN_DATA;

void MCP23017_GPA_INIT() {
    //MCP23017_GPAイニシャライズ
    I2C_Init(); //これだと速い
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(0x40); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Write(0x00); //レジスタ・ナンバー
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Write(0x00); //全入力設定 write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Stop(); //ストップ・コンディション
}

void MCP23017_GPB_INIT() {
    //MCP23017_GPイニシャライズ 
    I2C_Init(); //これだと速い
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(0x40); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Write(0x01); //レジスタ・ナンバー
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Write(0xFF); //全出力設定 write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Stop(); //ストップ・コンディション
}

void MCP23017_GPA_OUT(GPA_LED) {
    //MCP23017_GPAにデータ出力させる、Lチカ 
    I2C_Init(); //これだと速い
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(0x40); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Write(0x14); //レジスタ・ナンバー
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Write(GPA_LED); //LED表示 write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Stop(); //ストップ・コンディション
}

void MCP23017_GPB_IN() {
    //MCP23017_GPBのデータを読み込む、ディップスイッチ8bit 
    I2C_Init(); //これだと速い
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(0x40); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Write(0x13); //レジスタ・ナンバー
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_RepeatedStart(); //SR = RepeatedStart
    I2C_Master_Write(0x41); //スレーブアドレス READ
    I2C_Master_Wait();
    I2C_ackchk();
    k2 = I2C_rcv(); //スレーブアドレス側からのデータを受信する = k2
    I2C_nacksnd(); //NACk送信
    I2C_Master_Stop(); //ストップ・コンディション
    __delay_ms(10);

}

//******************************************************************************
//I2C 温度センサー SII S-5851A 部分

void s5851a_init() //温度センサー初期化
{
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(0x90); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする 
    I2C_Master_Write(0x01); //コンフィギュレーション・レジスタ
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Write(0x00); //常温設定
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする 
    I2C_Master_Stop(); //ストップ・コンディション
}

void s5851a_me1() //温度測定一回目のみ、二回目からはカレントリードと云う簡略化したプロトコルで良い
{
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(0x90); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする 
    I2C_Master_Write(0x00); //ダミー
    I2C_Master_Wait();
    I2C_ackchk();
    I2C_Master_RepeatedStart(); //リスタート
    I2C_Master_Write(0x91); //スレーブアドレス Read
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする 
    k3 = I2C_rcv(); //スレーブアドレス側からのデータを受信するMSB
    I2C_acksnd(); //ACK送信
    k4 = I2C_rcv(); //スレーブアドレス側からのデータを受信するLSB 但し上位4bitのみ下位4bitはゼロ
    I2C_nacksnd(); //NACK送信
    I2C_Master_Stop(); //ストップ・コンディション
}

void s5851a_me2() //温度測定一回目のみ、二回目からはカレントリードと云う簡略化したプロトコルで良い
{
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(0x91); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする 
    k3 = I2C_rcv(); //スレーブアドレス側からのデータを受信するMSB
    I2C_acksnd(); //ACK送信
    k4 = I2C_rcv(); //スレーブアドレス側からのデータを受信するLSB 但し上位4bitのみ下位4bitはゼロ
    I2C_nacksnd(); //NACK送信
    I2C_Master_Stop(); //ストップ・コンディション
}

void hairetsu() {
    if (k4 == 0) {
        LCD_str(moji10);
    } else if (k4 == 1) {
        LCD_str(moji11);
    } else if (k4 == 2) {
        LCD_str(moji12);
    } else if (k4 == 3) {
        LCD_str(moji13);
    } else if (k4 == 4) {
        LCD_str(moji14);

    } else if (k4 == 5) {
        LCD_str(moji15);
    } else if (k4 == 6) {
        LCD_str(moji16);
    } else if (k4 == 7) {
        LCD_str(moji17);
    } else if (k4 == 8) {
        LCD_str(moji18);
    } else if (k4 == 9) {
        LCD_str(moji19);

    } else if (k4 == 0x0A) {
        LCD_str(moji20);
    } else if (k4 == 0x0B) {
        LCD_str(moji21);
    } else if (k4 == 0x0C) {
        LCD_str(moji22);
    } else if (k4 == 0x0D) {
        LCD_str(moji23);
    } else if (k4 == 0x0E) {
        LCD_str(moji24);
    } else if (k4 == 0x0F) {
        LCD_str(moji25);
    }
    return;
}
//******************************************************************************
//I2C EEPROM 24LC64 部分  

void EEPROM_W() //EEPROM 1 byte write routin 2019/01/22
{
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(0xA0); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする 
    I2C_Master_Write(HADR); //EEPROM High address
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Write(LADR); //EEPROM Low address
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする 
    I2C_Master_Write(ROMDATA_W); //EEPROM Low address
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Stop(); //ストップ・コンディション
}

void EEPROM_R() //温度測定一回目のみ、二回目からはカレントリードと云う簡略化したプロトコルで良い
{
    I2C_Master_Start(); //スタート・コンディション
    I2C_Master_Write(0xA0); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Write(HADR); //EEPROM High address
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする
    I2C_Master_Write(LADR); //EEPROM Low address
    I2C_Master_Wait();
    I2C_ackchk();
    I2C_Master_RepeatedStart(); //リスタート
    I2C_Master_Write(0xA1); //スレーブアドレス Read
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする 
    ROMDATA_R = I2C_rcv(); //スレーブアドレス側からのデータを受信するMSB
    I2C_nacksnd(); //NACK送信
    I2C_Master_Stop(); //ストップ・コンディション
}

//******************************************************************************
//I2C color srnsor S11059-02DT 部分

void COLOR_S() //I2C color srnsor S11059-02DT読み出し、イニシャライズは無い
{
    //TRIGGER();

    I2C_Master_Start(); //スタート・コンディション

    I2C_Master_Write(0x54); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする

    I2C_Master_Write(0x00); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする

    I2C_Master_Write(0x89); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする

    I2C_Master_RepeatedStart(); //リスタート

    I2C_Master_Write(0x54); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする

    I2C_Master_Write(0x00); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする

    I2C_Master_Write(0x09); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする

    __delay_ms(10);
    //TRIGGER();

    I2C_Master_Start(); //スタート・コンディション

    I2C_Master_Write(0x54); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする

    I2C_Master_Write(0x03); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする

    I2C_Master_RepeatedStart(); //リスタート

    I2C_Master_Write(0x55); //スレーブアドレス write
    I2C_Master_Wait();
    I2C_ackchk(); //ACKチェック、無くても普通に動く、スレーブアドレス違ってもスルーする

    RGB_R_MSB = I2C_rcv(); //スレーブアドレス側からのデータを受信する
    I2C_acksnd(); //マスターから送信するack

    RGB_R_LSB = I2C_rcv(); //スレーブアドレス側からのデータを受信する
    I2C_acksnd(); //マスターから送信するack

    RGB_G_MSB = I2C_rcv(); //スレーブアドレス側からのデータを受信する
    I2C_acksnd(); //マスターから送信するack

    RGB_G_LSB = I2C_rcv(); //スレーブアドレス側からのデータを受信する
    I2C_acksnd(); //マスターから送信するack

    RGB_B_MSB = I2C_rcv(); //スレーブアドレス側からのデータを受信する
    I2C_acksnd(); //マスターから送信するack

    RGB_B_LSB = I2C_rcv(); //スレーブアドレス側からのデータを受信する
    I2C_acksnd(); //マスターから送信するack

    IR_MSB = I2C_rcv(); //スレーブアドレス側からのデータを受信する
    I2C_acksnd(); //マスターから送信するack

    IR_LSB = I2C_rcv(); //スレーブアドレス側からのデータを受信する

    I2C_nacksnd(); //NACK送信
    I2C_Master_Stop(); //ストップ・コンディション
}

//******************************************************************************
//新しいLCD制御 部分 2019/02/07(木)

//---------------------------------------------------------
// LCD表示制御コマンド
//---------------------------------------------------------
void LCD_init(void); //LCDの初期設定
void LCD_Init2(); //maru
void LCD_Clear(int); //LCDクリア(0=全面、1=1行目、2=2行目)
void LCD_puts(const char *p); //LCDへ連続文字表示
void LCD_Locate(unsigned char, unsigned char); //文字表示位置の設定
void LCD_CW(unsigned char); //LCDコマンド1バイト書き込み
void LCD_DW(unsigned char); //LCDデータ1バイト書き込み

char str[5]; //16進文字変換結果代入


//---------------------------------------------------------
// Clear LCD Screen (ACM1602)
// 引数=0 全面
// 引数=1 1行目のみ
// 引数=2 2行目のみ
// 画面をクリア。カーソルはホームポジションに。
//---------------------------------------------------------

void LCD_Clear(int para) { // 0=全クリア 1=1行目に空白書き込み 2=2行目に空白書き込み
    if (para == 0) {
        LCD_CW(0x01); //LCDクリアリセット
        return;
    }
    if (para == 1) {
        LCD_Locate(0, (para - 1));
        LCD_puts("                "); //(0,0)1行目に空白書き込み
        return;
    }
    if (para == 2) {
        LCD_Locate(0, (para - 1));
        LCD_puts("                "); //(0,1)2行目に空白書き込み
        return;
    }
}


//-----------------------------------------------
//  LCD文字表示(連続)
//  現在のカーソル位置から連続して文字を書き込む
//  1行目、2行目の終端を越えた文字は無視される
//------------------------------------------------

void LCD_puts(const char *p) {
    while (*p != '\0') {
        LCD_DW(*p); // DW = Data Write でここではキャラクタを指す
        p++;
    }
}

//-----------------------------------------
//  LCD Cursor Control (x, y))
//-----------------------------------------

void LCD_Locate(unsigned char x, unsigned char y) {
    //(x,y)の意味、x = 横方向 0--F  y = 縦方向 0 = 1行目 1 = 2行目
    unsigned char pos;
    pos = 0x40 * y + x;
    pos = pos + 0x80;
    LCD_CW(pos);
}

//---------------------------------------------
// LCD コマンド1バイト書き込み
//---------------------------------------------

void LCD_CW(unsigned char lcd_cmd) {
    I2C_Master_Start();
    I2C_Master_Write(0x7C);
    I2C_Master_Write(0x00); //これからCommand書くよが 0x00 、このCommandは位置、クリア、ブリンク、カーソル、コントラストなど
    I2C_Master_Write(lcd_cmd);
    I2C_Master_Stop();
    __delay_ms(5);
}

//---------------------------------------------
// LCD データ1バイト書き込み、キャラクタ = データ
//---------------------------------------------

void LCD_DW(unsigned char lcd_dat) {
    I2C_Master_Start();
    I2C_Master_Write(0x7C);
    I2C_Master_Write(0x40); //これからData書くよ = 0x40、このDataはキャラクタです
    I2C_Master_Write(lcd_dat);
    I2C_Master_Stop();
    __delay_ms(5);

}

//******************************************************************************

int main(void) {
    PICinit(); //PICを初期化
    //-----------
    //I2C_Init(); //これだと速い
    //-----------
    //LCD_Init(); //LCD初期化
    LCD_Init3();
    __delay_ms(2);
    //-----------
    LCD_Clear(0); //画面をクリア
    __delay_ms(10);
    LCD_Locate(0, 0); //ホームへカーソル移動
    __delay_ms(2); // LCD側の処理待ち、LCDは全く読み込めないので見込み時間

    //初期画面
    LCD_Locate(0, 0); //ホームへカーソル移動、1行目左端
    LCD_puts("S11059-02DT_v001");
    LCD_Locate(0, 1); //2行目 左端へ移動
    LCD_puts("PIC16F886 I2C");
    __delay_ms(3000);
    LCD_Clear(0); //画面をクリア
    //-------------------------------
    while (1) //Loop
    {

        COLOR_S(); //I2C color srnsor S11059-02DT読み出し
        //-------------------------------
        RGB_R_MSB = RGB_R_MSB << 8; //shift 8bit to left
        RGB_R = RGB_R_MSB | RGB_R_LSB; // make 2 byte

        RGB_G_MSB = RGB_G_MSB << 8; //shift 8bit to left
        RGB_G = RGB_G_MSB | RGB_G_LSB; // make 2 byte

        RGB_B_MSB = RGB_B_MSB << 8; //shift 8bit to left
        RGB_B = RGB_B_MSB | RGB_B_LSB; // make 2 byte

        IR_MSB = IR_MSB << 8; //shift 8bit to left
        IR = IR_MSB | IR_LSB; // make 2 byte

        LCD_Locate(0, 0); //ホームへカーソル移動、1行目左端
        LCD_puts("R=     ");
        LCD_Locate(2, 0);
        itoa(str, RGB_R, 10); //toa() 関数は整数 n を文字ストリングに変換します。 
        //このストリングは、渡されたバッファーに置かれます。
        //このバッファーは、出力を 入れられるだけの十分な大きさが必要です。 
        //基数値は、OCTAL、DECIMAL、または HEX が可能です。
        LCD_puts(str);

        LCD_Locate(9, 0); //1行目 9個目へ移動
        LCD_puts("G=     ");
        LCD_Locate(11, 0);
        itoa(str, RGB_G, 10);
        LCD_puts(str);

        LCD_Locate(0, 1); //2行目 左端へ移動
        LCD_puts("B=     ");
        LCD_Locate(2, 1);
        itoa(str, RGB_G, 10);
        LCD_puts(str);

        LCD_Locate(8, 1);
        ; //2行目、9個目へ移動
        LCD_puts("IR=     ");
        LCD_Locate(11, 1);
        itoa(str, IR, 10);
        LCD_puts(str);

        //------------------------------- 
        __delay_ms(333);

    }
    return 0; //Loop
    //-------------------------------
}


nice!(0)  コメント(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。