【嵌入式编程】 嵌入式编程介绍

主要介绍嵌入式编程入门知识

嵌入式编程介绍

嵌入式编程(Embedded Programming)是指在嵌入式系统中编写软件的过程,嵌入式系统通常是专门为某一特定任务设计的计算机系统,不像传统计算机那样可以运行多种应用程序。嵌入式系统的应用非常广泛,从智能家居设备、汽车控制系统、工业自动化,到医疗设备等,几乎无处不在。

嵌入式编程是什么?

嵌入式编程是为了控制嵌入式系统硬件而编写的软件。嵌入式系统通常具有以下特点:

  • 资源有限:嵌入式系统一般硬件资源有限,如内存、处理能力、电池寿命等。
  • 任务专一:嵌入式系统通常只执行单一任务或有限的几个任务。
  • 高实时性:很多嵌入式系统需要满足严格的实时性要求,即程序必须在特定时间内完成特定操作。
  • 稳定性高:由于嵌入式设备通常需要长时间运行,因此软件的稳定性和可靠性至关重要。

嵌入式编程不仅仅是开发简单的软件,它还需要开发者对硬件有一定了解,能够在有限的资源下优化代码,确保系统的高效和稳定运行。

嵌入式编程的基础

硬件平台

嵌入式编程首先需要选择合适的硬件平台。常见的嵌入式硬件平台包括:

  • 单片机(MCU):例如STMicroelectronics的STM32、Atmel的AVR系列、Microchip的PIC系列等。单片机广泛应用于各种小型设备。
  • 数字信号处理器(DSP):用于复杂的计算,像离散余弦变换、快速傅里叶变换,常用于图像处理,在数码相机等设备中使用。
  • 开发板:如树莓派、Arduino、ESP32等,它们适合快速原型开发。
  • FPGA:如Xilinx、Intel(Altera)等的FPGA芯片,适用于对硬件有高要求的应用。
  • ASIC:定制/半定制芯片,设计用于解决特殊需求。
  • ARM: 一个英国的芯片设计公司,但是不生产芯片。只卖知识产权。

嵌入式操作系统

对于一些复杂的嵌入式应用,开发者需要选择合适的操作系统来管理硬件资源。常见的嵌入式操作系统有:

  • RTOS(实时操作系统):如FreeRTOS、ChibiOS等,适用于需要高实时性的嵌入式应用。
  • Linux:例如在树莓派等开发板上运行嵌入式Linux,适用于需要丰富功能和较强处理能力的系统。
  • 裸机编程:没有操作系统支持,直接对硬件进行编程,适用于资源较为有限的设备。

编程语言

嵌入式开发常用的编程语言主要有:

  • C语言:由于其高效、底层控制能力和较小的代码体积,C语言是嵌入式编程中最常用的语言。
  • C++:对于一些更复杂的系统,C++提供了面向对象的特性,帮助开发者更好地管理代码。
  • 汇编语言:在一些资源非常有限或者对性能要求极高的场景下,可能需要使用汇编语言来直接控制硬件。

嵌入式编程工具

嵌入式开发离不开合适的开发工具,这些工具通常包括:

  • IDE(集成开发环境):如Keil、IAR Embedded Workbench、Eclipse等,用于编写、编译和调试嵌入式代码。
  • 编译器:GCC(GNU Compiler Collection)是最常用的开源编译器,它支持多种架构的嵌入式开发。
  • 调试工具:JTAG调试器、SWD(Serial Wire Debug)调试器等,用于硬件级调试,帮助开发者实时查看代码执行状态。
  • 仿真器:一些开发环境如Proteus提供硬件仿真,帮助开发者在没有实际硬件的情况下测试代码。

通信协议

一、 核心基石:UART 与 USART

这是理解所有串行通信的起点。

特性 UART (通用异步收发器) USART (通用同步/异步收发器)
核心特点 异步通信 同步 + 异步通信
时钟信号 单独的时钟线。依靠预定义的波特率同步。 单独的时钟线(CLK)。同步模式依赖此时钟。
连接线 最少2根:TXD (发送) 和 RXD (接收) 异步模式:2根 (TXD, RXD) 同步模式:3+根 (TXD, RXD, CLK)
关系 USART 是 UART 的超集。一个USART模块可以配置为UART模式工作。
关键区别 简单、常见、成本低。速率和可靠性受双方时钟精度影响。 更灵活。同步模式速度更高、可靠性更强,但多占一根引脚。
通俗比喻 两个人聊天:仅靠语速(波特率)来理解对方。 一个人唱歌,一个人打拍子:唱的人按拍子唱,听的人按拍子听,节奏精准。

现状:在现代单片机中,标为“UART”的接口实质上绝大多数都是“USART”功能,只是大家习惯统称为UART。

二、 理解层次:物理层 vs. 数据链路层

这是理清所有协议关系的最关键概念。请参考OSI模型(简化版):

  1. 物理层 (Physical Layer):规定“如何传输0和1”,解决电气特性、电平标准、接口形状的问题。好比公路的材料和结构(柏油路、水泥路、铁轨)
  2. 数据链路层 (Data Link Layer):规定“数据包如何组织、如何校验、谁先说话”,解决帧格式、差错控制、寻址、仲裁的问题。好比交通规则(红绿灯、停让标志、车道线)

常见的物理层标准/协议

协议 描述 特点 与UART的关系
TTL电平 单片机引脚直出电平 (0V=0, 3.3V/5V=1) 距离极短(<0.5m),易受干扰 UART 产生 TTL电平信号
RS-232 通过芯片(如MAX232)将TTL电平转换为(±3~±15V) 抗干扰增强,距离可达15米,点对点 UART -> MAX232芯片 -> RS-232接口
RS-485 通过芯片(如MAX485)将TTL转换为差分信号 抗干扰极强,距离远(1200m),支持多点 UART -> MAX485芯片 -> RS-485网络
CAN收发器 将CAN控制器的TTL信号转换为CAN差分电平(CAN_H, CAN_L) 高速、高可靠,用于汽车和工业领域 单片机CAN控制器 -> CAN收发器 -> CAN总线

常见的数据链路层协议

协议 描述 特点 与UART的关系
UART帧 UART硬件本身定义的简单帧格式(起始位+数据位+校验位+停止位) 非常简单,无地址、无复杂校验 UART 自身的规则
SPI 同步、全双工、高速通信协议。有CLK, MOSI, MISO, CS线 速度快,通常有独立的硬件控制器 独立,不依赖UART
I2C 同步、半双工、两线制(SCL, SDA)。支持多主多从,通过地址寻址 引脚节省,有独立的硬件控制器 独立,不依赖UART
CAN 高速、可靠、多主仲裁的工业级总线协议。有复杂的帧格式和错误检测 可靠性极高,有独立的硬件控制器和收发器 独立,不依赖UART
LIN 低速、低成本、单主多从的汽车网络协议 其物理层和帧格式基于UART,是UART的上层应用协议 基于 UART构建
I2C

I2C总线协议

I2C协议是一种多主机的串行通信协议,它只需要两条线:SDA(数据线)和SCL(时钟线)。它支持多个从设备连接到同一总线上,每个设备都有一个唯一的地址。

I2C协议通过地址来选择不同的从设备进行数据交换,因此相比SPI节省了引脚资源。其通信速率低于SPI,但足以应对多数应用。

ESP32S3初始化I2C示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
esp_err_t bsp_i2c_init(void)
{
    i2c_config_t i2c_conf = {
        .mode = I2C_MODE_MASTER, // 主模式
        .sda_io_num = BSP_I2C_SDA, // sda引脚
        .sda_pullup_en = GPIO_PULLUP_ENABLE,
        .scl_io_num = BSP_I2C_SCL, // scl引脚
        .scl_pullup_en = GPIO_PULLUP_ENABLE,
        .master.clk_speed = BSP_I2C_FREQ_HZ // 时钟频率
    };
    i2c_param_config(BSP_I2C_NUM, &i2c_conf);

    return i2c_driver_install(BSP_I2C_NUM, i2c_conf.mode, 0, 0, 0); // 不设置buffer
}
SPI

SPI总线协议

SPI协议是一种高速的、全双工、同步的通信总线。它通常由四条线组成:SCK(时钟线)、MOSI(主设备数据输出,从设备数据输入线)、MISO(主设备数据输入,从设备数据输出线)和CS(片选线)。

当多个从设备被连接到同一个主设备时,每个从设备都有一个单独的片选信号。数据在时钟信号的边沿被采样,通常是在上升沿或下降沿。SPI的速率比I2C高,但需要更多的引脚资源。

I2S

I2S协议:特点、工作原理、差异及其应用 ESP32 I2S使用 数字音频接口,常见数字音频信号传输标准,如I2S、PCM(TDM)、PDM等

I2S(Inter-IC Sound)协议 是一种用于将数字音频数据从一个设备传输到另一个设备的协议。该协议在电子设备内的集成电路(IC)之间传输脉冲编码调制(PCM)音频数据。I2S在将预录的音频文件从微控制器(MCU)传输到DAC或放大器的过程中起关键作用。此协议还可通过麦克风实现音频数字化。I2S协议不涉及压缩,因此无法播放OGG、MP3等压缩音频格式,但支持WAV文件。

ESP32 包含 2 个 I2S 外设。通过配置这些外设,可以借助 I2S 驱动来输入和输出采样数据。

标准 模式下的 I2S 总线包含以下几条线路:

  • MCLK:主时钟线。该信号线可选,具体取决于从机,主要用于向 I2S 从机提供参考时钟。
  • BCLK:位时钟线。用于数据线的位时钟。
  • WS:字(声道)选择线。通常用于识别声道(除 PDM 模式外)。
  • DIN/DOUT:串行数据输入/输出线。如果 DIN 和 DOUT 被配置到相同的 GPIO,数据将在内部回环。

PDM 通信模式下的 I2S 总线包含以下几条线路:

  • CLK:PDM 时钟线。
  • DIN/DOUT:串行数据输入/输出线。
CAN

CAN总线

CAN(Controller Area Network)总线协议是由 BOSCH 发明的一种基于消息广播模式的串行通信总线,它起初用于实现汽车内ECU之间可靠的通信,后因其简单实用可靠等特点,而广泛应用于工业自动化、船舶、医疗等其它领域。相比于其它网络类型,如局域网(LAN, Local Area Network)、广域网(WAN, Wide Area Network)和个人网(PAN, Personal Area Network)等,CAN 更加适合应用于现场控制领域,因此得名。

CAN总线是一种多主控(Multi-Master)的总线系统,它不同于USB或以太网等传统总线系统是在总线控制器的协调下,实现A节点到B节点大量数据的传输,CAN网络的消息是广播式的,亦即在同一时刻网络上所有节点侦测的数据是一致的,因此比较适合传输诸如控制、温度、转速等短消息。

LIN Bus

LIN Bus

由于不同车厂定义的协议兼容性的问题,在 1998 年由欧洲五大车厂(BMW, Volkswagen Group, Audi Group, Volvo Cars, Mercedes-Benz)成立联合工作组,由 Volcano Automotive Group 和 Motorola 提供技术支持,开发一种定位于车身电子领域传感器(Sensors)和执行器(Actuators)组网的串行通信总线,要求该总线系统的协议和时序控制尽可能简单,即使低端MCU没有专用通信单元也可以实现基于该总线的通信。这种总线即为 LIN 总线。

三、 无线协议分析:蓝牙、WiFi、2.4G

无线协议是完整的协议栈,包含了从物理层到应用层的所有定义。单片机通常通过串口与实现这些协议的“模组”交互。

技术 物理层 (公路) 数据链路层及更高层 (交通规则) 单片机如何与其交互
蓝牙 (Bluetooth) 2.4GHz无线电波 (GFSK调制) 基带/L2CAP层:管理连接、分包、加密。 应用层Profile:如SPP(串口透传)、GATT(低功耗蓝牙) 单片机通过 UART 连接蓝牙模块(如HC-05),发送AT指令或数据。模块内部完成所有复杂协议处理。UART是模块的输入口
WiFi 2.4GHz/5GHz无线电波 (DSSS/OFDM调制) MAC层:帧结构、CSMA/CA访问控制、加密(WPA2)。 TCP/IP协议栈:运行在更上层。 单片机通过 UARTSPI 连接WiFi模块(如ESP8266),发送AT指令控制其联网和收发TCP/IP数据包。
2.4G私有协议 (如NRF24L01) 2.4GHz无线电波 (GFSK调制) 厂商自定义的简单链路层:定义自己的数据包结构(地址、载荷、CRC)。 单片机通过 SPI 接口直接控制射频芯片的寄存器,配置参数并收发原始数据包。这里用了SPI,因为速度要求比UART高

四、 总结与全局关系图

所有协议与单片机核心的关系,可以通过下图一目了然:

com

图例与说明

  • 关键路径

    • UART路径:展示了UART数据如何通过不同物理层芯片(RS232/RS485)转换为不同的网络标准,以及如何作为高层协议(LIN/PPP)的基础和无线模组(BLE/Wi-Fi)的输入通道。
    • 独立协议路径:展示了SPI、I2C、CAN作为独立且平行的通信方式,直接由专用控制器管理。
    • 无线路径:展示了单片机通过UART或SPI与无线模组交互,由模组处理所有无线通信的复杂性。

常用模块

LCD

LVGL & gui guider

参考资料:

常用控件:

1
2
3
lv_XXX_create() // 如btn按键等
lv_label_create() // label
lv_timer_create() // timer

事件Event

1
2
3
4
5
交互类:点击、长按、释放、拖动
状态变化:失去焦点、获得焦点
对象变化:创建、删除、页面(屏)加载

添加事件接口:lv_obj_add_event_cb()

add_event

定时器timer

add_timer

常见问题

1、长文件名无法正常显示或其中中文无法显示

1
settting里面设置fat的Long filename support,API character encoding使用utf-8,记得保存

蓝牙模块

简介

蓝牙模块可以将有线串口数据流转换为无线蓝牙数据流,实现无线串口功能。

蓝牙类别 标志 特性
经典蓝牙 SPP,蓝牙3.0及以下 功耗高,速率较快,先配对后连接
低功耗蓝牙 BLE,蓝牙4.0及以上 功耗低,速率较慢,快速连接 增加组网、广播、定位等新功能
双模蓝牙 SPP + BLE 同时集成经典蓝牙和低功耗蓝牙,兼容性更强
主从类别 特性
单从机 仅能被动等待主设备连接,无法主动发起连接请求
主从一体 可切换角色为主设备或从设备,作为主设备时,可主动发起连接请求

常见模组

  • HC-04
  • HC-05
  • HC-08
  • JDY-31
  • JDY-33
  • BT16

硬件连接

blueteeth_connection

蓝牙模块配置(AT模式)

蓝牙未连接或者连接后按住KEY不放,可以使模块进入AT模式,此时通过串口发送AT指令,可对蓝牙模块进行配置。

AT指令 功能
AT 测试通讯
AT+BAUD 查询和设置串口波特率
AT+DEFAULT 参数恢复默认值
AT+ROLE 查询和设置角色(主设备/从设备)
AT+NAME 查询和设置经典蓝牙名称
AT+PIN 查询和设置经典蓝牙配对密码
AT+BNAME 查询和设置BLE蓝牙名称

注:以上仅以HC-04为例介绍AT模式,不同蓝牙模块的AT指令和进入AT模式的方法都可能不同,详细介绍请参考模块对应的手册

Bluetooth_1

IMU

IMU芯片通常通过SPI(Serial Peripheral Interface)或I2C(Inter-Integrated Circuit)两种通信协议与微控制器进行数据交换。

在选择SPI或I2C时,需要考虑到系统的需求。例如,如果对速度和数据吞吐量有较高要求,则SPI可能是更好的选择;如果引脚资源有限或者需要支持多设备通信,I2C则更为合适。

mpu6050

    / [pdf]

QMI8658

国产芯片

ESP32示例代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// 初始化qmi8658
void qmi8658_init(void)
{
    uint8_t id = 0; // 芯片的ID号
    qmi8658_register_read(QMI8658_WHO_AM_I, &id ,1); // 读芯片的ID号
    while (id != 0x05)  // 判断读到的ID号是否是0x05
    {
        vTaskDelay(1000 / portTICK_PERIOD_MS);  // 延时1秒
        qmi8658_register_read(QMI8658_WHO_AM_I, &id ,1); // 读取ID号
    }
    ESP_LOGI(TAG, "QMI8658 OK!");  // 打印信息

    qmi8658_register_write_byte(QMI8658_RESET, 0xb0);  // 复位  
    vTaskDelay(10 / portTICK_PERIOD_MS);  // 延时10ms
    qmi8658_register_write_byte(QMI8658_CTRL1, 0x40); // CTRL1 设置地址自动增加
    qmi8658_register_write_byte(QMI8658_CTRL7, 0x03); // CTRL7 允许加速度和陀螺仪
    qmi8658_register_write_byte(QMI8658_CTRL2, 0x95); // CTRL2 设置ACC 4g 250Hz
    qmi8658_register_write_byte(QMI8658_CTRL3, 0xd5); // CTRL3 设置GRY 512dps 250Hz 
}

滤波

TF卡

esp-idf官方例程:https://github.com/espressif/esp-idf/tree/bbe8aabca0/examples/storage/sd_card

ESP32与TF卡通信主要有两种方式:

  • SSPI:串行外设接口
  • SDIO:安全数字输入输出接口。其中SDIO又分为两种模式:
    • 四线模式:有四个数据引脚
    • 一线模式:只有一个数据引脚

References

Licensed under CC BY-NC-SA 4.0
最后更新于 Nov 26, 2025 22:40 +0800
loveleaves
使用 Hugo 构建
主题 StackJimmy 设计