STM32F1 HALライブラリィ…

久々にSTM32F103C8T6マイコンボードを引っ張り出して気圧計モジュールのBMP180をテストしてみた。
シンプルにポーリンクでBMP180を駆動しようとしたのだけど、これが動かない!!!

昔I2Cの何かモジュールでテストしたときはOKだったので、同じように書いたのですが、これが動かない!!!

BMP180とI2Cで通信しようとするとHAL_BUSYでタイム・アウトする。ソースはどう見ても間違ってないのです。

I2C通信でHAL_BUSY

ググってみてもそれらしいトラブル報告が見つからない。お手上げになっしまいました。

とあるさんの”STM32F1のI2Cの初期化でハマった“という記事にたどり着きました。
とあるさんによるとI2CのバスはGOIOを初期化した時点でBUSY状態になってしまうとのこと 💡

STM32CubeMxが吐き出したスケルトンソースのstm32f1xx_hal_msp.cの該当箇所を以下のように順番を入れ替えてみたら、動きました!!!
とあるさんの推察は正しく、HAL_GPIO_Init関数を呼び出した時点でI2CパスがBUSYになるようなのです。

void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{

  GPIO_InitTypeDef GPIO_InitStruct;
  if(hi2c->Instance==I2C1)
  {
  /* USER CODE BEGIN I2C1_MspInit 0 */
#if 0
  /* USER CODE END I2C1_MspInit 0 */
  
    /**I2C1 GPIO Configuration    
    PB8     ------> I2C1_SCL
    PB9     ------> I2C1_SDA 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    __HAL_AFIO_REMAP_I2C1_ENABLE();

    /* Peripheral clock enable */
    __HAL_RCC_I2C1_CLK_ENABLE();
  /* USER CODE BEGIN I2C1_MspInit 1 */
#else
    /* Peripheral clock enable */
    __HAL_RCC_I2C1_CLK_ENABLE();

    /**I2C1 GPIO Configuration    
    PB8     ------> I2C1_SCL
    PB9     ------> I2C1_SDA 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    __HAL_AFIO_REMAP_I2C1_ENABLE();
#endif
  /* USER CODE END I2C1_MspInit 1 */
  }
}

腑に落ちないが、こうしなければI2Cは使えないのだ!!!

いつからI2Cバスのトラブルか発生するようになったのか!?

昔I2Cのデバイスをテストしたときは動いてたと思うのだが、いつからこうなったのだ!!

I2Cバスのトラブルは解決までかなり苦労したので、今トラブってお手上げ状態の方のためにメモ残します。