トップページ > 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); }