PCB 设计最佳实践:从原理图到生产

PCB 设计流程 完整流程 需求分析 → 2. 原理图设计 → 3. 元器件选型 → 4. PCB 布局 → 5. 布线 → 6. DRC 检查 → 7. 生产文件输出 原理图设计 基本原则 模块化设计:按功能分块(电源、MCU、传感器等) 清晰标注:网络标签、测试点、版本信息 去耦电容:每个电源引脚就近放置 0.1uF 电容 预留资源:预留 GPIO、测试点、调试接口 常见错误 ❌ 避免以下错误: 电源网络标号混乱 缺少去耦电容 未连接的网络未标注 缺少版本标识 ✅ 推荐做法: 使用层次化设计 添加设计说明文档 标注关键信号 预留调试接口 元器件布局 布局原则 优先级 区域 说明 1 连接器 固定位置,靠近板边 2 电源部分 靠近电源入口 3 MCU/核心芯片 板子中心区域 4 模拟电路 远离数字干扰 5 其他器件 按信号流布局 关键器件布局 MCU 布局: 放置在板子中心 晶振靠近 MCU 去耦电容紧邻电源引脚 复位电路靠近复位引脚 电源布局: ...

March 23, 2026 · 3 min · Tech Snippets

嵌入式 C 语言编程技巧与最佳实践

嵌入式 C 语言特点 与通用 C 的区别 特性 嵌入式 C 通用 C 资源 受限(KB 级内存) 充足(MB/GB 级) 直接硬件访问 寄存器操作 抽象 API 实时性 关键 不重要 可靠性 极高 可接受失败 数据类型 使用固定宽度类型 #include <stdint.h> // ✅ 推荐:明确位宽 uint8_t status; uint16_t adc_value; int32_t temperature; // ❌ 避免:位宽不确定 char flag; // 可能是 8 位或 32 位 int count; // 可能是 16 位或 32 位 long timeout; // 可能是 32 位或 64 位 位域操作 // 状态寄存器定义 typedef struct { uint8_t ready : 1; // bit 0 uint8_t error : 1; // bit 1 uint8_t mode : 2; // bit 2-3 uint8_t reserved : 4; // bit 4-7 } StatusReg_t; // 使用 StatusReg_t status; status.ready = 1; status.mode = 0x02; 内存管理 避免动态分配 // ❌ 避免:malloc/free void* buffer = malloc(size); free(buffer); // ✅ 推荐:静态分配 static uint8_t buffer[256]; // ✅ 推荐:内存池 #define POOL_SIZE 10 static uint8_t memory_pool[POOL_SIZE][BLOCK_SIZE]; static uint8_t pool_bitmap = 0; const 和 volatile // const:只读数据(存储在 Flash) const uint16_t lookup_table[256] = {0}; // volatile:可能被外部修改 volatile uint8_t gpio_input; volatile uint32_t* const REGISTER_ADDR = (uint32_t*)0x40020000; // 组合使用 const volatile uint32_t* const HW_REGISTER = (uint32_t*)0x40020000; 中断编程 中断服务函数 // 中断服务函数 void EXTI0_IRQHandler(void) __attribute__((interrupt)); void EXTI0_IRQHandler(void) { // 1. 清除中断标志 EXTI->PR = EXTI_PR_PR0; // 2. 快速处理(置标志) g_button_pressed = 1; // 3. 如果需要,通知任务 xSemaphoreGiveFromISR(xBinarySemaphore, NULL); } 临界区保护 // 方法 1:关中断 uint32_t primask = __get_PRIMASK(); __disable_irq(); // 临界区代码 __set_PRIMASK(primask); // 方法 2:使用库 __disable_irq(); // 代码 __enable_irq(); // 方法 3:FreeRTOS taskENTER_CRITICAL(); // 代码 taskEXIT_CRITICAL(); 位操作技巧 常用宏 // 置位 #define SET_BIT(REG, BIT) ((REG) |= (1 << (BIT))) // 清零 #define CLEAR_BIT(REG, BIT) ((REG) &= ~(1 << (BIT))) // 翻转 #define TOGGLE_BIT(REG, BIT) ((REG) ^= (1 << (BIT))) // 读位 #define READ_BIT(REG, BIT) (((REG) >> (BIT)) & 1) // 设置位域 #define SET_BITS(REG, POS, LEN, VAL) \ ((REG) = (((REG) & ~(((1 << (LEN)) - 1) << (POS))) | \ (((VAL) & ((1 << (LEN)) - 1)) << (POS)))) 使用示例 // 配置 GPIO #define GPIO_MODE_OUTPUT 1 #define GPIO_PIN_5 5 // 设置 PA5 为输出 SET_BITS(GPIOA->MODER, 10, 2, GPIO_MODE_OUTPUT); // 切换 LED TOGGLE_BIT(GPIOA->ODR, GPIO_PIN_5); // 检查按键 if (READ_BIT(GPIOB->IDR, 0) == 0) { // 按键按下 } 代码优化 空间优化 // 使用更小的数据类型 uint8_t counter; // 而不是 int // 共用体节省内存 typedef union { uint32_t raw; struct { uint8_t b0, b1, b2, b3; } bytes; } DataUnion_t; // 使用位域 struct { uint8_t flag1 : 1; uint8_t flag2 : 1; uint8_t mode : 3; } flags; // 只占 1 字节 时间优化 // 使用查表代替计算 const uint16_t sin_table[256] = {...}; uint16_t sin_value = sin_table[i]; // 使用移位代替乘除 x = y * 8; // → x = y << 3; x = y / 4; // → x = y >> 2; // 循环展开 for (i = 0; i < 4; i++) { // → array[i] = 0; } // 展开为: array[0] = 0; array[1] = 0; array[2] = 0; array[3] = 0; 状态机 实现模式识别 typedef enum { STATE_IDLE, STATE_START, STATE_PROCESS, STATE_END } State_t; State_t current_state = STATE_IDLE; void state_machine(void) { switch (current_state) { case STATE_IDLE: if (start_condition) { current_state = STATE_START; } break; case STATE_START: init_resources(); current_state = STATE_PROCESS; break; case STATE_PROCESS: if (process_complete) { current_state = STATE_END; } break; case STATE_END: cleanup(); current_state = STATE_IDLE; break; } } 错误处理 返回值检查 typedef enum { ERR_OK = 0, ERR_INVALID_PARAM = -1, ERR_TIMEOUT = -2, ERR_NO_MEMORY = -3 } Error_t; Error_t sensor_read(float* value) { if (value == NULL) { return ERR_INVALID_PARAM; } // 读取传感器 if (timeout) { return ERR_TIMEOUT; } *value = read_value; return ERR_OK; } // 使用 float temp; Error_t err = sensor_read(&temp); if (err != ERR_OK) { // 错误处理 } 调试技巧 断言 #include <assert.h> void process_data(uint8_t* data, uint16_t size) { assert(data != NULL); assert(size > 0); assert(size <= MAX_SIZE); // 处理代码 } 日志宏 #define LOG_LEVEL_ERROR 0 #define LOG_LEVEL_INFO 1 #define LOG_LEVEL_DEBUG 2 #define LOG_LEVEL LOG_LEVEL_DEBUG #if LOG_LEVEL >= LOG_LEVEL_ERROR #define LOG_ERROR(fmt, ...) \ printf("[E] " fmt "\n", ##__VA_ARGS__) #endif #if LOG_LEVEL >= LOG_LEVEL_INFO #define LOG_INFO(fmt, ...) \ printf("[I] " fmt "\n", ##__VA_ARGS__) #endif #if LOG_LEVEL >= LOG_LEVEL_DEBUG #define LOG_DEBUG(fmt, ...) \ printf("[D] %s:%d " fmt "\n", \ __FILE__, __LINE__, ##__VA_ARGS__) #endif 编码规范 命名规范 // 类型:大驼峰 + _t typedef struct { ... } SensorData_t; // 函数:小写 + 下划线 void sensor_init(void); float sensor_read_temperature(void); // 变量:小写 uint8_t counter; float temperature; // 常量:大写 #define MAX_RETRY 10 #define TIMEOUT_MS 1000 // 宏函数:大写 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 注释规范 /** * @brief 读取温度传感器 * @param sensor_id: 传感器 ID * @param value: 存储读取值的指针 * @retval 成功返回 ERR_OK,失败返回错误码 */ Error_t sensor_read_temperature(uint8_t sensor_id, float* value); 结语 嵌入式 C 语言编程需要兼顾效率、可靠性和可维护性。遵循最佳实践,你的代码会更优秀! ...

March 22, 2026 · 4 min · Tech Snippets

基于 STM32+FreeRTOS 的智能平衡小车完整设计

项目概述 本项目设计并实现了一款基于 STM32F4 和 FreeRTOS 的两轮自平衡小车,采用串级 PID 控制算法,能够在 200ms 内完成自平衡启动,最大行进速度可达 1.5m/s。 系统架构 系统说明: 上层应用:蓝牙遥控、速度指令、状态显示 FreeRTOS 任务层:4 个任务(控制/传感器/通信/显示) 硬件抽象层:GPIO、TIM、ADC、I2C、UART 硬件层:STM32F407 + MPU6050 + 电机驱动 + 编码器 核心技术指标 指标 参数 控制周期 1ms (1kHz) 平衡角度范围 ±15° 最大速度 1.5m/s 启动时间 <200ms 续航时间 60 分钟 负载能力 500g 硬件设计 核心器件选型 MCU: STM32F407VGT6 主频:168MHz Flash: 1MB, SRAM: 192KB 定时器:12 个(含 4 个高级定时器) 编码器接口:硬件正交解码 IMU: MPU6050 6 轴:加速度计 + 陀螺仪 I2C 接口:400kHz 量程:±2g / ±2000°/s 电机驱动: TB6612FNG ...

March 20, 2026 · 3 min · Tech Snippets

开源 6 自由度机械臂:从设计到控制全解析

项目介绍 本项目是一款开源的 6 自由度桌面机械臂,有效负载 500g,重复定位精度±0.5mm,支持正逆运动学解算和笛卡尔空间轨迹规划。 技术参数 参数 规格 自由度 6 (J1-J6) 工作半径 400mm 有效负载 500g 重复精度 ±0.5mm 最大速度 200mm/s 控制周期 2ms 机械设计 结构方案 采用串联式 6 轴结构: J1: 基座旋转 (±180°) J2: 大臂俯仰 (-90°~+90°) J3: 小臂俯仰 (-90°~+120°) J4: 手腕旋转 (±180°) J5: 手腕俯仰 (-90°~+90°) J6: 末端旋转 (±180°) 3D 打印件 材料:PLA+ / PETG 壁厚:3mm (关键部位 4mm) 填充率:40% 层厚:0.2mm 传动设计 关节 传动方式 减速比 J1 同步带 3:1 J2 同步带 4:1 J3 同步带 4:1 J4 齿轮 5:1 J5 齿轮 5:1 J6 直连 1:1 硬件系统 控制板 主控: STM32F429 ...

March 18, 2026 · 4 min · Tech Snippets

自研 BMS 电池管理系统:硬件设计与 SOC 算法

项目概述 本项目设计并实现了一款 8 串锂电池管理系统 (BMS),支持 30A 持续放电、主动均衡、SOC/SOH 估算和 CAN 通信,适用于电动自行车、储能电源等应用。 技术指标 参数 规格 串数 8S (29.6V 标称) 持续电流 30A 峰值电流 60A (10s) 均衡电流 100mA 电压精度 ±2mV 电流精度 ±1% SOC 精度 ±3% 硬件设计 系统架构 信号流向: 电池组 → AFE:8 串电池电压采集 AFE → MCU:I2C 数字接口 传感器 → MCU:ADC 模拟输入 MCU → CAN/保护/电源:控制输出 关键器件选型 AFE 芯片: ISL94208 8 串电池监测 电压精度:±2mV 内置均衡开关 I2C 接口 电流检测: INA240 双向电流检测 共模电压:80V 增益:20V/V 带宽:400kHz MCU: STM32G071 主频:64MHz ADC: 12 位,2.5MSPS CAN: 1 路 Flash: 128KB MOSFET: AON7534 ...

March 15, 2026 · 6 min · Tech Snippets