トップページ > dsPIC入門 > dsPICでI2C(5)
//********************************************************************
//I2Cスレーブ側プログラム @dsPIC30F4012
//********************************************************************
//********************************************************************
//ヘッダファイル
#include "p30f4012.h"
#include "uart.h"
#include "i2c.h"
//********************************************************************
//コンフィギュレーション
_FOSC(CSW_FSCM_OFF & XT_PLL8); //10MHzセラロックを使っているのでクロックは80MHz。
_FWDT(WDT_OFF);
_FBORPOR(PBOR_ON & BORV_20 & PWRT_64 & MCLR_EN);
_FGS(CODE_PROT_OFF);
//********************************************************************
//I2Cの設定パラメータ
unsigned int I2Cconfig1 = I2C_ON & I2C_IDLE_CON & I2C_CLK_HLD & I2C_IPMI_DIS & I2C_7BIT_ADD & I2C_SLW_DIS
& I2C_SM_DIS &I2C_GCALL_DIS & I2C_STR_EN & I2C_NACK & I2C_ACK_DIS & I2C_RCV_DIS
& I2C_STOP_DIS & I2C_RESTART_DIS;
unsigned int I2Cconfig2 = 180; //100kbpsのつもり・・・
//********************************************************************
//関数プロトタイプ宣言
void init_uart(void);
//********************************************************************
//メイン関数
int main(void)
{
//===================================================================
//デバッグ用LEDのポート設定
TRISF = 0x06;
init_uart();
//===================================================================
//開く
OpenI2C(I2Cconfig1,I2Cconfig2);
//待機
IdleI2C();
//アドレスを設定
I2CADD=0x08;
//割り込み許可
ConfigIntI2C(MI2C_INT_OFF & SI2C_INT_ON & SI2C_INT_PRI_7);
putsUART1("I2C start as Slave\n\r");
while(BusyUART1());
IdleI2C();
while(1);
}
//********************************************************************
//I2C割り込み
void _ISR _SI2CInterrupt(void)
{
unsigned char temp;
//割り込みフラグクリア
IFS0bits.SI2CIF = 0;
//とりあえず、自分が指定されたらLEDを点灯。。。
PORTB = 0x01;
//アドレス受信の場合
if((I2CSTATbits.R_W == 0) && (I2CSTATbits.D_A == 0))
{
//デバッグ用
PORTB = 0x02;
//データを読み出して、レジスタの内容をクリアしておきます。
temp = SlaveReadI2C();
IdleI2C();
//受信動作中はクロックが止まっているので、クロック動作を再開させます。
I2CCONbits.SCLREL = 1;
return;
}
//データ受信の場合
else if((I2CSTATbits.R_W == 0) && (I2CSTATbits.D_A == 1))
{
//デバッグ用
PORTB = 0x04;
//取得データをUARTで送信しておきます。
WriteUART1(SlaveReadI2C());
while(BusyUART1());
putsUART1("\n\r");
while(BusyUART1());
//クロック動作再開。
I2CCONbits.SCLREL = 1;
return;
}
//データ送信要求の場合
//アドレスを指定されてから、即データを返すので・・・
//スレーブ側が送信する場合はI2CSTATbits.D_Aは1にならない??
else if((I2CSTATbits.R_W == 1) && (I2CSTATbits.D_A == 0))
{
//デバッグ用
PORTB = 0x08;
IdleI2C();
//デバッグ用文字列を返しておきます。
SlaveWriteI2C('c');
IdleI2C();
return;
}
return;
}
//********************************************************************
void init_uart(void)
{
unsigned int config1 = UART_EN & UART_IDLE_CON & UART_ALTRX_ALTTX & UART_NO_PAR_8BIT & UART_1STOPBIT
& UART_DIS_WAKE & UART_DIS_LOOPBACK & UART_DIS_ABAUD;
unsigned int config2 = UART_INT_TX_BUF_EMPTY & UART_TX_PIN_NORMAL & UART_TX_ENABLE & UART_INT_RX_CHAR
& UART_ADR_DETECT_DIS & UART_RX_OVERRUN_CLEAR;
//115200[bps]に設定。
OpenUART1(config1,config2,10);
}