嵌入式开发之旅
标准接口(Application Programming Interface, API)是一组预先定义好的函数、协议或工具,它规定了不同软件组件之间如何交互和通信。简单来说,API 是开发者与某个系统(硬件、库、服务等)之间的“桥梁”——开发者无需关心系统内部如何实现,只需通过调用这些接口即可完成特定功能。用生活中的例子理解 API 🌰你需要做什么:插上电源,按下开关。你不需要做什么:了解水壶内
嵌入式开发之旅
前言
本文章参考了同为米醋电子工作室会员柒的部分优秀笔记,仅做个人学习用,如有侵权,请联系本人删除。
从8051到STM32的进阶之路
文章目录
一、STM32和8051的相同点
1、外设基本相同
以蓝桥杯单片机v10-v20原理图为例

STM32(基于西门子32)为例

我们通过以上两张图片对比发现51和32的大部分外设基本相同,其32就多了个TF卡和FLASH,在嵌入式 系统中,TF卡(TransFlash卡)和Flash存储是两种常见的存储设备,类似于51单片机中的EEPROM,断 电存储。我们可以通过这些外设进一步学习相应的协议(如iic,lsp) 主要区别总结:
| 特性 | TF卡(MicroSD卡) | Flash存储 |
|---|---|---|
| 可拆卸性 | 可拆卸,方便更换和扩展存储 | 通常不可拆卸,内置于设备中 |
| 储存容量 | 容量通常较小(几GB到几百GB不等) | 容量更大,可达TB级别 |
| 耐用性 | 相对较低,适合轻度使用 | 耐用性强,适合频繁写入的环境 |
| 应用场景 | 便捷的外部存储,移动设备使用 | 嵌入式系统、固态硬盘等内置存储 |
| 性能 | 读取/写入速度相对较慢 | 较高的读写速度,尤其在大容量存储中 |
当我们从51过渡到32是必须要了解这些外设和基本的框架移植,例如给你其他51类型单片机的原理图和 特定的底层驱动代码,要你实现指定的功能(AD_DA,Temperature,key ,led,seg等等),假如我们能够从蓝桥杯单片机中的框架逻辑中移植到其他51系列单片机中实现功能,可以说你在51单片机中入门了;
二、STM32和8051的区别
| 特性 | STM32 | 8051 |
|---|---|---|
| 架构 | ARM Cortex-M(32位) | 8051架构(8位) |
| 位宽 | 32位 | 8位 |
| 处理能力 | 力高,适合复杂应用 | 低,适合简单应用 |
| 内存 | 较大,Flash和RAM较大 | 较小,有限的存储空间 |
| 外设支持 | 丰富(USB, CAN, UART等) | 基本(串口、定时器等) |
| 功耗 | 高性能版本较高功耗,但有低功耗版 | 较低功耗 |
| 开发工具 | 现代化开发工具,支持C/C++开发 | 简单工具,用汇编语言 |
| 英语领域 | 高端嵌入式应用(工业、医疗、汽车等) | 低端嵌入式应用(家电控制等) |

我们通过以上图片的对比可以发现区别不仅仅体现在内部结构上,还体现在对数据类型的支持
以及,我们需要了解到在是stm32中,不在使用单片机中的unsigned char和unsigned int类型的定义,而是使用图中的数据类型定义方式
三、代码的命名规范性
我们常见的命名规则有
1、蛇形命名法(单词之间⽤下划线分隔,所有字⺟通常都为⼩写)
read_temperature , gather_time flash_flag
2、全⼤写命名法 一般来说全大写命名法适用于变量的宏定义
#define MAX_BUFFER_SIZE 1024 #define PI 3.14159
3、驼峰命名法 第⼀个单词⾸字⺟⼩写,后续单词⾸字⺟⼤写
myAPP recevieSSBUF
四、嵌入式的三种开发方式(重点)
1、寄存器级开发
直接操作硬件寄存器的编程方式,所有的硬件外设和控制都通过直接读写 寄存器来实现,提供最大灵活性和性能,但需要深入了解硬件细节。
| 优点 | 缺点 |
|---|---|
| 灵活性高,精确控制硬件 | 开发效率低,工作量大 |
| 代码体积小,运行效率高 | 可移植性差,代码复用难 |
| 深入理解硬件工作原理 | 学习曲线陡峭 |
// 使能GPIOA时钟
RCC->APB2ENR |= (1 << 2);
// 配置PA5为推挽输出
GPIOA->CRL &= ~(0xF << 20);
GPIOA->CRL |= (0x3 << 20);
// 主循环
while (1) {
GPIOA->BSRR = (1 << 5); // PA5置高,点亮LED
for (int i = 0; i < 100000; i++); // 延时
GPIOA->BRR = (1 << 5); // PA5置低,熄灭LED
for (int i = 0; i < 100000; i++); // 延时
}
2、标准库开发(通常称为标准外设库,如STM32的Standard Peripheral Library, SPL)
是一种基于直接操作硬件寄存器的软件开发方式,但它通过提供一组封装好的函数和结构体,简化了对寄存器的直接操作。标准库的目标是降低直接操作寄存器的复杂度,同时保留对硬件的精细控制能力。它与HAL库最大的区别在于抽象层次更低,更接近硬件底层,平衡了开发效率和硬件控制。
| 优点 | 缺点 |
|---|---|
| 开发效率较高 | 代码体积略大(相比于寄存器级开放) |
| 代码可读性好 | 性能次于寄存器级开发 |
| 同系列芯片间可移植性较好 | 需要学习API接口 |
什么是标准接口(API)?
标准接口(Application Programming Interface, API) 是一组预先定义好的函数、协议或工具,它规定了不同软件组件之间如何交互和通信。简单来说,API 是开发者与某个系统(硬件、库、服务等)之间的“桥梁”——开发者无需关心系统内部如何实现,只需通过调用这些接口即可完成特定功能。
用生活中的例子理解 API 🌰
想象你要用电水壶烧水:
- 你需要做什么:插上电源,按下开关。
- 你不需要做什么:了解水壶内部的电路设计、加热原理、温度控制逻辑。
示例1:配置GPIO(STM32F1标准库)
API 在嵌入式开发中的体现
在嵌入式系统中,API 通常是一组函数或方法,由库(如 HAL 库、标准库)或操作系统提供,用于简化硬件操作或复杂任务。例如:
-
示例1:控制 GPIO 的 API
-
函数名:
HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState) -
作用:设置某个 GPIO 引脚的电平(高/低)。
-
你无需关心:
- 如何配置寄存器?
- 不同芯片的 GPIO 寄存器地址是否不同?
- 是否需要先使能时钟?
- 如何配置寄存器?
-
-
示例2:延时 API
-
函数名:
HAL_Delay(uint32_t Delay) -
作用:让程序暂停指定毫秒数。
-
你无需关心:
- 如何配置定时器?
- 如何计算时钟频率?
- 如何配置定时器?
-
3、HAL库开发(HAL库是ST公司目前主力推的开发方式,全称就是Hardware Abstraction Layer(硬件抽象层))
它的出现比标准库要晚,但其实和标准库一样,都是为了节省程序开发的时期,而且HAL库尤其的 有效,如果说标准库把实现功能需要配置的寄存器集成了,那么HAL库的一些函数甚至可以做到某些特定功能的集成。也就是说,同样的功能,标准库可能要用几句话,HAL库只需用一句话就够 了。
| 优点 | 缺点 |
|---|---|
| 开发效率最高 | 代码体积大 |
| 可移植性强 | 性能开销较大 |
| 易于上手,适合初学者 | 底层问题难以追踪 |
GPIO点灯示例 (STM32 HAL库)
int main(void) {
HAL_Init(); // 初始化HAL库
SystemClock_Config(); // 配置系统时钟
__HAL_RCC_GPIOA_CLK_ENABLE(); // 使能GPIOA时钟
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
while (1) {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
HAL_Delay(500);
}
}
4、三种开发方式对比

5、标准库与HAL库比较
| 特性 | 标准库 | HAL库 |
|---|---|---|
| 抽象层次 | 低(直接操作寄存器) | 高(完全隐藏寄存器) |
| 代码体积 | 小(适合资源受限的芯片) | 大(功能复杂,代码量多) |
| 移植性 | 差(不同芯片系列需要修改代码) | 好(跨芯片系列兼容) |
| 开发效率 | 低(需要了解寄存器细节) | 高(专注于业务逻辑) |
| 适用场景 | 对性能/资源敏感的项目、学习底层硬件 | 快速开发、跨平台项目 |
相同点:
都是库(都是编写好的很多操作寄存器的函数函数放在一个文件 中)。然后把他们打包在两个文件夹中,一个叫src(存放.c文件),一个叫inc(存放.h文件),那这个就相当于我自己创建了一个属于自己的库了。创建了库的话我要用数码管就把smg.c和smg.h拿出来就能 调用里面的函数,很是方便。
不同点:
函数的名称、操作的逻辑、不同函数之间的调用、函数对寄存器的调用,HAL库更加的方便与快捷
打个比喻:
标准库就像是手动挡汽车,汽车上包含许多外设如离合,刹车,油门等等,我们只需要理解其汽车的工作原理,多练习就会很容易上手,但是当我们换一辆汽车,开起来可能会没有之前那么熟练(可移植性低);
了。创建了库的话我要用数码管就把smg.c和smg.h拿出来就能 调用里面的函数,很是方便。
不同点是:函数的名称、操作的逻辑、不同函数之间的调用、函数对寄存器的调用,HAL库更加的方便与快捷
打个比喻:
标准库就像是手动挡汽车,汽车上包含许多外设如离合,刹车,油门等等,我们只需要理解其汽车的工作原理,多练习就会很容易上手,但是当我们换一辆汽车,开起来可能会没有之前那么熟练(可移植性低);
对于HAL库可以理解为自动挡汽车,同样包含许多手动挡汽车的外设,你不需要关心离合和换挡,直接开就行(可移植性比较高)
为什么标准库逐渐被HAL库取代?
- 移植困难
标准库的API在不同芯片系列之间差异较大。例如,STM32F1和STM32F4的标准库函数名可能相同,但底层寄存器完全不同,移植时需要大量修改代码。 - 工具链支持不足
标准库缺乏现代化工具支持(如STM32CubeMX),开发者需要手动编写初始化代码,效率低下。 - 中间件兼容性差
高级功能(如USB、文件系统)难以直接与标准库集成,而HAL库与中间件(如FreeRTOS、FatFS)深度绑定。 - 学习成本高
开发者需要深入理解寄存器配置,对新手不友好。
标准库的适用场景
尽管HAL库更现代,标准库仍有一些适用场景:
- 资源极度受限的项目
如果芯片的Flash/RAM资源非常紧张(如STM32F0系列),标准库的轻量级特性更有优势。 - 需要极致性能
标准库没有HAL库的中间层开销,适合对实时性要求极高的场景(如电机控制)。 - 学习底层硬件原理
标准库是学习寄存器操作和硬件工作原理的“垫脚石”。通过分析标准库代码,可以深入理解芯片如何通过寄存器控制外设。 - 维护老旧项目
许多传统嵌入式项目仍在使用标准库,维护时需要熟悉其代码结构。
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐


所有评论(0)