![]() |
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);
}
|