嵌入式开发之旅

前言

本文章参考了同为米醋电子工作室会员柒的部分优秀笔记,仅做个人学习用,如有侵权,请联系本人删除。

从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. 你需要做什么:插上电源,按下开关。
  2. 你不需要做什么:了解水壶内部的电路设计、加热原理、温度控制逻辑。
    示例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库取代?
  1. 移植困难
    标准库的API在不同芯片系列之间差异较大。例如,STM32F1和STM32F4的标准库函数名可能相同,但底层寄存器完全不同,移植时需要大量修改代码。
  2. 工具链支持不足
    标准库缺乏现代化工具支持(如STM32CubeMX),开发者需要手动编写初始化代码,效率低下。
  3. 中间件兼容性差
    高级功能(如USB、文件系统)难以直接与标准库集成,而HAL库与中间件(如FreeRTOS、FatFS)深度绑定。
  4. 学习成本高
    开发者需要深入理解寄存器配置,对新手不友好。
标准库的适用场景

尽管HAL库更现代,标准库仍有一些适用场景:

  1. 资源极度受限的项目
    如果芯片的Flash/RAM资源非常紧张(如STM32F0系列),标准库的轻量级特性更有优势。
  2. 需要极致性能
    标准库没有HAL库的中间层开销,适合对实时性要求极高的场景(如电机控制)。
  3. 学习底层硬件原理
    标准库是学习寄存器操作和硬件工作原理的“垫脚石”。通过分析标准库代码,可以深入理解芯片如何通过寄存器控制外设。
  4. 维护老旧项目
    许多传统嵌入式项目仍在使用标准库,维护时需要熟悉其代码结构。
Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐