STM32G031でI2Cモニター


目的
I2Cモニターで開発力アップ


![o_con420.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/fca67e17-4a62-1eec-69bb-072f9073e9ed.jpeg)


![o_con421.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/5667ecc6-2944-b0cb-a63d-bb4e105b43fe.jpeg)



マスター


https://qiita.com/caa45040/items/89fa7395fef2e8b8338a


I2c-USART-USBコンバーター


https://qiita.com/caa45040/items/5032e6905c9425f41495



いろいろ

既に目標だった低速ソフトウェアI2Cの開発は、達成されていて
高速系は、ちょっとした、お遊び
そろそろ、I2Cは飽きてきたので、RS-485をやり始めるか
目標しては、当面500Kbps 監視線とロングのブレーク信号あり8バイト分
パケット転送、ヘッダー0x00,フッターが0xFF,8バイト固定で有効4バイト
(32ビット固定),アドレス

--00 00 00 00   00 00 00 00--    ブレーク

--00 AA DD DD   DD DD CC FF--　　8バイト固定パケット

AA アドレス
DD DD DD DD データ 4バイト
CC チェックサム　先頭32ビット目

アドレスは、8ビットで0x00の使用は、禁止
装置IDやサブアドレスは、めんどいから設けない
255あれば足りるでしよう。そもそも32台以上電気的に繋がらない
老舗の旅館的に拡張していくとパケット長がだんだん延びていく

チェックサムは、自分を含めないで8バイト足したもの
自分は、仮に0x00 、　おおくのシステムは、アンクを取っているが
赤外線リモコン的なシステムは、アンクは、ないので投げっぱなし

リードは、アドレスの先頭が1でアドレスとオール0とチェックサム
STM32G031の全ポート(6ビット)を使えば足りるか?
1 RX
2 VDD
3 GND
4 システム側の半二重

8 TX
7 ブレーク監視
6　ブレーク送信
5　方向操作


サーボみたいな物は、アドレス1個で送りっぱなし

温度センサーみたいな物は、アドレス1個で受けぱなし

エンコーダ、カウンターみたいな物は、カウントしっぱなし
32ビットでオーバーフローしてもそのまま


可変長は、処理がめんどくさくなるから、しない
なんだかんだ要求を詰め込むとバケットサイズが約15百バイトとかになって
0で埋めなくては、いけないのでめんどい
実際には、固定長で使うのでめんどい

RS-485を使ったシステムで似たようなので1週間ぐらい掛ったからな
たぶんそのくらいかかる
サーボ、温度、赤外線距離、超音波距離、カウンター、電流
絶対条件は、アナログサーボを32個、数珠繋ぎ
逆接防止、短距離フラットの時にグランドはさみ
1 VDD
2 [A]
3 GND
4 [B]



STM32G031で遊ぶのそのままのプログラム


```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





```