1. 课程导学与开发环境搭建
各位同学好,我是你们这门课的老周。做嵌入式通信接口开发十几年了,踩过的坑比写过的代码还多。今天咱们先不急着敲代码,把地基打牢再说。
这一章,我带你看看嵌入式通信协议的全貌,对比一下 I2C、SPI、UART、CAN 这四位"老大哥"到底有什么区别。然后咱们把开发环境搭起来,再学学逻辑分析仪和示波器怎么用——这两样东西,可是调试通信协议的"眼睛"。
1.1 嵌入式通信协议概述
嵌入式系统里,芯片和芯片之间怎么说话?靠的就是通信协议。说白了,就是一套约定好的"规矩":谁先开口、说多快、怎么确认对方听懂了。
我刚开始做项目那会儿,总觉得协议这东西,能用就行。直到有一次,一个 SPI 设备死活读不到数据,折腾了两天,最后发现是时钟极性配反了。嗯,从那以后,我再也不敢小看协议细节了。
核心观点:通信协议的本质是"时序 + 电平 + 数据格式"的三位一体。任何一个环节出错,设备之间就没法正常沟通。
常见的嵌入式通信接口,按传输方式可以分为两类:
- 同步通信:发送和接收共用同一个时钟信号。典型代表:I2C、SPI。
- 异步通信:双方各自有独立的时钟,靠起始位和停止位来同步。典型代表:UART、CAN。
你想想看,同步通信就像两个人一起唱歌,得有人打拍子;异步通信就像两个人发微信,你发你的,我回我的,只要格式对就行。
1.2 I2C / SPI / UART / CAN 协议对比
这四种协议,是嵌入式开发里最常用的。我整理了一张对比表,你一看就明白:
| 特性 | I2C | SPI | UART | CAN |
|---|---|---|---|---|
| 信号线数 | 2 线 (SCL, SDA) | 4 线 (SCK, MOSI, MISO, CS) | 2 线 (TX, RX) | 2 线 (CAN_H, CAN_L) |
| 通信方式 | 同步,半双工 | 同步,全双工 | 异步,全双工 | 异步,半双工 |
| 拓扑结构 | 多主多从,总线型 | 一主多从,星型 | 点对点 | 多主,总线型 |
| 最大速率 | 3.4 Mbps (高速模式) | 几十 Mbps | 典型 115200 bps | 1 Mbps |
| 传输距离 | 几米以内 | 几米以内 | 十几米 | 几十米到几公里 |
| 典型应用 | 传感器、EEPROM | 显示屏、ADC、SD卡 | 调试口、GPS、蓝牙 | 汽车、工业控制 |
我个人习惯,选协议的时候先看三个条件:距离、速度、设备数量。距离短、设备多,选 I2C;速度快、数据量大,选 SPI;点对点通信,UART 最省事;要抗干扰、远距离,那就得上 CAN。
小经验:我在一个车载项目里,用 UART 传数据,结果线长了点,数据全是乱码。后来换成 CAN,问题立马解决。所以,别小看传输距离这个参数。
1.3 开发板与工具链搭建
咱们这门课,用的是 STM32 系列开发板。为什么选它?因为 STM32 的通信外设丰富,文档齐全,社区活跃。你遇到问题,网上随便一搜就有答案。
工具链方面,我推荐两个:
- Keil MDK:老牌 IDE,编译快,调试方便。适合习惯 Windows 环境的朋友。
- STM32CubeIDE:ST 官方出品,免费,集成了 CubeMX 配置工具。我个人现在主要用这个。
搭建步骤其实很简单,我列个清单:
- 下载并安装 Keil 或 STM32CubeIDE。
- 安装对应的芯片包(Keil 需要装 Pack,CubeIDE 自带)。
- 连接开发板,安装驱动(ST-Link 或 J-Link)。
- 新建一个工程,选好芯片型号,配置时钟和调试接口。
- 写一个简单的 LED 闪烁程序,验证环境是否正常。
注意:我曾经遇到过 ST-Link 驱动装不上,折腾了半天,最后发现是 USB 线的问题。换了一根带屏蔽的线,立马好了。所以,调试线材一定要用质量好的。
下面这张图,展示了咱们整个课程的知识体系:
1.4 逻辑分析仪与示波器使用入门
调试通信协议,光靠 printf 打印日志是不够的。你想想看,UART 发出去的数据对不对,SPI 的时钟极性有没有配错,这些都得靠仪器来看。
逻辑分析仪和示波器,就是咱们的"硬件调试器"。
- 逻辑分析仪:专门看数字信号,能同时抓多路信号,自动解析协议。适合调试 I2C、SPI、UART 这些数字接口。
- 示波器:看模拟信号,能观察波形质量、噪声、上升沿/下降沿时间。适合分析信号完整性和时序问题。
我个人的习惯是:先用逻辑分析仪抓数据,看协议对不对;如果发现数据异常,再用示波器看波形质量。两样配合,基本能解决 90% 的问题。
入门技巧:刚开始用逻辑分析仪,别贪多。先抓一个字节的数据,看看起始位、数据位、停止位对不对。等熟悉了,再抓整包数据。
举个例子,调试 UART 时,你可以在逻辑分析仪上看到这样的时序:
// UART 发送一个字节 0x55 (二进制 01010101)
// 空闲状态:高电平
// 起始位:低电平 (1 bit)
// 数据位:0 1 0 1 0 1 0 1 (8 bits,LSB first)
// 停止位:高电平 (1 bit)
// 逻辑分析仪上看到的波形:
// 高 ──────┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐──────
// │ │ │ │ │ │ │ │ │
// 低 └─┘ └─┘ └─┘ └─┘
// S 0 1 0 1 0 1 0 1 S
// (S = 起始位,最后一位 S = 停止位)
你看,有了仪器,这些时序细节一目了然。比对着手册猜,靠谱多了。
避坑指南:我曾经用逻辑分析仪抓 SPI 数据,发现 MISO 线上一直没信号。查了半天,原来是 CS 片选信号没拉低。所以,抓数据前,先确认使能信号对不对。