It has been a while since I compared some 32F103 chips. Most recent posts has been about identifying them, but let’s now have a look at how they perform. In this post I will have a look at the I²C peripheral.

The test is simple: A number of I²C peripherals is connected to the chip under test, and I will attempt to communicate with them. This will be done using the blocking API. At this point, no tests of the interrupt or DMA methods of using the I²C peripheral are done, just the blocking API. These tests are performed at 100 kHz and at 400 kHz.

The I²C sensors/peripherals under tests are:

  • SSD1306
  • BH1750
  • SHT3X
  • LM75B
  • HCD1080
  • CCS811
  • PCF8563
  • BMP280

The 32F103 chips tested are:

  • APM32F103 (ApexMic)
  • APM32F103 (Geehy)
  • CH32F103
  • CS32F103
  • FCM32F103
  • GD32F103
  • HK32F103
  • MH32F103
  • STM32F103xB

As well as RISC-V based 32F103 chips

  • CH32V103
  • GD32VF103

The following chips have not been tested, as they are too different from an STM32F103 to run an unmodified firmware:

  • BLM32F103
  • MG32F103
  • MM32F103
  • RX32F103

The firmware is written against the STM32F1 HAL and CMSIS. The firmware will first test whether communication with the device is possible (HAL_I2C_IsDeviceReady()) and then try to read the sensor, rtc, or put a text on the display.

The results of the test: (results.txt) Most microcontrollers work fine, but there are some issues:

One of the chips with problems is the GigaDevice GD32F103. At 100 kHz everything works out fine, however, running at 400 kHz there are problems communicating with certain devices. The devices causing problems are: BH1750, LM75B, HCD1080 and CCS811. One thing to note, the HAL_I2C_IsDeviceReady() succeeds, but actual communication fails. When the communication fails, all further I²C communication will fail. The I²C peripheral must be re-initialised in order to allow for further communication.

Also GigaDevices RISC-V variant has issues. Again, the same BH1750, LM75B, HCD1080 and CCS811 cause issues, with the only difference, the HCD1080 already fails at HAL_I2C_IsDeviceReady() at 400 kHz, and this does not disturb further I²C communication.

The other device giving trouble is the MegaHunt MH32F103. This chip is also known as Air32F103. It might be sold as “STM32F103C8T6 china” on AliExpress, with re-labelled chips. As the chips are re-labelled, I can not be certain it is actually a MegaHunt part. Either when labelled as STM32F103 or Air32F103. But that aside, let’s look at the results. On the MH32, the HCD1080 causes problems at any speed. Further communication is not possible, even when re-initialising the I²C peripheral. All other devices communicate fine at 100 kHz, but at 400 kHz, the SHT3X and CCS811 cause problems. Further communication ain’t possible, but this time, re-initialising the I²C peripheral enabled further communication again.

Edit 2023-03-18: The SSD1306 Display fails on the FCM32F103. I didn’t capture this error before, as I was using the u8g2 graphics library which does not do any error handling, and only looked at the initial HAL_I2C_IsDeviceReady() result to determine the test results for the display.

It seems the HCD1080 and CCS811 are the most notable sensors to cause issues. In earlier notes I had written down the HCD1080 to also fail on the HK32, but right now, all tests on the HK32 succeed. Tests in the past have been performed with earlier versions of the STM32F1 HAL, and that may explain the difference. However, there is something about these devices. I guess I should connect a logic analyser or a scope to look into the details some times, but for now, my testing mainly concerns running the same binary on all chips and collect the results.

The code used for testing can be found at github