16F88のスレーブ側プログラム
マスタがデバイスアドレス 0x68 にデータを送信した場合、マスタからのデータを受け取り バーLED に表示します。表示する値が5の場合、左から5個のLEDをすべて点灯します。
バーLEDは10個のLEDから構成されますが、PIC側には、連続したポートがありません。PA0-PA4,PA6,PA7,PB0,PB2,PB3、のトビトビの端子を利用します。A,B
ポートにまたがり、連続でもありません。そこで、二つの配列を利用します。各配列は、表示したい値に対する、各ポートの値を設定しておきます。
int sega[11]={0xFF,0x1,0x3,0x7,0xf,0x1f,0x7f,0xff,0xff,0xff,0xfF};
int segb[11]={0x7,0x0,0x0,0x0,0x0,0x0, 0x0, 0x0, 0x1, 0x3, 0x7};
表示が0(10と同じ)の場合、sega[0],segb[0]は、0xffと0x7、となりフル点灯になります。またポートBの場合、I2Cの信号がありますから、まとめて出力できません。1本づつ個別に出力します。
//I2C LedBar Slave
//マスタからのデータでAポートのLEDを点灯
//LED Bar
//I2Cアドレス 0x68
//LED接続 PA0-PA4,PA6,PA7,PB0,PB2,PB3
#include <16F88.h>
//#fuses HS,NOWDT,NOLVP,NOBROWNOUT
#fuses INTRC_IO,NOWDT,NOLVP,NOBROWNOUT
#use delay(clock = 4000000)
#use I2c(slave,sda=PIN_B1,scl=PIN_B4,address=0x68,force_hw)
#use fast_io(B)
#use fast_io(A)
int val;
int state;
int sega[11]={0xFF,0x1,0x3,0x7,0xf,0x1f,0x7f,0xff,0xff,0xff,0xfF};
int segb[11]={0x7,0x0,0x0,0x0,0x0,0x0, 0x0, 0x0, 0x1, 0x3, 0x7};
#INT_SSP
void ssp_interupt (){
state=i2c_isr_state();
if(state>=0x80){//addrs match with master read
//i2c_write(0);//return value
}
else if(state >0){//adrs match with master write
val=i2c_read(0);//1:ack,default 0:nack
val=val %10;
output_A(sega[val]);//1-7
output_bit(PIN_B0,segb[val]&0x1);//8
output_bit(PIN_B2,segb[val]&0x2);//9
output_bit(PIN_B3,segb[val]&0x4);//10
//output_bit(PIN_B5,segb[val]&0x8);//10
output_toggle(PIN_B5);//受信で点滅
}
}
void main (){
set_tris_a(0x20);
output_float(PIN_B1); //I2C pin float
output_float(PIN_B4); //I2C pin float
set_tris_b(0x12); //I2Cの端子は入力に設定
val=0;
enable_interrupts(INT_SSP); //SSP割り込みを許可
enable_interrupts(GLOBAL); //全ての割り込みを許可
while (1) {
sleep();
}
}