STM32G031でソフトウェアI2Cで遊ぶ



x ANK時もPPでしているので注意 修正済み 2022/5/3 13:26
x PPは、オープンドレインでは、なく、プルプッシュ

目的
I2C-USART用


![o_con382.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/49aacc65-0433-788c-bb5c-4b2ae625e189.jpeg)




![o_con374.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/ab5ce89a-72a9-4c80-0bec-3db71b2c2d50.jpeg)




イメージです。

-368



![o_con368.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/1155db81-0b80-cb92-7b73-82684dc100b5.jpeg)


修正後



```C++



//soft_i2c_test_031_1

#include <Arduino.h>


//A5
#define SCK_0_HIGH()  digitalWrite(PA11, HIGH)
#define SCK_0_LOW()   digitalWrite(PA11, LOW)

//A4
#define SDA_0_HIGH()  digitalWrite(PA12, HIGH)
#define SDA_0_LOW()   digitalWrite(PA12, LOW)
#define SDA_O         A4

// 1000us   1kh
//  100us  10kh
//   10us 100kh
#define myDelay()  delayMicroseconds(100);

int soft_i2c(char add_p, char data_p) {

  int ii;

  //待ち
  SDA_0_HIGH();
  SCK_0_HIGH();
  myDelay();
  myDelay();
  myDelay();

  //START
  SDA_0_LOW();
  myDelay();
  SCK_0_LOW();
  myDelay();

  for (ii = 0; ii < 8; ii++) {
    SCK_0_LOW();
    if ( ((add_p << ii) & 0x80) == 0 ) {
      SDA_0_LOW();
    } else {
      SDA_0_HIGH();
    }//endif
    myDelay();
    SCK_0_HIGH();
    myDelay();
  }//for

  //ack
  SCK_0_LOW();
  SDA_0_HIGH();
  myDelay();
  SCK_0_HIGH();
  myDelay();

  for (ii = 0; ii < 8; ii++) {
    SCK_0_LOW();

    if ( ((data_p << ii) & 0x80) == 0 ) {
      SDA_0_LOW();
    } else {
      SDA_0_HIGH();
    }//endif

    myDelay();
    SCK_0_HIGH();
    myDelay();
  }//for

  //ack
  SCK_0_LOW();
  SDA_0_HIGH();
  myDelay();
  SCK_0_HIGH();
  myDelay();

  //STOP
  SCK_0_LOW();
  SDA_0_LOW();
  myDelay();
  SCK_0_HIGH();
  myDelay();
  SDA_0_HIGH();
  myDelay();

  return (0);

}//soft_i2c


void setup() {

  pinMode(PA12, OUTPUT_OPEN_DRAIN);
  pinMode(PA11, OUTPUT_OPEN_DRAIN);
  digitalWrite(PA12, HIGH);
  digitalWrite(PA11, HIGH);

}//setup


void loop() {

  char *ss1 = "hello world\r\n";
  int ii = 0;
  while (ss1[ii] != 0 ) {
    soft_i2c(0x80, ss1[ii]); ii++;
  }//while

  delay(1000); //1秒の待ち

}//loop




```



修正前(0x80に「0」を送信)

```c++


//soft_i2c_test_031_1

#include <Arduino.h>

//A5
#define SCK_0_HIGH()  digitalWrite(PA11, HIGH)
#define SCK_0_LOW()   digitalWrite(PA11, LOW)

//A4
#define SDA_0_HIGH()  digitalWrite(PA12, HIGH)
#define SDA_0_LOW()   digitalWrite(PA12, LOW)
#define SDA_O         A4


// 1000us   1kh
//  100us  10kh
//   10us 100kh
#define myDelay()  delayMicroseconds(100);

//debug
/*

  int d_sda = 0;
  int d_sck = 0;

  void debug1(){

  Serial.print("300,");
  Serial.print( (d_sda * 100)+20 );
  Serial.print( ',' );
  Serial.print( d_sck * 100 + 10);
  Serial.print(",0");
  Serial.println(" ");

  }

  void myDelay(){

  for(int ii=0;ii<10;ii++){
    delay(100);
    debug1();
  }

  }

  //A5
  void SCK_0_HIGH()  {digitalWrite(A5, HIGH);d_sck =1;}
  void SCK_0_LOW()   {digitalWrite(A5, LOW); d_sck =0;}

  //A4
  void SDA_0_HIGH()  {digitalWrite(A4, HIGH);d_sda = 1;}
  void SDA_0_LOW()   {digitalWrite(A4, LOW); d_sda = 0;}

*/


int soft_i2c(char add_p, char data_p) {

  int ii;

  //  for (ii = 0;ii<15;ii++){
  //   digitalWrite(13, HIGH);delay(20);digitalWrite(13, LOW);delay(20);
  //  }

  //待ち
  SDA_0_HIGH();
  SCK_0_HIGH();
  myDelay();
  myDelay();
  myDelay();

  //START
  SDA_0_LOW();
  myDelay();
  SCK_0_LOW();
  myDelay();


  for (ii = 0; ii < 8; ii++) {
    SCK_0_LOW();
    if ( ((add_p << ii) & 0x80) == 0 ) {
      SDA_0_LOW();
    } else {
      SDA_0_HIGH();
    }//endif
    myDelay();
    SCK_0_HIGH();
    myDelay();
  }//for

  //ack
  SCK_0_LOW();
  SDA_0_HIGH();
  //pinMode(SDA_O, INPUT);
  myDelay();
  SCK_0_HIGH();
  myDelay();
  //pinMode(SDA_O, OUTPUT); digitalWrite(SDA_O, HIGH);

  //    //debug
  //    SCK_0_HIGH();SDA_0_HIGH();
  //    myDelay();myDelay();myDelay();

  for (ii = 0; ii < 8; ii++) {
    SCK_0_LOW();

    if ( ((data_p << ii) & 0x80) == 0 ) {
      SDA_0_LOW();
    } else {
      SDA_0_HIGH();
    }//endif

    myDelay();
    SCK_0_HIGH();
    myDelay();
  }//for

  //ack
  SCK_0_LOW();
  SDA_0_HIGH();
  //pinMode(SDA_O, INPUT);
  myDelay();
  SCK_0_HIGH();
  myDelay();
  //pinMode(SDA_O, OUTPUT); digitalWrite(SDA_O, HIGH);

  //    //debug
  //    SCK_0_HIGH();SDA_0_HIGH();
  //    myDelay();myDelay();myDelay();

  //STOP
  SCK_0_LOW();
  SDA_0_LOW();
  myDelay();
  SCK_0_HIGH();
  myDelay();
  SDA_0_HIGH();
  myDelay();

  //    //debug
  //    SCK_0_HIGH();SDA_0_HIGH();
  //    myDelay();myDelay();myDelay();
  //    //debug
  //    SCK_0_HIGH();SDA_0_HIGH();
  //    myDelay();myDelay();myDelay();

  return (0);

}//soft_i2c


void setup() {

  //debug
  //シリアルポートの初期化
  //Serial.begin(9600);

  pinMode(PA12, OUTPUT);
  pinMode(PA11, OUTPUT);
  digitalWrite(PA12, HIGH);
  digitalWrite(PA11, HIGH);

}//setup


void loop() {

  soft_i2c(0x80, '0');
  delay(1000); //1秒の待ち

}//loop



```