STM32L010とMbedでI2Cスレーブの受信文字をシリアル出力(受信)(STM32L010F4P6)HAL


x 過去ログを見よ->
x Mbed2リビジョン143

目的
I2Cスレーブのテスト
I2Cのみしかピンの関係で出力できないマイコンをデバッグする時に便利
I2C-USRT,I2C to USRT,I2Cとシリアルコンバータと言うらしい


いろいろ
コピペすると動くと思うけどやや難しい



![o_con152.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/2e09f593-2548-45ae-7ae0-bca7fa49c323.jpeg)




いろいろ
I2Cとシリアルの変換関係でいろいろ同じ様な物が乱発されているが
いろいろテストしたいお年頃なのでゆるしてちょんまげ(おやじギャグ)。

I2C,シリアル変換は、いろいろ昔から出ているけど高速系に振っている
感じがする。割り込みやDMAを使いI2Cで1Mbpsとかシリアルで1Mbpsとか
リングバッファーを使ったりとかなんか需要あるのか?
設定もフルで出来る様になっている物が多い?
商業的にやるとフルフルMAXで最大速度が売りになるのかね?
温度センサー系の低速デバイスの時は、9600bpsでなんの問題もナッシング
高速系だと確率的に取りこぼしする確率が上がる様な気がするしかも
ケーブル(よりせん線がおすすめ)や伝達距離が極端に短くなる(1cmとか)
プルアップ抵抗を大きくして(50Ωとか)、パワフルな外部トランジスタで
引いてあげなきゃいけなくなるような、ならないような?
I2Cフラッシュメモリだとかだとそこそこ高速なのがあるか例　M24C64-RDW6TP　1MHz





```c++


//I2C_SLAVE_TEST2_2

#include "mbed.h"

//I2Cアドレス
const int ADDR = 0x80; //  address

//I2Cの構造体
I2C_HandleTypeDef hi2c1;

//シリアルの構造体
UART_HandleTypeDef huart2;


//I2Cの初期化
void I2C_INIT1()
{

    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C1;
    PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
    HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);

    __HAL_RCC_GPIOA_CLK_ENABLE();

    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    __HAL_RCC_I2C1_CLK_ENABLE();

    //I2C_HandleTypeDef hi2c1;

    hi2c1.Instance = I2C1;
    hi2c1.Init.Timing = 0x00000708;
    hi2c1.Init.OwnAddress1 = ADDR;
    hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
    hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
    hi2c1.Init.OwnAddress2 = 0;
    hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
    hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
    hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
    HAL_I2C_Init(&hi2c1);

    HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE);

    HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0);

}//I2C_INIT1


//シリアルの初期化
void USRT_INIT1()
{

    //シリアルの構造体の定義
    //UART_HandleTypeDef huart2;

    //シリアルへのクロックの選択
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
    PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
    HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);

    //シリアルへクロックの供給
    __HAL_RCC_USART2_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();

    //シリアル用のGPIOの設定
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    //シリアルの設定
    huart2.Instance = USART2;
    huart2.Init.BaudRate = 9600;
    huart2.Init.WordLength = UART_WORDLENGTH_8B;
    huart2.Init.StopBits = UART_STOPBITS_1;
    huart2.Init.Parity = UART_PARITY_NONE;
    huart2.Init.Mode = UART_MODE_TX_RX;
    huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart2.Init.OverSampling = UART_OVERSAMPLING_16;
    huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
    huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    HAL_UART_Init(&huart2);

}//USRT_INIT1


//GPIOの初期化
void GPIO_INIT1()
{

    __HAL_RCC_GPIOA_CLK_ENABLE();

    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = GPIO_PIN_4;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}//GPIO_INIT1

//メイン関数
int main()
{
    wait_ms(2); //HAL_Delay()になぜか失敗するので呼び出す

    //I2Cの初期化
    I2C_INIT1();

    //シリアルの初期化
    USRT_INIT1();

    //GPIOの初期化
    GPIO_INIT1();

    //無限ループ
    while (1) {
       
        uint8_t aRxBuffer[10] = {0};

        while (HAL_I2C_Slave_Receive(&hi2c1,aRxBuffer, 1, 1000) != HAL_OK) {};

        //LED ON debug
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);

        //I2Cスレーブの受信データの表示
        HAL_UART_Transmit(&huart2,aRxBuffer, 1, 10);

        //I2Cスレーブの受信データの表示
        //HAL_UART_Transmit(&huart2, (uint8_t *)"\tRead A: ", 9, 10);
        //uint8_t n1  = '0' + (aRxBuffer[0] % 16);
        //uint8_t n10 = '0' + (aRxBuffer[0] / 16);
        //HAL_UART_Transmit(&huart2, &n10, 1, 10);
        //HAL_UART_Transmit(&huart2, &n1, 1, 10);
        //HAL_UART_Transmit(&huart2, (uint8_t *)"\r\n", 2, 10);

        //LED OFF debug
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);

    }//while

}//main

//容量削減
void error(const char* format, ...) {}




```