嵌入式从0到1开发环境搭建

如果大家身边没有芯片和开发板的同学,可通过wokwi在线仿真网站开发,
- 具体教程参考:Wokwi在线仿真网站使用
我这里演示通过Mac搭建,windows同理。核心是三个软件:CLion IDE + STM32CubeMX + STM32CubeCLT (命令行工具集)
- CLion IDE:代码编辑、项目管理和调试界面。
- STM32CubeMX:用于图形化配置芯片引脚、时钟和外设,并生成基础代码。
- STM32CubeCLT (命令行工具集):统一调度编译器和专用调试工具。安装这个工具集之后就不用专门,去安装 OpenOCD 和 arm-none-eabi-gcc 了。
因为我这里使用的是STLink调试,所以不用安装其他工具。
之所以选择这三款而不用常规的Keil,一个是因为本地电脑环境受限,另一个是因为CLion有AI插件以及代码补全,开发起来非常的便捷。
环境搭建
我这里是Mac M3 arm64环境
1. CLion:代码编辑
CLion IDE:代码编辑、项目管理和调试界面。
下载地址:JetBrains 官网(非商业用途可免费使用)

2. STM32CubeMX:基础代码生成
STM32CubeMX:用于图形化配置芯片引脚、时钟和外设,并生成基础代码。
下载地址:STM32CubeMX下载链接

3. STM32CubeCLT:命令工具集
STM32CubeCLT (命令行工具集):统一调度编译器和专用调试工具。安装这个工具集之后就不用专门,去安装 OpenOCD 和 arm-none-eabi-gcc 了。
下载地址:STM32CubeCLT下载链接
下载后解压是两个pkg包,无脑下一步安装即可,安装之后我本地默认在/opt/ST/STM32CubeCLT_1.21.0
路径,不同版本号路径可能不同。

项目实战
这里我们以LED简单流水灯效果(双灯)为例。
1. STM32CubeMX生成基础代码
- 打开CLion - New Project - STM32CubeMX

- 选择Launch STM32CubeMX,打开CubeMX,配置对应参数,替我们生成初始化代码

- 进入CubeMX后,选择配置MCU,然后选择自己的芯片,开始项目配置


- Debug选择Serial Wire,时钟和串口我这里先不设置,后续直接通过AI+IDE快速编写

- 设置项目目录、编译器等,然后生成代码


- 复制项目路径,在CLion中打开


2. CLion配置调试环境、编写代码
- 编译环境我这里选择默认的,大家如果想自己配置一套点击+号重新配置即可


- 编写c代码,以控制LED灯点亮
这一步直接跟AI描述你的需求或者需要锻炼编码能力的手动编写也可。同时根据你的开发板原理图确认 LED 的点亮电平。
main.h:
c
#ifndef __MAIN_H
#define __MAIN_H
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32f4xx_hal.h"
void Error_Handler(void);
#ifdef __cplusplus
}
#endif
#endif /* __MAIN_H */
main.c:
c
#include "stm32f4xx_hal.h"
/* 系统时钟配置函数声明 */
void SystemClock_Config(void);
void Error_Handler(void);
/* LED 引脚定义 */
#define LED0_PIN GPIO_PIN_9 // PF9
#define LED1_PIN GPIO_PIN_10 // PF10
#define LED_PORT GPIOF
/* 简易延时函数 */
static void delay_ms(uint32_t ms)
{
HAL_Delay(ms);
}
/* LED 初始化 */
static void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* 使能 GPIOF 时钟 */
__HAL_RCC_GPIOF_CLK_ENABLE();
/* 配置 PF9, PF10 为推挽输出,默认高电平(LED 灭) */
GPIO_InitStruct.Pin = LED0_PIN | LED1_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct);
/* 熄灭两个 LED(高电平) */
HAL_GPIO_WritePin(LED_PORT, LED0_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(LED_PORT, LED1_PIN, GPIO_PIN_SET);
}
int main(void)
{
/* HAL 库初始化(必须) */
HAL_Init();
/* 配置系统时钟(建议使用 CubeMX 生成的代码,这里提供一个基础配置) */
SystemClock_Config();
/* 初始化 LED 引脚 */
LED_Init();
/* 流水灯主循环 */
while (1)
{
/* LED0 亮,LED1 灭 */
HAL_GPIO_WritePin(LED_PORT, LED0_PIN, GPIO_PIN_RESET); // 低电平点亮
HAL_GPIO_WritePin(LED_PORT, LED1_PIN, GPIO_PIN_SET);
delay_ms(300);
/* LED0 灭,LED1 亮 */
HAL_GPIO_WritePin(LED_PORT, LED0_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(LED_PORT, LED1_PIN, GPIO_PIN_RESET);
delay_ms(300);
}
}
/**
* @brief 系统时钟配置(正点原子探索者板,8MHz 外部晶振,主频 168MHz)
* @note 如果你已经在 CubeMX 中生成过 SystemClock_Config,可以直接替换此函数。
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
Error_Handler();
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_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
Error_Handler();
}
/**
* @brief 错误处理函数
*/
void Error_Handler(void)
{
while (1)
{
// 可在此处添加故障指示(例如闪灯)
}
}
3. CLion配置烧录器、编译烧录
- 配置烧录器
这里根据自己CubeCLT的安装路径填写即可。

- 点击Build,构建


- 通过STLink将开发板和本地电脑连接,点击烧录(将程序烧录到芯片中),然后就可以观察效果了。
烧录之前可以执行下面命令,以确认驱动是否正常:
bash
ST-LINK_gdbserver --version


最终效果:红、绿两个LED灯交替闪烁。

