GD32F103CBT6 Won't Blink

Hi Everyone,

I’ve got myself some Chinese GD32F103CBT6’s (128KB Flash, 20KB SRAM). Got them soldered onto a breakout board, and I can successfully connect, wipe, and upload programs to it. I was expecting this MC to be pin-equivalent to the beloved bluepill’s STM32F103C8T6 (went with CB instead of C8 for the extra memory space). STM32Cube recognizes it all properly (device ID 0x410 with 128KB flash). Tried a full chip erase before any uploads.

I’ve got an 8MHz crystal across pins 5 and 6, and a decoupling capacitor on RST. Boot1 and Boot0 are tied to GND.

I’m using VScode with PlatformIO, and my platformio.ini looks like this. I’ve tried other configurations too, matching the generic bluepill and the 128kb version of the bluepill.
[env:genericSTM32F103CB]
platform = ststm32
board = genericSTM32F103CB
framework = arduino
board_build.mcu = stm32f103cbt6
board_build.f_cpu = 72000000L

Got a simple Blink program to blink PA1 every 100ms.
#include <Arduino.h>
#define LED PA1
void setup() {
pinMode(LED, OUTPUT);
}
void loop() {
digitalWrite(LED,HIGH);
delay(100);
digitalWrite(LED,LOW);
}

Compiles fine, uploads fine, but the pin won’t blink.

I’ve tried:

Changing the platformio.ini environment to bluepill_f103c8_128k and bluepill_f103c8 (and changing the board name appropriately)
Addressing the pin name differently (PA1 vs PA_1), and tried different pins.

I’m wondering if I need to somehow change the clock settings? Has anyone gotten a GD32F103CBT6 to work out like a bluepill?

I’m not very experienced with more advanced embedded platforms, I’ve only recently started using STM32’s, but I’m trying to get this GD32 working to provide myself a backup for global chip shortages, in case supply chain issues fail me when trying to source STM parts. I did recently successfully build my project out on a STM32G071CBT6, and was quite pleased that I got that to work, but I expected this task to be as simple as treating the GD32 like a bluepill, but this is proving not to be the case. Fortunately the slight differences between the two chips aren’t critical to my application.

Any guidance here would be appreciated! Let me know if I can provide any more information here.

There is no delay after setting the LED to LOW. The code will set the LED to LOW and then immediately come back around to the start of loop and set the LED HIGH and wait. The LED will always be high.

Good point, silly oversight on my end- but in this case the LED doesn’t go high at all either, I should have specified.

Even not with higher delay() times?

Can you add this to the source code:

extern "C" void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_PeriphCLKInitTypeDef PeriphClkInit;

  /* Initializes the CPU, AHB and APB busses clocks */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = 16;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
    Error_Handler();
  }

  /* Initializes the CPU, AHB and APB busses clocks */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
                                | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) {
    Error_Handler();
  }

  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
  PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
    Error_Handler();
  }
}

and change

board_build.f_cpu = 72000000L

to

board_build.f_cpu = 64000000L

in the platformio.ini.

This should replace the clock setup code with a 64MHz from internal high-speed oscillator configuration (to rule out a non-working or wrongly configured oscillator).

This worked! Got the LED blinking, thank you! Next step is to connect my LCD screen and see if I can port my old program over, but I don’t think this should be an issue now that it’s alive.

Also, I’ve used many of your examples from your other posts so solve all kinds of problems, thank you so much for your support for the community :slightly_smiling_face:

1 Like

That’s good to hear!

But this also means that the microcontroller wasn’t able to start from the external crystal in the default configuration (HSE + PLL to 72MHz). So maybe something is wrong with the crystal or it has the wrong loading capacitors installed or whatever. Pins 5 + 6 are definitely right for the LQFP48 package according to the datasheet.