トップページ > dsPIC入門 > dsPICでI2C(4)
//********************************************************************
//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 writeI2C(char address,char data);
unsigned char readI2C(unsigned char address);
void init_uart(void);
//********************************************************************
//メイン関数
int main(void)
{
unsigned int i;
//===================================================================
TRISE = 0x00;
PORTE = 0x00;
init_uart();
//===================================================================
//開く
OpenI2C(I2Cconfig1,I2Cconfig2);
IdleI2C();
//マスター側なので、アドレスは適当な値に設定。
I2CADD = 0x09;
putsUART1("I2C start as Master\n\r");
while(BusyUART1());
//スレーブ側の立ち上がりを待つ。
for(i=0;i<60000;i++);
//データ書き込みテスト
writeI2C(0x08,'a');
writeI2C(0x08,'b');
//データ読み込みテスト
if(readI2C(0x08) == 'c')
{
//デバッグ用に、いろいろ出しておきます。
putsUART1("Receive Succeeded...\n\r");
while(BusyUART1());
PORTE = 0xff;
writeI2C(0x08,'@');
}
//I2Cを閉じる
while(I2CCONbits.PEN);
CloseI2C();
while(1);
}
//********************************************************************
//7bitアドレス指定で1文字送信
void writeI2C(char address,char data)
{
//スタートコンディション発行
StartI2C();
//待機。これ入れないと動作しません・・・
IdleI2C();
//アドレスデータを1bitだけ上位へシフト。
address = address << 1;
//スレーブへ送信する場合は最下位bitが0です。
address &= 0b11111110;
//アドレス送信
MasterWriteI2C(address);
//データ送信完了まで待つ。
while(I2CSTATbits.TBF);
//スレーブ側からアクノリッジが帰ってきていることを確認
while(I2CSTATbits.ACKSTAT);
//待機。これ入れないと動作しません・・・
IdleI2C();
//データ送信
MasterWriteI2C(data);
//データ送信まで待ちます。
while(I2CSTATbits.TBF);
//スレーブ側からアクノリッジが帰ってきていることを確認
while(I2CSTATbits.ACKSTAT);
//待機
IdleI2C();
//通信を一時停止。
StopI2C();
IdleI2C();
}
//********************************************************************
unsigned char readI2C(unsigned char address)
{
//受信データ格納変数
unsigned char received_data;
//スタートコンディション発行
StartI2C();
//待機
IdleI2C();
//アドレスデータを1bitだけ上位へシフト。
address = address << 1;
//スレーブから受信する場合は最下位bitが1です。
address |= 0b00000001;
//アドレス送信
MasterWriteI2C(address);
//データ送信完了まで待つ。
while(I2CSTATbits.TBF);
//スレーブ側からアクノリッジが帰ってきていることを確認
while(I2CSTATbits.ACKSTAT);
//待機。これ入れないと動作しません・・・
IdleI2C();
//データ受信
received_data = MasterReadI2C();
IdleI2C();
//データ送信完了を知らせるためにNACKを返します。
NotAckI2C();
IdleI2C();
//通信を一時停止。
StopI2C();
return received_data;
}
//********************************************************************
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);
}