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





x まだ試していない　確認済み2022/5/8 6:37


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

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

イメージです。


![o_con368.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/a48ed787-5f7b-debd-ed1c-b1d7ca7cc9e1.jpeg)



![o_con401.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/843a1bda-9c98-11a8-aa05-8884e052193e.jpeg)



![o_con402.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/1f8cb408-02b1-486b-50ed-7c81fd81a4ae.jpeg)



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


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




いろいろ

ほぼ、意味のない情報　2022/5/7 20:30 ふろ行ってくらー
mbed版を単純に置き換えただけ
LCDやI2C-USARTコンバータや距離センサーと低速でやり取り出来たら
いいなと作り始めてハマりまくり




バグ修正済み


```c++




//soft_i2c_slave_test_031_1

#include <Arduino.h>

//1ピン PB7 LED1
//2ピン Vdd
//3ピン Gnd
//4ピン PA0 TX

//5ピン PA14 SWD-CL
//6ピン PA13 SWD-DA
//7ピン PA12 SDA
//8ピン PA11 SCL

//GPIOの初期化 //LED1
#define myled PB7


#define DW   digitalWrite
#define TX1        PA0   // 4pin
#define UART_DELAY 106  // 012-110 9600bps ok 031

//仮想シリアルへの一文字出力 9600bps
void pc_putc(char ch)
{
  DW(TX1, HIGH);

  DW(TX1, LOW);//START
  delayMicroseconds(UART_DELAY); //START BIT WAIT

  for (int ii = 0; ii < 8; ii++) {
    DW(TX1, (ch >> ii) & 1  );
    delayMicroseconds(UART_DELAY); //DATA 1-8BIT WAIT
  }//for

  DW(TX1, HIGH);//Stop
  delayMicroseconds(UART_DELAY); //StOP BIT WAIT

}//pc_putc


//文字列の表示
int pc_printf(char *str1) {

  //文字の中身がゼロか
  while (*str1) {

    //一文字出力
    pc_putc(*str1 ++);

  } //while

  //戻り値
  return (0);
}//pc_printf


#define  SDA1 PA12
#define  SCL1 PA11

int TinmOut1 = 100000;

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

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

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

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

//SCLがLの間は、ループ TinmOut1付き
void SCL_L() {
  while (digitalRead(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()
*/

//初期化関数
void setup()
{

  //TXポートの初期化
  pinMode(TX1, OUTPUT);
  DW(TX1, HIGH);

  //LED1ポートの初期化
  pinMode(myled, OUTPUT);

  //ソフトI2Cの初期化
  pinMode(SDA1, INPUT);
  pinMode(SCL1, INPUT);

}//setup

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];

//無限ループ
void loop()
{

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

  //開始
  SDA_START();

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

  SCL_H();
  SCL_L();
  a6 = digitalRead(SDA1);

  SCL_H();
  SCL_L();
  a5 = digitalRead(SDA1);

  SCL_H();
  SCL_L();
  a4 = digitalRead(SDA1);

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

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

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

  SCL_H();
  SCL_L();
  a0 = digitalRead(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 = digitalRead(SDA1);

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

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

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

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

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

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

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

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


  digitalWrite(myled, HIGH); //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]);

  digitalWrite(myled, HIGH); //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("[] ");
    }//ebdif
    
  }//for
  pc_printf("\r\n");//リターン


  //データの表示
  for (ii = 0; ii < 8; ii++) {
    if (ii == 4) pc_printf(": ");

    if (d[ii] == 0) {
      pc_printf("__ ");
    } else {
      pc_printf("[] ");
    }//endif
    
  }//for
  pc_printf("\r\n");//リターン

  delay(500);//0.5秒待つ
  
}//loop





```







たぶんバグだらけ




```c++




//soft_i2c_slave_test_031_1


#include <Arduino.h>



//1ピン PB7 LED1
//2ピン Vdd
//3ピン Gnd
//4ピン PA0 TX


//5ピン PA14 SWD-CL
//6ピン PA13 SWD-DA
//7ピン PA12 SDA
//8ピン PA11 SCL  




//GPIOの初期化 //LED1
#define myled PB_4


#define DW   digitalWrite
#define TX1        PA0   // 4pin
#define UART_DELAY 106  // 012-110 9600bps ok 031


//仮想シリアルへの一文字出力 9600bps
void pc_putc(char ch)
{
  DW(TX1, HIGH);

  DW(TX1, LOW);//START
  delayMicroseconds(UART_DELAY); //START BIT WAIT

  for (int ii = 0; ii < 8; ii++) {
    DW(TX1, (ch >> ii) & 1  );
    delayMicroseconds(UART_DELAY); //DATA 1-8BIT WAIT
  }//for

  DW(TX1, HIGH);//Stop
  delayMicroseconds(UART_DELAY); //StOP BIT WAIT

}//pc_putc


//文字列の表示
int pc_printf(char *str1) {

    //文字の中身がゼロか
    while(*str1){

        //一文字出力
        pc_putc(*str1 ++);

    } //while

    //戻り値
    return(0);
}//pc_printf



#define  SDA1 PA_12
#define  SCL1 PA_11


int TinmOut1 = 100000;


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



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

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

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

//SCLがLの間は、ループ TinmOut1付き
void SCL_L() {while(digitalRead(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 setup()
{

  //TXポートの初期化
  pinMode(TX1, OUTPUT);
  DW(TX1, HIGH);


  //LED1ポートの初期化
  pinMode(myled, OUTPUT);


  pinMode(SDA1, INPUT);
  pinMode(SCL1, INPUT);

}//setup

    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];

//無限ループ
void loop() {



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

        //開始
        SDA_START();
        

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

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

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

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

        SCL_H();
        SCL_L();
        a0 = digitalRead(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 = digitalRead(SDA1);

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

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

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

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

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

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

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

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


        digitalWrite(myled,HIGH); //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]);

        digitalWrite(myled,HIGH); //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");

        delay(500);

    

}//loop




```