手把手教你用CubeMX给GD32F103点灯、串口通信(附完整代码)

张开发
2026/4/19 12:09:36 15 分钟阅读

分享文章

手把手教你用CubeMX给GD32F103点灯、串口通信(附完整代码)
从零开始用CubeMX点亮GD32F103完整开发指南与避坑手册第一次拿到GD32开发板时我和大多数嵌入式开发者一样充满疑虑——这个号称与STM32引脚兼容的国产芯片真的能用熟悉的CubeMX工具链开发吗经过三个月的实际项目验证我发现只要掌握几个关键配置技巧GD32F103完全可以用STM32那套生态快速上手。本文将带你从CubeMX工程创建开始完成LED控制与串口通信这两个最基础但最重要的功能验证过程中会特别标注与STM32开发的差异点并提供可直接复用的代码模板。1. 开发环境搭建与工程创建1.1 工具链准备开发GD32F103需要以下软件环境注意版本选择直接影响兼容性STM32CubeMX建议6.5.0及以上版本IDEKeil MDK需安装GD32设备支持包或VSCodePlatformIOGD32固件库从官网下载GigaDevice.GD32F10x_DFP.x.x.x.pack设备包提示GD32的HAL库与STM32有细微差异建议始终使用CubeMX生成代码框架避免直接移植STM32项目1.2 CubeMX工程初始化关键步骤新建工程时选择STM32F103C8T6作为芯片型号利用引脚兼容特性在Project Manager → Code Generator中勾选Generate peripheral initialization as a pair of .c/.h files在Project Manager → Advanced Settings中设置GD32的宏定义USE_HAL_DRIVER GD32F10X_MD时钟树配置时需要特别注意HSE Value → 8MHz (需与实际板载晶振一致) CPU Clock → 72MHz (GD32F103最高频率) APB1 Prescaler → 2 (确保APB1时钟不超过36MHz)2. GPIO配置与LED控制实战2.1 引脚配置的特殊处理在CubeMX中配置PC13为LED控制引脚时需要额外注意在Pinout视图右键PC13选择GPIO_Output在Configuration → GPIO中设置GD32特有配置Output mode需选择Push-Pull与STM32不同Pull-up/Pull-down根据电路设计选择开发板通常需要上拉对比项STM32默认配置GD32推荐配置Output LevelHighLowMaximum SpeedLowMediumOutput TypePush-PullPush-Pull2.2 代码实现与调试技巧生成代码后在main.c中添加LED闪烁逻辑/* USER CODE BEGIN PV */ #define LED_Pin GPIO_PIN_13 #define LED_GPIO_Port GPIOC /* USER CODE END PV */ int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); while (1) { HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); HAL_Delay(500); // 500ms间隔 } }常见问题排查LED不亮检查开发板LED电路是低电平还是高电平驱动闪烁频率异常确认SystemCoreClock已正确设置为72MHz下载失败确保调试器配置中选择的是Cortex-M3内核3. 串口通信完整实现3.1 CubeMX中的UART配置细节使用USART1进行串口通信时这些参数需要特别注意波特率115200需与终端软件一致数据位8bits停止位1bitGD32特有设置在NVIC Settings中必须使能中断在DMA Settings中建议添加RX的DMA通道配置完成后生成代码会自动生成以下关键函数HAL_UART_Init() HAL_UART_Transmit() HAL_UART_Receive_IT()3.2 中断接收与回显实现在stm32f1xx_it.c中添加中断处理void USART1_IRQHandler(void) { HAL_UART_IRQHandler(huart1); }在main.c中实现回调函数/* USER CODE BEGIN 0 */ uint8_t RxBuffer[1]; void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart-Instance USART1) { HAL_UART_Transmit(huart, RxBuffer, 1, 100); HAL_UART_Receive_IT(huart, RxBuffer, 1); // 重新启用接收 } } /* USER CODE END 0 */ int main(void) { // ...初始化代码... HAL_UART_Receive_IT(huart1, RxBuffer, 1); // 启动中断接收 while(1) { // 主循环可添加其他任务 } }4. 工程优化与进阶技巧4.1 解决GD32特有的时钟问题GD32的时钟树与STM32存在细微差异若发现外设时钟异常可尝试修改SystemClock_Config()中的FLASH延迟__HAL_FLASH_SET_LATENCY(FLASH_LATENCY_2);检查APB1/APB2分频设置是否合理4.2 提高代码效率的实用技巧使用寄存器操作替代HAL库提升GPIO切换速度LED_GPIO_Port-ODR ^ LED_Pin; // 比HAL_GPIO_TogglePin快3倍串口DMA传输配置示例HAL_UART_Transmit_DMA(huart1, (uint8_t*)Hello GD32\r\n, 12);4.3 常见问题快速排查表现象可能原因解决方案无法下载程序调试器配置错误确认选择Cortex-M3而非M0/M4串口无输出波特率不匹配检查CubeMX与终端设置LED响应延迟时钟配置错误重新校验SystemClock_Config中断不触发NVIC未使能在CubeMX中勾选对应中断在完成基础功能验证后可以进一步测试PWM、SPI等外设。实际项目中我发现GD32的ADC精度表现甚至优于同价位STM32但I2C时序需要更严格的超时设置。

更多文章