STM32F303でソフトウェアI2Cスレーブで遊ぶ　その1


目的
I2Cスレーブの規格を都合よく解釈して
I2Cスレーブを作ってみた。

フルの移行図なんか完全に無視


イメージです。


![o_con368.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/6b5a1e52-31a6-147f-df44-2538ff665371.jpeg)


![o_con399.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/9657b669-082c-192d-db6c-72daab3163b3.jpeg)



テストて使ったI2Cマスター (修正前　0x80「0」)


https://qiita.com/caa45040/items/6cfdcb4c7319a0456ee4


いろいろ

必要ない情報　2022/5/7 15頃　半日とかして、つまつたので
近くのサイデリアに軽食を食いに行って行ってタイムアウトのアイデアを思い付いた
同期がうまく取れないとどこかに引っかかってしまいうまくいかなかった。
一旦タイムアウトすると必ず、SDAの立ち下がり待ちに引っかかるので
とりあえずうまくいった。



```c++





//soft_i2c_slave_test_303_1


#include "mbed.h"

//GPIOの初期化
DigitalOut myled(PB_3);//LED1

//シリアルの初期化
Serial pc(SERIAL_TX, SERIAL_RX); //nucleo 303


DigitalIn  SDA1(A4);
DigitalIn  SCL1(A5);

int TinmOut1 = 100000;


//SDAがHの間は、ループ
#define SDA_START() while(SDA1 == 1){}



//SDAがHの間は、ループ TinmOut1付き
#define SDA_H() while(SDA1 == 1 && TinmOut1 != 0){TinmOut1--;}

//SDAがLの間は、ループ TinmOut1付き
#define SDA_L() while(SDA1 == 0 && TinmOut1 != 0){TinmOut1--;}

//SCLがHの間は、ループ TinmOut1付き
void SCL_H() {while(SCL1 == 1 && TinmOut1 != 0){TinmOut1--;}}

//SCLがLの間は、ループ TinmOut1付き
void SCL_L() {while(SCL1 == 0 && TinmOut1 != 0){TinmOut1--;}}

int input,input_bk=1;

//立ち上がり
void SCL_UP_H()
{
    while(TinmOut1 != 0){
       
       //立ち上がり
       input = SCL1;
       if( input_bk != input ){
           if( input == 1 ) break;
       }//endif
       
      //バックアップの保存
      input_bk = input;
      
      TinmOut1--; 
    }//while
}//SCL_UP_H()

//メイン関数
int main()
{

    char buf[10]; //I2Cバッファー
    int ii; //ループカウンター

    //アドレス
    int a0,a1,a2,a3,a4,a5,a6,a7;
    int a[8];

    //データ
    int d0,d1,d2,d3,d4,d5,d6,d7;
    int d[8];



    //無限ループ
    while(1) {


        //スタート信号の立下りを待つ
        //タイムアウトの設定
        TinmOut1=100000;        

        //開始
        SDA_START();
        

        //アドレスの取り込み
        SCL_H();
        SCL_L();
        a7 = SDA1;
        
        SCL_H();
        SCL_L();
        a6 = SDA1;
        
        SCL_H();
        SCL_L();
        a5 = SDA1;
        
        SCL_H();
        SCL_L();
        a4 = SDA1;

        SCL_H();
        SCL_L();
        a3 = SDA1;

        SCL_H();
        SCL_L();
        a2 = SDA1;

        SCL_H();
        SCL_L();
        a1 = SDA1;

        SCL_H();
        SCL_L();
        a0 = SDA1;


        //a7 = 1;
        //a6 = 0;
        //a5 = 0;
        //a4 = 0;
        //a3 = 0;
        //a2 = 0;
        //a1 = 0;
        //a0 = 0;

        //アンクの処理
        SCL_H();
        SCL_L();
        //a0 = SDA1;

        //データの取り込み

        SCL_H();
        SCL_L();
        d7 = SDA1;

        SCL_H();
        SCL_L();
        d6 = SDA1;

        SCL_H();
        SCL_L();
        d5 = SDA1;

        SCL_H();
        SCL_L();
        d4 = SDA1;

        SCL_H();
        SCL_L();
        d3 = SDA1;

        SCL_H();
        SCL_L();
        d2 = SDA1;

        SCL_H();
        SCL_L();
        d1 = SDA1;

        SCL_H();
        SCL_L();
        d0 = SDA1;

        //d7 = 0;
        //d6 = 0;
        //d5 = 1;
        //d4 = 1;
        //d3 = 0;
        //d2 = 0;
        //d1 = 0;
        //d0 = 0;


        myled = 1; //LED ON  debug

        buf[0] = 'U';//バッファーのクリア


        //I2Cスレーブの受信データの表示
        pc.putc(buf[0]);
        pc.printf("\r\n");
        

        //I2Cスレーブの受信データの表示 debug
        //pc.printf("Read A: %x\r\n", buf[0]);

        myled = 0; //LED OFF  debug


        a[7]=a0;
        a[6]=a1;
        a[5]=a2;
        a[4]=a3;
        a[3]=a4;
        a[2]=a5;
        a[1]=a6;
        a[0]=a7;
        
        d[7]=d0;
        d[6]=d1;
        d[5]=d2;
        d[4]=d3;
        d[3]=d4;
        d[2]=d5;
        d[1]=d6;
        d[0]=d7;

        //アドレスの表示
        for(ii=0; ii<8; ii++) {
            if(ii == 4) pc.printf(": ");
            
            if(a[ii] == 0){
                pc.printf("__ ");
            }else {
                pc.printf("[] ");   
            }
        }
        pc.printf("\r\n");


        //データの表示
        for(ii=0; ii<8; ii++) {
             if(ii == 4) pc.printf(": ");
             
             if(d[ii] == 0){
                pc.printf("__ ");
            }else {
                pc.printf("[] ");   
            }
           

        }
        pc.printf("\r\n");

        wait_ms(500);

    }//while

}//main





```