PCF8574の1,2,3ピンはチップのアドレス設定で、ここでは0に設定しています。 従って、アドレスは0x40となります。 P0(4), P1(5)には抵抗を介してLEDを電源に繋いでいます。 SDA(15), SCL(14)は2.2kΩで電源にプルアップしています。 P6(11),P7(12)の入力テストのために1kΩのプルダウン抵抗に接触させます。 |
main.c | |
---|---|
#include "vs-wrc003.h" // 汎用I2cデジタル入出力拡張用ICであるPCF8574のテスト // P0(4)にLEDを付ける // P1(5)にLEDを付ける // P6(11)とP7(12)をグラウンドに交互に接触させると // 基板上のLEDが点灯する void main(void); void main() { //制御周期の設定[単位:Hz 範囲:30.0~] const BYTE MainCycle = 60; unsigned char x; Init((BYTE)MainCycle); // CPUの初期設定 i2c_init(); // I2Cの初期化 while(1) { IOwrite(1); // P0をon P1をoff Wait(200); IOwrite(2); // P0をoff P1をon Wait(200); IOwrite(0xff); // 入力モードにする x = IOread() & 0xc0; // 入力して2bitのみにする x >>= 6; // 下位の2bitに移動させる LED(~x); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
i2c.c | |
---|---|
/* ---------------------------------------------------------------------- i2c.c i2c バス処理 ---------------------------------------------------------------------- */ #include "iodefine.h" /* ---------------------------------------------------------------------- i2c_checkBusCondition i2c バスが空くまで待つ ---------------------------------------------------------------------- */ void i2c_waitBusFree() { while (IIC2.ICCR2.BIT.BBSY == 1); } /* ---------------------------------------------------------------------- i2c_sendStartCondition i2c バスに開始要求を送る ---------------------------------------------------------------------- */ void i2c_sendStartCondition() { IIC2.ICCR2.BYTE = 0xbd; } /* ---------------------------------------------------------------------- i2c_sendStopCondition i2c バスに停止要求を送る ---------------------------------------------------------------------- */ void i2c_sendStopCondition() { IIC2.ICSR.BIT.STOP = 0; // STOP をクリアする IIC2.ICCR2.BYTE = 0x3D; // 停止条件を発行する(BBSY=0, SCP=0) while (IIC2.ICSR.BIT.STOP != 1) ; } /* ---------------------------------------------------------------------- i2c_setTransmitMode i2c 送受信モードの設定 0: スレーブ受信モード 1: スレーブ送信モード 2: マスタ受信モード 3: マスタ送信モード ---------------------------------------------------------------------- */ void i2c_setTransmitMode(unsigned char tmode) { switch (tmode){ case 0: tmode = 0x00; // MST=0, TRS=0 break; case 1: tmode = 0x10; // MST=0, TRS=1 break; case 2: tmode = 0x20; // MST=1, TRS=0 break; case 3: tmode = 0x30; // MST=1, TRS=1 break; } // レジスタに送受信モードを設定する IIC2.ICCR1.BYTE = ((IIC2.ICCR1.BYTE & 0xcf) | tmode); } /* ---------------------------------------------------------------------- i2c_sendByte i2c バスへ1バイト送信 ---------------------------------------------------------------------- */ unsigned char i2c_sendByte(unsigned char ch) { unsigned char tend; // データを送信する IIC2.ICDRT = ch; while(1) { tend = IIC2.ICSR.BIT.TEND; if(tend == 1) break; } // ACK を返す return(IIC2.ICIER.BIT.ACKBR); } /* ---------------------------------------------------------------------- i2c_receiveByte i2c バスから1バイト受信 ack: データ受信時相手に返すACKビット rcvd: 最終バイトをリードするときは1にするこの後停止条件発行可能になる 連続してデータ受信する場合は0 ---------------------------------------------------------------------- */ unsigned char i2c_receiveByte(unsigned char ack, unsigned char rcvd) { unsigned char rdt; // データ受信後に送信するACKフラグを設定する。 IIC2.ICIER.BIT.ACKBT = ack; // 最終バイト読み込み時は1 IIC2.ICCR1.BIT.RCVD = rcvd; // i2c バスから送られるデータの受信開始 rdt = IIC2.ICDRR; // データが8bit転送されるまで待つ while(IIC2.ICSR.BIT.RDRF != 1) ; // 揃ったデータを取り出す rdt = IIC2.ICDRR; return(rdt); } /* ---------------------------------------------------------------------- i2c_init i2c初期化 ---------------------------------------------------------------------- */ void i2c_init(void) { // I2C の転送レートをΦ/200(Φ=20MHz, 100kHz)に設定する IIC2.ICCR1.BIT.CKS = 0x0d; // IIC バスモードをMSB ファースト、ウェイト挿入しない、 // ビット数: 9 ビットに設定する IIC2.ICMR.BIT.MLS = 0; // MSB First IIC2.ICMR.BIT.WAIT = 0; // WAIT 無し IIC2.ICMR.BIT.BCWP = 0; // ビットカウンタライトプロテクト解除 IIC2.ICMR.BIT.BC = 0; // 9ビット IIC2.ICMR.BIT.BCWP = 1; // ビットカウンタライトプロテクト // IIC2 I/F モジュールの動作状態を転送動作可能状態 // (SCL/SDA は、バス駆動状態)に設定する IIC2.ICCR1.BIT.ICE = 1; } /*---------------------------------------------------------------- ここからPCF8574専用ルーチン -----------------------------------------------------------------*/ #define PCF8574_WRITE 0x40 void IOwrite(unsigned char data) { unsigned char rdt; i2c_waitBusFree(); // i2c バス空き待ち do { i2c_setTransmitMode(3); // マスタ送信モード i2c_sendStartCondition(); // i2c バスを開始条件にする rdt = i2c_sendByte(PCF8574_WRITE); // スレーブアドレスを送信 } while(rdt == 1); // デバイスからACKが返るまでガンバル i2c_sendByte(data); // レジスタ番号を送信 IIC2.ICSR.BIT.TEND = 0; i2c_sendStopCondition(); // i2c バスを停止条件にする。 i2c_setTransmitMode(0); // スレーブ受信モードにする } unsigned char IOread() { unsigned char rdt; i2c_waitBusFree(); // i2c バス空き待ち do { i2c_setTransmitMode(3); // マスタ送信モード i2c_sendStartCondition(); // i2c バスを開始条件にする rdt = i2c_sendByte(PCF8574_WRITE); // スレーブアドレスを送信 } while(rdt == 1); // デバイスからACKが返るまでガンバル i2c_setTransmitMode(3); // マスタ送信モード i2c_sendStartCondition(); // i2c バスを開始条件にする i2c_sendByte(PCF8574_WRITE | 1); // スレーブアドレスを送信 i2c_setTransmitMode(2); // マスタ受信モード IIC2.ICSR.BIT.TDRE = 0; rdt = i2c_receiveByte(1, 1); // ACK=1, RCVD = 1で受信する。 i2c_sendStopCondition(); // i2c バスを停止条件にする。 IIC2.ICCR1.BIT.RCVD = 0; i2c_setTransmitMode(0); // スレーブ受信モードにする return(rdt); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
右側にもう一つのPCF8574を追加します。 PCF8574の1ピンをVddに繋ぎ、2,3ピンはチップはGNDに繋ぎます。 従って、アドレスは0x42となります。 SDA(15), SCL(14)はとなりの同等のピンに繋げます。 P6(11),P7(12)の入力テストのために1kΩのプルダウン抵抗に接触させます。 |
main.c |
---|
#include "vs-wrc003.h" // 汎用I2cデジタル入出力拡張用ICであるPCF8574のテスト // 0x40のアドレスのチップを出力に用い、 // 0x42のアドレスのチップを入力に用いる設定 // 0x40側 // P0(4)にLEDを付ける // P1(5)にLEDを付ける // 0x42側 // P6(11)をグラウンドに接触させると、基板上緑のLEDが点灯する // P7(12)をグラウンドに接触させると、基板上橙のLEDが点灯する #define PCF8574 0x40 void main(void); void main() { //制御周期の設定[単位:Hz 範囲:30.0~] const BYTE MainCycle = 60; unsigned char x; int ioAdr = PCF8574; Init((BYTE)MainCycle); //CPUの初期設定 i2c_init(); // I2Cの初期設定 IOwrite(ioAdr+2, 0xff); // 入力モードにする while(1) { IOwrite(ioAdr, 1); // P0をon P1をoff Wait(200); IOwrite(ioAdr, 2); // P0をoff P1をon Wait(200); x = IOread(ioAdr+2) & 0xc0; // 入力して2bitのみにする x >>= 6; // 下位の2bitに移動させる LED(~x); } } |
i2c.c |
---|
/* ---------------------------------------------------------------------- i2c.c i2c バス処理 ---------------------------------------------------------------------- */ #include "iodefine.h" /* ---------------------------------------------------------------------- i2c_checkBusCondition i2c バスが空くまで待つ ---------------------------------------------------------------------- */ void i2c_waitBusFree() { while (IIC2.ICCR2.BIT.BBSY == 1); } /* ---------------------------------------------------------------------- i2c_sendStartCondition i2c バスに開始要求を送る ---------------------------------------------------------------------- */ void i2c_sendStartCondition() { IIC2.ICCR2.BYTE = 0xbd; } /* ---------------------------------------------------------------------- i2c_sendStopCondition i2c バスに停止要求を送る ---------------------------------------------------------------------- */ void i2c_sendStopCondition() { IIC2.ICSR.BIT.STOP = 0; // STOP をクリアする IIC2.ICCR2.BYTE = 0x3D; // 停止条件を発行する(BBSY=0, SCP=0) while (IIC2.ICSR.BIT.STOP != 1) ; } /* ---------------------------------------------------------------------- i2c_setTransmitMode i2c 送受信モードの設定 0: スレーブ受信モード 1: スレーブ送信モード 2: マスタ受信モード 3: マスタ送信モード ---------------------------------------------------------------------- */ void i2c_setTransmitMode(unsigned char tmode) { switch (tmode){ case 0: tmode = 0x00; // MST=0, TRS=0 break; case 1: tmode = 0x10; // MST=0, TRS=1 break; case 2: tmode = 0x20; // MST=1, TRS=0 break; case 3: tmode = 0x30; // MST=1, TRS=1 break; } // レジスタに送受信モードを設定する IIC2.ICCR1.BYTE = ((IIC2.ICCR1.BYTE & 0xcf) | tmode); } /* ---------------------------------------------------------------------- i2c_sendByte i2c バスへ1バイト送信 ---------------------------------------------------------------------- */ unsigned char i2c_sendByte(unsigned char ch) { unsigned char tend; // データを送信する IIC2.ICDRT = ch; while(1) { tend = IIC2.ICSR.BIT.TEND; if(tend == 1) break; } // ACK を返す return(IIC2.ICIER.BIT.ACKBR); } /* ---------------------------------------------------------------------- i2c_receiveByte i2c バスから1バイト受信 ack: データ受信時相手に返すACKビット rcvd: 最終バイトをリードするときは1にするこの後停止条件発行可能になる 連続してデータ受信する場合は0 ---------------------------------------------------------------------- */ unsigned char i2c_receiveByte(unsigned char ack, unsigned char rcvd) { unsigned char rdt; // データ受信後に送信するACKフラグを設定する。 IIC2.ICIER.BIT.ACKBT = ack; // 最終バイト読み込み時は1 IIC2.ICCR1.BIT.RCVD = rcvd; // i2c バスから送られるデータの受信開始 rdt = IIC2.ICDRR; // データが8bit転送されるまで待つ while(IIC2.ICSR.BIT.RDRF != 1) ; // 揃ったデータを取り出す rdt = IIC2.ICDRR; return(rdt); } /* ---------------------------------------------------------------------- i2c_init i2c初期化 ---------------------------------------------------------------------- */ void i2c_init(void) { // I2C の転送レートをΦ/200(Φ=20MHz, 100kHz)に設定する IIC2.ICCR1.BIT.CKS = 0x0d; // IIC バスモードをMSB ファースト、ウェイト挿入しない、 // ビット数: 9 ビットに設定する IIC2.ICMR.BIT.MLS = 0; // MSB First IIC2.ICMR.BIT.WAIT = 0; // WAIT 無し IIC2.ICMR.BIT.BCWP = 0; // ビットカウンタライトプロテクト解除 IIC2.ICMR.BIT.BC = 0; // 9ビット IIC2.ICMR.BIT.BCWP = 1; // ビットカウンタライトプロテクト // IIC2 I/F モジュールの動作状態を転送動作可能状態 // (SCL/SDA は、バス駆動状態)に設定する IIC2.ICCR1.BIT.ICE = 1; } /*---------------------------------------------------------------- ここからRCF8574専用ルーチン -----------------------------------------------------------------*/ void IOwrite(int address, int data) { unsigned char rdt; i2c_waitBusFree(); // i2c バス空き待ち do { i2c_setTransmitMode(3); // マスタ送信モード i2c_sendStartCondition(); // i2c バスを開始条件にする rdt = i2c_sendByte(address); // スレーブアドレスを送信 } while(rdt == 1); // デバイスからACKが返るまでガンバル i2c_sendByte(data); // レジスタ番号を送信 IIC2.ICSR.BIT.TEND = 0; i2c_sendStopCondition(); // i2c バスを停止条件にする。 i2c_setTransmitMode(0); // スレーブ受信モードにする } unsigned char IOread(int address) { unsigned char rdt; i2c_waitBusFree(); // i2c バス空き待ち do { i2c_setTransmitMode(3); // マスタ送信モード i2c_sendStartCondition(); // i2c バスを開始条件にする rdt = i2c_sendByte(address); // スレーブアドレスを送信 } while(rdt == 1); // デバイスからACKが返るまでガンバル i2c_setTransmitMode(3); // マスタ送信モード i2c_sendStartCondition(); // i2c バスを開始条件にする i2c_sendByte(address | 1); // スレーブアドレスを送信 i2c_setTransmitMode(2); // マスタ受信モード IIC2.ICSR.BIT.TDRE = 0; rdt = i2c_receiveByte(1, 1); // ACK=1, RCVD = 1で受信する。 i2c_sendStopCondition(); // i2c バスを停止条件にする。 IIC2.ICCR1.BIT.RCVD = 0; i2c_setTransmitMode(0); // スレーブ受信モードにする return(rdt); } |