前言
本系列学习笔记是本人跟随米醋电子工作室学习嵌入式的学习笔记,自用为主,不是教学或经验分享,若有误,大佬轻喷,同时欢迎交流学习,侵权即删。
一、嵌入式开发中的命名规范
嵌入式开发需要保证代码的可读性、可维护性、团队统一性,以保证调试与优化便捷。
1.本人后续统一使用命名方法
蛇形命名法
全部小写,不同单词用'_'隔开,英语不会现查,避免使用汉语拼音
cpp
uint16_t sensor_data_count; //全部小写,不同单词用'_'隔开
2.嵌入式开发命名注意事项
避免与保留字冲突;注意变量长度限制;语义必须清晰(再次强调:英语不会现查,避免使用汉语拼音)
二、 8051 vs. STM32
1.核心架构对比
| 特性 | 8051架构 (经典8位) | STM32架构 (ARM Cortex-M 32位) |
|---|---|---|
| 内核位数 | 8位 | 32位 |
| 指令集 | CISC (复杂指令集) | RISC (精简指令集) |
| 性能 | 较低 (约 0.1-1 DMIPS) | 高 (1.25 ~ 1000+ DMIPS,视系列而定) |
| 时钟频率 | 通常 12-24 MHz (现代衍生品可达100MHz+) | 通常 16 MHz ~ 550 MHz (视系列而定) |
| 内存架构 | 哈佛架构 (程序与数据地址空间分离) | 改进型哈佛架构 (统一编址,但总线分离) |
| 地址空间 | 有限 (通常 < 64KB RAM,< 64KB Flash) | 非常大 (高达 4GB 的线性地址空间) |
| 典型外设 | UART, GPIO, 定时器,I²C (基础) | USB, CAN, Ethernet, ADC/DAC, DMA, 高级定时器等 |
| 功耗管理 | 简单 (空闲/停机模式) | 复杂精细 (多种低功耗模式,动态调频) |
| 开发环境 | Keil C51, SDCC | Keil MDK, IAR, STM32CubeIDE (基于GCC/LLVM) |
| 核心优势 | 简单、极低成本、低功耗、历史悠久生态 | 高性能、丰富外设、强大开发生态、性价比高 |
| 典型应用 | 简单控制、家电、遥控器、低成本传感器 | 物联网设备、工业控制、消费电子、汽车电子 |
2.数据类型支持对比
| 固定宽度数据类型 | 8051(Keil C51 编译器) | STM32(Keil MDK/ARM GCC 编译器) | 备注 |
|---|---|---|---|
uint8_t |
1 字节(8 位),范围:0 ~ 255,原生支持 | 1 字节(8 位),范围:0 ~ 255,原生支持 | 无符号 8 位整数,两者完全兼容 |
int8_t |
1 字节(8 位),范围:-128 ~ 127,原生支持 | 1 字节(8 位),范围:-128 ~ 127,原生支持 | 有符号 8 位整数,两者完全兼容 |
uint16_t |
2 字节(16 位),范围:0 ~ 65535,原生支持 | 2 字节(16 位),范围:0 ~ 65535,原生支持 | 无符号 16 位整数,两者完全兼容 |
int16_t |
2 字节(16 位),范围:-32768 ~ 32767,原生支持 | 2 字节(16 位),范围:-32768 ~ 32767,原生支持 | 有符号 16 位整数,两者完全兼容 |
uint32_t |
4 字节(32 位),软件模拟支持(效率极低) | 4 字节(32 位),原生支持,范围:0 ~ 4294967295 | STM32 原生支持,8051 无硬件加速,实用价值低 |
int32_t |
4 字节(32 位),软件模拟支持(效率极低) | 4 字节(32 位),原生支持,范围:-2147483648 ~ 2147483647 | 有符号 32 位整数,STM32 可高效运算 |
uint64_t |
8 字节(64 位),几乎不支持(编译器兼容差) | 8 字节(64 位),原生支持,范围:0 ~ 18446744073709551615 | STM32 支持 64 位无符号整数,8051 无实用价值 |
int64_t |
8 字节(64 位),几乎不支持(编译器兼容差) | 8 字节(64 位),原生支持,范围:±9.2e18 | 有符号 64 位整数,仅 STM32 可正常使用 |
float32_t(float) |
4 字节(32 位),软件模拟运算(速度极慢) | 4 字节(32 位),Cortex-M4/M7/M33 等支持硬件 FPU 加速 | STM32 硬件浮点运算效率远超 8051 |
float64_t(double) |
8 字节(64 位),极少支持(软件模拟无实用价值) | 8 字节(64 位),原生支持(部分内核硬件加速) | 高精度浮点仅 STM32 具备实际使用意义 |
| 指针类型(对应地址宽度) | uint16_t/uint24_t(依赖存储模式,寻址有限) |
uint32_t(部分内核支持uint64_t),寻址范围大 |
STM32 可直接寻址大内存,8051 需切换存储模式 |
三、嵌入式开发方式
嵌入式的三种开发方式:寄存器开发、标准库开发、HAL库开发
| 对比维度 | 寄存器开发 | 标准库开发 | HAL 库开发 |
|---|---|---|---|
| 核心原理 | 直接操作硬件寄存器的内存地址 / 位域 | 封装寄存器操作,提供外设专用函数接口 | 高度抽象封装,提供跨系列统一 API 接口 |
| 操作对象 | 寄存器地址(如GPIOA->ODR)、寄存器位 |
标准库函数(如GPIO_SetBits()) |
HAL 库 API 函数(如HAL_GPIO_WritePin()) |
| 开发难度 | 高(需熟记寄存器地址、位定义、时序要求) | 中(无需记寄存器,只需掌握外设函数用法) | 低(只需掌握统一 API,无需关注底层细节) |
| 开发效率 | 低(手动配置所有寄存器,易出错) | 较高(函数封装简化配置,开发速度快) | 高(API 更易用,支持 STM32CubeMX 自动生成代码) |
| 代码执行效率 | 最高(无冗余封装,直接操作硬件,占用资源最少) | 较高(轻量封装,几乎无性能损耗) | 中等(多层封装,存在少量性能开销) |
| 可移植性 | 极差(寄存器地址随芯片型号变化,无法跨系列复用) | 一般(仅支持特定 STM32 系列,无法跨系列兼容) | 好(跨 STM32 全系列兼容,可快速迁移项目) |
| 代码可读性 / 可维护性 | 差(寄存器操作晦涩,后期维护难度大) | 较好(函数命名规范,逻辑清晰) | 最好(API 统一规范,注释完善,团队协作友好) |
| 硬件适配范围 | 仅针对单一芯片型号 | 针对某一系列 STM32(如 F103 系列) | 支持 STM32 全系列(F1/F4/H7 等) |
| 官方支持状态 | 无官方维护(仅提供寄存器手册) | 已停止维护(ST 不再更新,仅保留历史版本) | 持续维护(ST 主推,不断更新优化) |
| 核心适用场景 | 极致追求性能 / 资源受限场景、底层驱动开发 | 传统 STM32 项目维护、对效率有要求的中小项目 | 量产项目、跨系列开发、快速原型搭建、团队协作项目 |