Skip to content

第2章 CubeMX编程指南

第2章 STM32CubeMX 编程指南

2.1 本章知识导图

uml diagram


2.2 CubeMX 简介与安装

2.2.1 工具定位

STM32CubeMX 是 ST 官方提供的图形化初始化代码生成工具。其核心作用是:

用鼠标点选完成芯片所有外设的初始化配置,然后一键生成可直接编译的 C 工程框架,开发者只需在框架中填写业务逻辑。

CubeMX 解决的核心痛点:

痛点 传统手写方式 CubeMX 方式
时钟树配置 手动计算 PLL,易出错 填目标频率,自动计算
引脚复用冲突 翻数据手册逐一核查 图形界面实时检测并高亮冲突
外设初始化代码 手写数十行结构体赋值 图形配置后全部自动生成
FreeRTOS 移植 手动复制源码、修改配置 勾选即可,自动配置调度器

2.2.2 安装方式

CubeMX 提供两种使用方式,功能完全相同:

  方式一:STM32CubeIDE(推荐)
  ┌──────────────────────────────────┐
  │         STM32CubeIDE             │
  │  ┌────────────┐  ┌─────────────┐ │
  │  │  CubeMX    │  │  编译器      │ │
  │  │  (内置)   │  │  调试器      │ │
  │  └────────────┘  └─────────────┘ │
  │  一个软件包含全部开发功能           │
  └──────────────────────────────────┘
  下载:https://www.st.com/stm32cubeide

  方式二:STM32CubeMX 独立版
  ┌──────────────────┐      ┌────────────┐
  │   CubeMX 独立版  │ 生成  │  Keil MDK  │
  │  (仅图形配置)   ├─────► │  或其他IDE │
  └──────────────────┘      └────────────┘
  下载:https://www.st.com/stm32cubemx

本课程推荐使用 STM32CubeIDE,因为它将 CubeMX 配置、代码编辑、编译、烧录、调试集成在同一窗口,无需在多个软件间切换。

2.2.3 主界面布局

STM32CubeMX(或 CubeIDE 的 .ioc 编辑界面)分为五个主要区域:

  ┌─────────────────────────────────────────────────────────────────┐
  │  菜单栏:File / Window / Help                                    │
  ├────────────────────────────┬────────────────────────────────────┤
  │                            │  ② 外设配置面板                     │
  │                            │  ┌──────────────────────────────┐  │
  │   ① 芯片引脚视图            │  │  选中外设后,在此设置参数       │  │
  │      (Pin View)            │  │  例:GPIO mode / Speed        │  │
  │                            │  └──────────────────────────────┘  │
  │  引脚颜色含义:              │                                    │
  │  🟢 绿色 = 已配置            ├────────────────────────────────────┤
  │  🔴 红色 = 冲突              │  ③ 标签页切换                      │
  │  ⬜ 灰色 = 未使用            │  [Pinout & Config] [Clock Config]  │
  │                            │  [Project Manager] [Tools]         │
  ├────────────────────────────┴────────────────────────────────────┤
  │  ④ 时钟树(Clock Configuration 标签页)                          │
  │     HSE ──► PLL ──► SYSCLK ──► AHB / APB1 / APB2              │
  ├─────────────────────────────────────────────────────────────────┤
  │  ⑤ 工程管理器(Project Manager 标签页)                          │
  │     工程名称 / 路径 / IDE选择 / HAL库版本                         │
  └─────────────────────────────────────────────────────────────────┘

2.3 创建工程的完整流程

Blue Pill(STM32F103C8T6)LED 闪烁 为例,演示从零创建一个 CubeMX 工程的六个步骤。

2.3.1 步骤① 选择目标芯片

打开 STM32CubeIDE → File → New → STM32 Project → 在芯片选型界面:

  芯片选型界面操作:

  搜索框输入:STM32F103C8
         ↓
  在结果列表中选择:STM32F103C8Tx
         ↓
  右侧显示芯片信息:
  ┌─────────────────────────────────────┐
  │  Core:      ARM Cortex-M3           │
  │  Freq:      72 MHz                  │
  │  Flash:     64 KB                   │
  │  RAM:       20 KB                   │
  │  Package:   LQFP48                  │
  └─────────────────────────────────────┘
         ↓
  点击 Next → 填写工程名(如 LED_Blink)→ Finish

2.3.2 步骤② 系统配置(SYS / RCC)

Pinout & Configuration 标签页左侧的 System Core 类别中:

配置 SYS(调试接口):

  SYS → Debug → Serial Wire (SWD)
  (启用 SWD 调试接口,否则无法用 ST-Link 烧录和调试)

配置 RCC(时钟源):

  RCC → HSE (High Speed External) → Crystal/Ceramic Resonator
  (启用外部 8MHz 晶振,为后续 PLL 倍频至 72MHz 提供精确时钟源)

完成后,芯片图上 PC14/PC15(晶振引脚)和 PA13/PA14(SWD 引脚)会自动变为绿色,无需手动分配。

2.3.3 步骤③ 引脚功能分配

在芯片引脚图上,鼠标左键点击 PC13 引脚 → 从弹出菜单中选择 GPIO_Output

  PC13 引脚配置过程:

  点击 PC13 → 选择 GPIO_Output
       ↓
  左侧面板 → GPIO → PC13 出现在列表中
       ↓
  点击 PC13 行 → 配置详情:
  ┌──────────────────────────────────────┐
  │  GPIO output level:  High            │  ← 初始电平高(LED 默认灭)
  │  GPIO mode:          Output Push Pull│  ← 推挽输出
  │  GPIO Pull-up/down:  No pull-up...   │
  │  Maximum output speed: Low           │  ← 低速,驱动 LED 足够
  │  User Label:         LED             │  ← 自定义标签,生成宏定义
  └──────────────────────────────────────┘

2.3.4 步骤④ 时钟树配置

切换到 Clock Configuration 标签页:

  时钟树配置(Blue Pill 72MHz 标准配置):

  HSE(8MHz) → [PLLXTPRE: /1] → [PLLMUL: ×9] → PLL = 72MHz
                                                     │
                                        [SW: PLL] ───► SYSCLK = 72MHz
                                                     │
                              ┌──────────────────────┤
                              │                      │
                          AHB Presc              APB1 Presc
                             /1                      /2
                          HCLK=72MHz            PCLK1=36MHz
                                                     │
                                              (I2C1/USART2/SPI2)
  操作方法:
  → 在 "HCLK(MHz)" 输入框中直接填入 72,按回车
  → CubeMX 自动完成所有分频/倍频参数的计算与填充

2.3.5 步骤⑤ 外设参数配置

对于本示例(LED 闪烁),GPIO 已在步骤③配置完毕。若有其他外设(如 USART),在 Pinout & Configuration 左侧列表中展开对应类别进行配置(详见第4节)。

2.3.6 步骤⑥ 工程设置与代码生成

切换到 Project Manager 标签页:

  Project Manager 关键设置:

  ┌─────────────────────────────────────────────────────┐
  │  Project Name:   LED_Blink                          │
  │  Project Location: C:\Users\...\STM32Projects\      │
  │  Toolchain/IDE:  STM32CubeIDE    ← 选择目标 IDE     │
  ├─────────────────────────────────────────────────────┤
  │  Code Generator 标签页(重要设置):                   │
  │  ☑ Generate peripheral initialization as a pair    │
  │    of '.c/.h' files per peripheral                 │
  │    (每个外设生成独立的 .c/.h,结构更清晰)             │
  │  ☑ Keep User Code when re-generating               │
  │    (重新生成时保留 USER CODE 区块内的代码)            │
  └─────────────────────────────────────────────────────┘
       ↓
  点击右上角 "Generate Code" 按钮
       ↓
  弹出提示 "Open Project?" → 点击 Yes,自动在 CubeIDE 中打开工程

2.4 生成代码的结构与编写规范

2.4.1 工程目录结构

CubeMX 生成的工程具有固定目录结构:

  LED_Blink/
  ├── Core/
  │   ├── Inc/
  │   │   ├── main.h              ← 引脚宏定义(LED_Pin / LED_GPIO_Port)
  │   │   ├── stm32f1xx_hal_conf.h← HAL 库功能开关配置
  │   │   └── stm32f1xx_it.h      ← 中断服务函数声明
  │   └── Src/
  │       ├── main.c              ← 主程序(用户主要编写此文件)
  │       ├── stm32f1xx_hal_msp.c ← HAL MSP(底层引脚/时钟初始化回调)
  │       ├── stm32f1xx_it.c      ← 中断服务函数(如 SysTick_Handler)
  │       └── system_stm32f1xx.c  ← SystemInit(),通常无需修改
  ├── Drivers/
  │   ├── STM32F1xx_HAL_Driver/   ← HAL 库源码(ST 官方,不要修改)
  │   │   ├── Inc/
  │   │   └── Src/
  │   └── CMSIS/                  ← ARM 内核接口(不要修改)
  ├── LED_Blink.ioc               ← CubeMX 配置文件(双击重新打开配置)
  └── LED_Blink.elf               ← 编译产物(二进制固件)

规则:只在 Core/Src/Core/Inc/ 中编写用户代码,Drivers/ 目录内容不要手动修改。

2.4.2 main.h 中的引脚宏定义

CubeMX 根据 User Labelmain.h 中自动生成宏定义:

/* main.h(CubeMX 自动生成,勿手动修改此区域) */
#define LED_Pin          GPIO_PIN_13   /* 来自 User Label: LED */
#define LED_GPIO_Port    GPIOC

main.c 中使用宏定义而非硬编码引脚,好处:

/* 推荐写法(使用宏定义)*/
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);

/* 不推荐写法(硬编码,电路改动后需逐处修改)*/
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);

2.4.3 USER CODE BEGIN / END 编写规范

CubeMX 生成的 main.c 中遍布成对的注释标记,用户代码必须写在标记之间

int main(void)
{
    /* USER CODE BEGIN 1 */
    /* 在 HAL_Init 之前的变量声明或早期初始化 */
    uint32_t tick_count = 0;
    /* USER CODE END 1 */

    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();

    /* USER CODE BEGIN 2 */
    /* GPIO 初始化完成后,主循环之前的一次性操作 */
    HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET); /* LED 灭 */
    /* USER CODE END 2 */

    while (1)
    {
        /* USER CODE BEGIN WHILE */
        HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
        HAL_Delay(500);
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
        /* USER CODE END 3 */
    }
}

常见 USER CODE 区域说明:

区域标记 位置 适合写什么
USER CODE BEGIN Includes 头文件区 添加自定义头文件
USER CODE BEGIN PD 宏定义区 添加 #define 常量
USER CODE BEGIN PV 全局变量区 声明全局变量
USER CODE BEGIN 0 函数实现前 定义辅助函数
USER CODE BEGIN 1 main 开头 局部变量声明
USER CODE BEGIN 2 初始化后 一次性启动逻辑
USER CODE BEGIN WHILE while(1) 内 主循环业务逻辑

⚠️ 警告:写在 USER CODE BEGIN/END 之外的代码,在下次执行 "Generate Code" 时会被 CubeMX 覆盖删除

2.4.4 中断回调函数的编写规范

HAL 库采用弱符号回调(weak callback)机制:HAL 驱动内部定义了 __weak 修饰的空回调函数,用户在 USER CODE BEGIN 0 区域重写同名函数即可覆盖:

/* 在 main.c 的 USER CODE BEGIN 0 区域重写 */

/* GPIO 外部中断回调(按键按下触发)*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if (GPIO_Pin == BTN_Pin)
    {
        HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    }
}

/* 定时器溢出回调 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == TIM2)
    {
        HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    }
}

2.5 常用外设配置实战

2.5.1 GPIO — 输出与输入

LED 输出(推挽输出):

CubeMX 配置:PC13 → GPIO_Output,Mode = Output Push Pull,Label = LED

/* 主循环中控制 LED */
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET); /* 低电平 → 亮 */
HAL_Delay(500);
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);   /* 高电平 → 灭 */
HAL_Delay(500);

/* 或使用翻转,更简洁 */
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
HAL_Delay(500);

按键输入(上拉输入):

CubeMX 配置:PA0 → GPIO_Input,Pull = Pull-up,Label = BTN

/* 轮询方式读取按键 */
if (HAL_GPIO_ReadPin(BTN_GPIO_Port, BTN_Pin) == GPIO_PIN_RESET)
{
    /* 按键按下(低电平有效,因为接了上拉) */
    HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
}
else
{
    HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
}

2.5.2 USART — 串口通信

CubeMX 配置步骤:

  Connectivity → USART1
  ├── Mode: Asynchronous(异步串口)
  └── Parameter Settings:
      ├── Baud Rate:   115200 Bits/s
      ├── Word Length: 8 Bits
      ├── Parity:      None
      └── Stop Bits:   1
  → 自动分配:PA9 = USART1_TX,PA10 = USART1_RX

生成代码中自动出现 MX_USART1_UART_Init(),用户调用 HAL API:

/* USER CODE BEGIN Includes */
#include <string.h>  /* for strlen */
/* USER CODE END Includes */

/* USER CODE BEGIN 2 */
char msg[] = "Hello from STM32!\r\n";
HAL_UART_Transmit(&huart1, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
/* USER CODE END 2 */

/* 接收单字节(阻塞模式)*/
uint8_t rx_byte;
HAL_UART_Receive(&huart1, &rx_byte, 1, HAL_MAX_DELAY);

/* 接收完成后用中断回调(非阻塞,推荐)*/
HAL_UART_Receive_IT(&huart1, &rx_byte, 1); /* 启动中断接收 */

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) /* 接收完成回调 */
{
    if (huart->Instance == USART1)
    {
        /* 处理 rx_byte,然后重新启动接收 */
        HAL_UART_Receive_IT(&huart1, &rx_byte, 1);
    }
}

2.5.3 TIM — 定时器与 PWM

基本定时(产生周期性中断):

  Timers → TIM2
  ├── Clock Source: Internal Clock
  ├── Prescaler (PSC):    7199    → 72MHz ÷ (7199+1) = 10 kHz
  └── Counter Period (ARR): 9999  → 10kHz ÷ (9999+1) = 1 Hz(每秒溢出一次)
  → NVIC Settings: TIM2 global interrupt ☑ Enable
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim2);  /* 启动定时器中断 */
/* USER CODE END 2 */

/* 定时器溢出回调(每 1 秒触发一次)*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == TIM2)
    {
        HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    }
}

PWM 输出(控制舵机 / LED 亮度):

  Timers → TIM3 → Channel1: PWM Generation CH1
  ├── Prescaler:  71    → 72MHz ÷ 72 = 1 MHz
  └── Counter Period: 19999  → 周期 = 20ms(50Hz,标准舵机信号)
  → PA6 自动分配为 TIM3_CH1
/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); /* 启动 PWM 输出 */
/* USER CODE END 2 */

/* 修改占空比(舵机位置控制)*/
/* 脉宽 1ms(0°) ~ 2ms(180°),对应 ARR=19999 时,CCR = 1000 ~ 2000 */
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 1500); /* 中间位置 90° */

2.5.4 I2C — 总线通信

  Connectivity → I2C1
  ├── Mode: I2C
  └── Speed Mode: Standard Mode(100 kHz)
  → PB6 = I2C1_SCL,PB7 = I2C1_SDA(自动分配,需外接 4.7kΩ 上拉)
/* 向从设备地址 0x68(如 MPU6050)发送数据 */
uint8_t data[2] = {0x6B, 0x00};   /* 寄存器地址,数据 */
HAL_I2C_Master_Transmit(&hi2c1, 0x68 << 1, data, 2, HAL_MAX_DELAY);

/* 从从设备读取 6 字节 */
uint8_t buf[6];
HAL_I2C_Master_Receive(&hi2c1, 0x68 << 1, buf, 6, HAL_MAX_DELAY);

/* 读写指定寄存器(Mem 方式,更常用)*/
HAL_I2C_Mem_Read(&hi2c1, 0x68 << 1,   /* 设备地址 */
                  0x3B,                 /* 寄存器地址(加速度 X 高字节)*/
                  I2C_MEMADD_SIZE_8BIT,
                  buf, 6, HAL_MAX_DELAY);

2.5.5 ADC — 模拟信号采集

  Analog → ADC1
  ├── IN0: 勾选(使能通道 0 → PA0 引脚)
  └── Parameter Settings:
      ├── Continuous Conversion Mode: Enabled
      └── Scan Conversion Mode:       Disabled(单通道)
/* USER CODE BEGIN 2 */
HAL_ADC_Start(&hadc1);                /* 启动 ADC 转换 */
/* USER CODE END 2 */

/* 读取 ADC 值(阻塞轮询)*/
HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
uint32_t adc_val = HAL_ADC_GetValue(&hadc1);   /* 12位,0 ~ 4095 */

/* 换算为电压(参考电压 3.3V)*/
float voltage = adc_val * 3.3f / 4095.0f;

2.5.6 FreeRTOS 多任务配置

2.5.6.1 启用 FreeRTOS

在 CubeMX 中:Middleware and Software Packs → FreeRTOS → CMSIS_V2

  FreeRTOS 配置界面:
  ├── Config Parameters(内核参数)
  │    ├── configTICK_RATE_HZ:    1000   (系统节拍 1ms)
  │    └── configTOTAL_HEAP_SIZE: 3072   (总堆大小,按需调整)
  └── Tasks and Queues(任务管理)
       ├── 默认任务 defaultTask 已自动创建
       └── 点击 Add 可添加更多任务

⚠️ 启用 FreeRTOS 后,CubeMX 会自动将 HAL 时基从 SysTick 改为 TIM(如 TIM1),因为 FreeRTOS 自身需要独占 SysTick。

2.5.6.2 创建任务

在 CubeMX 的 FreeRTOS 配置页 → Tasks and QueuesAdd Task

  任务配置参数:
  ┌─────────────────────────────────────────┐
  │  Task Name:    ledTask                  │
  │  Priority:     osPriorityNormal         │
  │  Stack Size:   128  (words = 512 bytes) │
  │  Entry Function: StartLedTask           │
  │  Code Generation Option: As weak       │
  └─────────────────────────────────────────┘

生成代码后,在 freertos.cUSER CODE BEGIN 区填写任务逻辑:

/* freertos.c - USER CODE BEGIN Header_StartLedTask */
void StartLedTask(void *argument)
{
    /* USER CODE BEGIN StartLedTask */
    for (;;)
    {
        HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
        osDelay(500);   /* FreeRTOS 延时:让出 CPU,其他任务可以运行 */
    }
    /* USER CODE END StartLedTask */
}
2.5.6.3 任务间通信

信号量(二值信号量,用于任务同步):

在 CubeMX → FreeRTOS → Timers & SemaphoresAdd Binary Semaphore,命名为 btnSemaphore

/* 中断回调中释放信号量(通知任务有按键事件)*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if (GPIO_Pin == BTN_Pin)
    {
        osSemaphoreRelease(btnSemaphoreHandle);
    }
}

/* 按键处理任务:等待信号量 */
void StartBtnTask(void *argument)
{
    for (;;)
    {
        osSemaphoreAcquire(btnSemaphoreHandle, osWaitForever); /* 阻塞等待 */
        HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    }
}

消息队列(用于传递数据):

在 CubeMX → FreeRTOS → Timers & SemaphoresAdd Queue,命名 adcQueue,长度 4,Item Size uint32_t

/* ADC 采集任务:发送数据到队列 */
void StartAdcTask(void *argument)
{
    for (;;)
    {
        HAL_ADC_Start(&hadc1);
        HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
        uint32_t val = HAL_ADC_GetValue(&hadc1);
        osMessageQueuePut(adcQueueHandle, &val, 0, 0);
        osDelay(10);
    }
}

/* 数据处理任务:从队列接收数据 */
void StartProcessTask(void *argument)
{
    uint32_t val;
    for (;;)
    {
        osMessageQueueGet(adcQueueHandle, &val, NULL, osWaitForever);
        /* 处理 val ... */
    }
}
2.5.6.4 osDelay 与 HAL_Delay 的区别
函数 底层实现 使用场景
HAL_Delay(ms) SysTick 忙等待(或 TIM 基准轮询) 不可在 FreeRTOS 任务中使用,会阻塞整个调度器
osDelay(ms) FreeRTOS vTaskDelay(),任务挂起 FreeRTOS 任务中必须使用此函数,让出 CPU

2.5.7 重新配置工程

2.5.7.1 修改配置的工作流

当硬件设计发生变化(如增加传感器、修改引脚)或需要启用新外设时:

  迭代开发流程:

  双击 .ioc 文件重新打开 CubeMX
           ↓
  修改引脚 / 外设 / 时钟配置
           ↓
  点击 "Generate Code"
           ↓
  CubeMX 重新生成初始化代码
  (USER CODE BEGIN/END 内的用户代码自动保留)
           ↓
  在新生成的框架中继续编写业务逻辑
2.5.7.2 用户代码保护机制验证

以下场景演示 USER CODE 保护是否生效:

  场景:在 main.c 的 while(1) 中写了业务代码,
        随后在 CubeMX 中新增了 USART1 外设,重新生成代码。

  重新生成后的 main.c:
  ┌────────────────────────────────────────────────────┐
  │  MX_GPIO_Init();                                   │
  │  MX_USART1_UART_Init();   ← CubeMX 自动添加        │
  │                                                    │
  │  /* USER CODE BEGIN 2 */                           │
  │  // 你之前写的启动代码    ← ✅ 保留                  │
  │  /* USER CODE END 2 */                             │
  │                                                    │
  │  while (1) {                                       │
  │      /* USER CODE BEGIN WHILE */                   │
  │      HAL_GPIO_TogglePin(...);  ← ✅ 保留            │
  │      HAL_Delay(500);           ← ✅ 保留            │
  │      /* USER CODE END WHILE */                     │
  │  }                                                 │
  └────────────────────────────────────────────────────┘
2.5.7.3 常见问题与最佳实践
问题 原因 解决方法
代码被覆盖 用户代码写在 USER CODE 标记之外 严格遵守 BEGIN/END 规范
引脚冲突(红色高亮) 两个外设分配了同一引脚 在 CubeMX 中重新分配其中一个引脚
烧录后程序不运行 SYS 未配置 SWD,或 BOOT0 未正确设置 确认 SYS→Debug→Serial Wire 已启用
FreeRTOS 任务卡死 在任务中使用了 HAL_Delay 全部替换为 osDelay
堆栈溢出崩溃 任务栈空间不足 增大 Stack Size,或使用 uxTaskGetStackHighWaterMark 监控
HAL_Delay 不准 FreeRTOS 占用了 SysTick CubeMX 已自动切换时基到 TIM,无需手动处理

2.5.7.4 使用 Coolify 配置容器运行 PicSimLab 仿真

PicSimLab 是一种用于嵌入式/传感器仿真的轻量化仿真环境。可通过 Coolify 将 PicSimLab 以容器形式部署,便于在云或本地服务器上提供仿真服务给学生和实验环境。

示例 docker-compose.yml(作为 Coolify 的仓库部署或本地测试):

version: "3.8"
services:
  picsimlab:
    image: picsimlab/picsimlab:latest    # 若无官方镜像,改为自己构建的镜像名
    restart: unless-stopped
    ports:
      - "8080:8080"                     # Web UI 或 API 端口
    volumes:
      - ./picsimlab-work:/home/picsimlab/work  # 持久化仿真工程与数据
    environment:
      - TZ=Asia/Shanghai

在 Coolify 中部署步骤(简要):

  1. 打开 Coolify 控制台,点击 Create → Application。
  2. 选择 "Container"(容器)或使用 "Repository" 并指向包含 docker-compose.yml 的仓库(推荐)。
  3. 如果选 Container:填写 Image(例如 picsimlab/picsimlab:latest),设置端口映射 8080,配置环境变量与卷挂载(将宿主路径映射到容器的 /home/picsimlab/work)。
  4. 如果选 Repository:指定分支与 Docker Compose 文件路径,Coolify 会根据 docker-compose.yml 构建并部署服务。
  5. 部署完成后,通过 Coolify 提供的域名或映射端口访问 PicSimLab Web 界面(例如 http://:8080 或应用子域)。

注意: - 若没有官方镜像,请在仓库中包含 Dockerfile 或 docker-compose.yml,由 Coolify 从源码构建镜像。 - 保证宿主机有必要的端口、磁盘和 CPU 权限来运行仿真。


2.5.8 本章在线测试(10 题)

Quiz results are saved to your browser's local storage and will persist between sessions.

#

1) 在 CubeMX 中,若要使用 ST-Link 下载与调试,SYS -> Debug 应设置为哪一项?

#

2) Blue Pill 标准 72MHz 配置中,外部晶振通常设置为:

#

3) 在引脚视图中,红色高亮通常表示:

#

4) 下列哪个步骤用于让 CubeMX 自动计算主频相关参数?

#

5) 关于 User Label(例如给 PC13 标记为 LED),正确的是:

#

6) 在 FreeRTOS 任务函数中应优先使用哪个延时函数?

#

7) 重新生成代码时,哪类代码最容易被覆盖?

#

8) 下列关于工程目录的说法哪些正确?

#

9) 若新增 USART1 后重新 Generate Code,最合理的预期是:

#

10) 当 CubeMX 中出现引脚冲突时,优先处理方式是:

Quiz Progress

0 / 0 questions answered (0%)

0 correct