嵌入式接口和总线

UART(串口)

简介

Universal Asynchronous Receiver Transmitter 即通用异步收发器,是一种通用的串行、异步通信总线该总线有两条数据线,可以实现全双工的发送和接收在嵌入式系统中常用于主机与辅助设备之间的通信

通信基础

串行通信和并行通信是数据传输的两种核心方式,核心区别在于数据位的传输路径数量,适用场景因传输距离、速度、成本等因素差异明显:

一、核心定义
  • 串行通信:数据按 “位” 为单位,通过一条传输线(加地线) 逐位、依次传输(比如排队单列通过隧道)。
  • 并行通信:数据按 “字节 / 字” 为单位,通过多条并行传输线同时传输多个位(比如多列队伍同时通过多条隧道)。
二、关键区别(核心特性对比)
特性 串行通信 并行通信
传输线数量 少(1-2 条数据线),成本低 多(n 位数据需 n 条线),成本高
传输距离 远(信号干扰小、衰减低),支持米 - 千米级 近(线间干扰严重、衰减快),仅限厘米 - 米级
传输速度 单条线速度有限,但可通过差分信号、高频优化(如 USB 3.0、PCIe) 单次传输多位,短距离下速度极高(如内存 DDR)
抗干扰能力 强(线少,串扰少) 弱(线多且密集,串扰、同步问题突出)
同步要求 需严格同步时钟(异步串行可通过起始 / 停止位同步) 需高精度同步(所有线的数据需同时到达)
三、典型应用场景
1. 串行通信(远距离、低成本优先)
  • 嵌入式 / 工业:UART(串口)、I2C、SPI(短距离串行,芯片间通信)、RS232/RS485(工业设备通信)。
  • 日常设备:USB(手机充电 / 数据传输)、以太网(网线通信)、HDMI(视频传输)、蓝牙 / Wi-Fi(无线串行本质)。
2. 并行通信(短距离、高速优先)
  • 板级芯片间:内存 DDR(如 DDR5,多通道并行传输)、CPU 与北桥芯片通信。
  • 传统设备:并行打印机接口(LPT 口,已逐步淘汰)、IDE 硬盘接口(被 SATA 串行接口替代)。
四、核心逻辑总结
  • 串行通信:“少线慢走、稳走远”—— 牺牲单条线的传输效率,换低成本、抗干扰和长距离,是主流的远距离数据传输方式。
  • 并行通信:“多线快走、近距优”—— 利用多线并行提升速率,但受限于距离和干扰,仅用于短距离高速场景(如内存、芯片内部)。

随着技术发展,很多传统并行接口(如 IDE、LPT)已被串行接口替代,核心原因是串行通信在长距离、抗干扰、成本控制上的综合优势更适配现代设备需求。

UART数据帧格式

UART(通用异步收发器)的帧格式说明,用于定义串口通信中单个字符的传输结构,分以下模块解析:

帧结构模块 说明 作用
空闲位 逻辑 1(高电平),无数据传输时的默认状态 标识通信 “空闲”,为下一个字符的起始位做准备
起始位 1 位,逻辑 0(低电平) 通知接收端 “数据开始传输”,触发接收端按波特率采样后续数据
数据位 5-8 位,先传输低位、后传输高位 承载实际的字符数据(如 ASCII 码),位数可配置(常见 8 位)
校验位 可有可无 用于简单的错误检测(如奇偶校验:奇校验要求数据位 + 校验位中 1 的个数为奇数,偶校验则为偶数)
停止位 1 位、1.5 位或 2 位,逻辑 1(高电平) 通知接收端 “当前字符传输结束”,可用于补偿收发双方的时序误差

UART 通过这种 “起始位 - 数据位 - 校验位 - 停止位” 的帧结构,实现了无需共享时钟的异步通信 —— 接收端通过起始位同步采样节奏,通过停止位确认传输完成,从而在两根线(TX 发送、RX 接收)上完成全双工的数据交互,是嵌入式、工业领域中设备间串口通信的核心协议格式。

比特率就是每秒传输的二进制位数,单位是 bps(Bits Per Second)。

UART 控制器

  • 集成情况:一般处理器(如单片机、ARM 芯片)都会集成 UART 控制器,无需额外外接硬件即可实现串口通信。
  • 使用方式:使用 UART 进行通信时,只需对其内部的相关寄存器进行设置(如配置波特率、数据位长度、校验位、停止位等参数),即可实现数据的收发控制。

单工和双工

一、单工通信
  • 定义:数据只能单向传输,发送端只发送、接收端只接收,无法反向传输。
  • 特点:传输链路简单,成本低,但灵活性差。
  • 典型应用
    • 广播 / 电视:电台、电视台向观众单向发送信号。
    • 传感器:温度传感器仅向控制器上报数据,无反向指令。
    • 传统对讲机(按下通话键才能说话,此时无法听)。
二、双工通信

双工通信又分为半双工全双工,核心差异是双向传输的 “同时性”:

1. 半双工通信
  • 定义:数据可以双向传输,但同一时间只能单方向传输(需切换传输方向)。
  • 特点:链路可双向复用,成本低于全双工,但存在 “切换延迟”。
  • 典型应用
    • 对讲机(现代手持对讲机,可听可讲,但不能同时进行)。
    • 早期的以太网(CSMA/CD,同一时间网段内只能有一方发数据)。
    • 某些工业总线(如 RS-485,多设备分时双向通信)。
2. 全双工通信
  • 定义:数据可以双向同时传输,发送和接收可独立进行,无需切换方向。
  • 特点:通信效率最高,但链路设计复杂(需独立的发送 / 接收通道)。
  • 典型应用
    • 电话:双方可同时说话、听对方声音。
    • 现代以太网(如千兆以太网,发送和接收通道独立)。
    • 手机通话、即时通讯(微信语音 / 文字可同时收发)。
    • 计算机串口(UART)若配置为全双工模式,也可同时收发数据。
三、核心区别对比表
类型 数据传输方向 同时双向传输 链路复杂度 典型场景
单工 单向 简单 广播、传感器上报
半双工 双向(分时) 中等 对讲机、早期以太网
全双工 双向(同时) 复杂 电话、现代以太网、手机

理解单双工通信的差异,能帮助在设计通信系统时,根据 “双向传输需求”“实时性要求”“成本预算” 选择合适的模式(比如对实时双向交互要求高的场景选全双工,单向广播场景选单工即可)。

串口输出重定向

是指:将默认的调试输出(比如 printfSerial.print 打印的内容),从「默认串口」转移到「自定义的串口 / 输出介质」,核心目的是灵活分配串口资源(比如默认串口连传感器,调试信息改到另一个串口)。

一、核心原理

串口默认是将数据发送到外部物理接口(如 DB9 串口、单片机的 TX 引脚),输出重定向则是通过修改数据的输出路径,让数据流向其他目标(如文件、网络、本地控制台),本质是 “拦截并修改数据的输出通道”。

二、常见实现方式
1. 软件层面(嵌入式 / 操作系统场景)

在嵌入式系统(如 STM32 单片机)或带操作系统的设备(如 Linux)中,通过修改标准输出(stdout)的映射关系,让原本打印到串口的信息重定向到其他位置。

2. 硬件层面(物理信号转发)

通过硬件电路或转接模块,将串口的 TX/RX 信号转发到其他接口(如 USB、以太网),实现 “物理层的输出重定向”。

  • 典型场景:
    • USB 转串口模块(如 CH340):将串口信号转为 USB 信号,让电脑将串口输出识别为 USB 设备的数据流。
    • 串口服务器:将串口输出转为网络数据包(如 TCP/IP),实现远程设备对串口数据的接收。
三、应用场景
  1. 调试与日志记录
    • 嵌入式开发中,将串口调试信息重定向到本地文件,便于离线分析问题(如长时间运行的设备日志)。
    • Linux 设备中,将串口输出重定向到系统日志(syslog),统一管理设备日志。
  2. 跨设备数据交互
    • 工业设备中,将串口传感器的数据重定向到以太网,实现远程监控。
    • 物联网设备中,将串口输出的传感器数据转发到 WiFi 模块,上传到云端。
  3. 模拟与测试
    • 在没有物理串口的环境中(如仿真器),将串口输出重定向到虚拟终端,模拟真实串口的交互。
四、关键注意事项
  • 数据格式兼容:重定向后需确保目标设备能解析串口的数据格式(如波特率、数据位、校验位需一致)。

  • 性能与延迟:若重定向到低速设备(如文件),需注意数据吞吐量,避免因写入过慢导致数据丢失。

  • 双向性扩展:输出重定向通常可扩展为 “双向重定向”(即同时支持输入和输出),实现设备的双向通信改造。

    // 重定向fputc函数,将printf输出定向到USART1
    int fputc(int ch, FILE *f) {
        // 等待串口发送缓冲区为空
        while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
        // 发送字符
        USART_SendData(USART1, (uint8_t)ch);
        return ch;
    }
    

UART 存在的问题

电气接口不统一
问题点 说明
时序与电气特性分离 UART 仅定义了信号的时序(如起始位、数据位的传输顺序),但未定义接口的电气特性(如电平标准、驱动能力)
电平兼容性差 通信时一般使用处理器的 TTL 电平,但不同处理器的 TTL 电平存在差异(如有的是 3.3V 逻辑,有的是 5V 逻辑),导致不同处理器的 UART 不能直接相连
连接器无标准 未规定不同器件连接时的连接器标准,不同设备间通过 UART 通信时,硬件连接的接口形式(如引脚布局、接口形状)不统一,连接很不方便

UART 作为异步串口通信的核心协议,在时序定义上具备通用性,但因电气接口的不统一,实际设备间直连时往往需要电平转换(如 RS232、RS485 等标准就是为解决 TTL 电平兼容性和连接器问题而衍生的)或定制化硬件适配,这是其在跨设备、跨平台应用中需要额外关注的局限性。

抗干扰与通信距离
问题类型 说明 背景与影响
抗干扰能力差 UART 通常使用 TTL 信号表示 0 和 1,但 TTL 信号抗干扰能力弱,数据传输易出错 TTL 信号以高低电平区分二进制位,在复杂电磁环境(如工业场景、长距离传输)中,外界干扰易导致电平误判,引发数据丢包、乱码
通信距离极短 因 TTL 信号抗干扰差,其通信距离受限,一般仅用于同一块电路板上的芯片间通信 超出短距离后,TTL 信号衰减和干扰会急剧增加,无法保证数据可靠传输,因此 UART 原生 TTL 模式仅适用于板级芯片间的近距离交互

为解决这些问题,衍生出了 RS-232、RS-485 等基于 UART 时序的电气标准:RS-232 通过正负电平增强抗干扰(通信距离可达几十米),RS-485 通过差分信号进一步提升抗干扰和传输距离(可达上千米),从而拓展了 UART 在工业、远程通信等场景的应用。

TTL 和 RS232

TTL 和 RS232 是两种串口通信的电平标准,核心区别在于电压范围、抗干扰能力、传输距离,具体说明如下:

一、TTL 信号

  • 定义

    :是单片机、处理器等芯片内部常用的电平标准,属于 “单极性电平”。

    • 逻辑 “1”:一般为 3.3V 或 5V(不同芯片有差异,如 5V TTL 的逻辑 1 是≥2.4V,逻辑 0 是≤0.4V)。
    • 逻辑 “0”:0V 左右。
  • 特点

    • 抗干扰能力弱:单极性电平容易受外界电磁干扰,导致电平误判。
    • 传输距离短:通常仅用于同一块电路板上的芯片间通信(如单片机和传感器在同一块 PCB 上的连接)。
  • 典型场景:嵌入式单片机内部通信(如 STM32 的 UART 默认输出 TTL 电平)。

二、RS232 信号

  • 定义

    :是针对串口通信的标准化电平,属于 “双极性电平”。

    • 逻辑 “1”:-5V ~ -15V。
    • 逻辑 “0”:+5V ~ +15V。
  • 特点

    • 抗干扰能力强:正负电平的差异能有效抵御外界干扰,减少数据错误。
    • 传输距离远:可支持几十米的通信距离(如工业设备间的串口互连)。
  • 典型场景:设备间的长距离串口通信(如老式计算机与 Modem 的连接、工业仪器的串口调试)。

三、核心区别对比

特性 TTL 信号 RS232 信号
电压范围 单极性(0V~5V/3.3V) 双极性(-15V~+15V)
抗干扰能力
传输距离 极短(板内芯片间) 较远(可达几十米)
应用场景 芯片内部、板内短距通信 设备间长距串口通信

简单来说,TTL 是 “芯片内部的短距通信语言”,RS232 是 “设备间的长距通信语言”—— 如果需要让不同设备(如电脑和工业传感器)远距离串口通信,就需要用 RS232;如果只是芯片内部或同一块电路板上的通信,TTL 就足够了。

RS232 协议

核心信息 说明 背景与意义
制定时间与机构 1970 年由美国电子工业协会(EIA)联合贝尔系统、调制解调器厂家、计算机终端生产厂家共同制定 为解决早期串口通信(如 UART)电气接口不统一、抗干扰差的问题,推出的串行通信标准
标准内容 规定了标准连接器(如 DB9、DB25),明确每个引脚的作用;同时定义了信号电平(采用 ±12V 左右的正负电平,区别于 TTL 的 0-5V) 标准化的连接器和电平,让不同厂家的设备可通过 RS232 接口直接互连,且提升了抗干扰能力(通信距离可达几十米)

RS232 是串口通信领域的经典标准,曾广泛用于计算机与调制解调器(Modem)、工业设备的通信,其标准化的硬件接口和电平定义,解决了 UART 原生模式的兼容性和抗干扰痛点,是串行通信从 “板级” 走向 “设备级” 应用的关键技术之一。

RS232 的接口与信号规范

模块 说明 背景与意义
接口类型 最初规定 25 引脚的 DB-25 连接器,后 IBM PC 机简化为 DB-9 连接器并成为事实标准;工业控制中一般仅使用 RXD(接收)、TXD(发送)、GND(地)三条线 标准化连接器解决了设备间物理连接的兼容性问题,简化后的 DB-9 和三线制应用更灵活,降低了硬件成本
信号电平 逻辑 “1” 电平为 - 5V 到 - 15V,逻辑 “0” 电平为 + 5V 到 + 15V 采用正负电平替代 TTL 的单极性电平,大幅提升抗干扰能力,使通信距离可达约 15 米解决了 UART 原生模式抗干扰差、传输距离短的痛点

RS232 通过标准化的硬件接口和电气电平,实现了不同设备间串口通信的兼容性与可靠性,是串行通信从 “板内” 扩展到 “设备间” 的关键技术,曾广泛应用于计算机、工业设备、通信终端的互连,其简化的 DB-9 接口和三线制设计至今仍在部分场景中使用。

RS232 存在的问题

问题类型 说明 背景与影响
电平兼容性与硬件风险 信号电平值较高(±5V~±15V),易损坏接口电路芯片;且与 TTL 电平(0~5V/3.3V)不兼容,需使用电平转换芯片(如 MAX232)才能与 TTL 电路(如单片机)连接 增加了硬件设计的复杂度和成本,若未做电平转换直接连接,会导致芯片烧毁
通信速度较低 传输速率受限于电平驱动能力,无法满足高速数据传输需求 在需要高带宽的场景(如高速设备调试、大数据量串口通信)中,RS232 的速率瓶颈明显
抗干扰能力不足 易产生共模干扰,抗噪声干扰性弱 复杂电磁环境(如工业现场、强电设备附近)中,数据易受干扰导致丢包、乱码
传输距离有限 传输距离较短,一般仅达 15 米 无法满足长距离设备间通信的需求(如跨厂房的工业设备互连)

这些问题促使了后续 RS-485、USB 等更优通信标准的发展:RS-485 通过差分信号提升抗干扰和传输距离(可达上千米),USB 则以高速、即插即用特性替代了 RS232 在很多场景的应用。

RS485 协议

核心信息 说明 背景与意义
制定机构 由电信行业协会和电子工业联盟定义 为解决 RS232 抗干扰弱、传输距离短、多设备组网难的问题,推出的串行通信标准
传输优势 能在远距离(可达上千米)、电子噪声大的环境下有效传输信号 适用于工业现场、强干扰场景的设备通信,如工厂自动化产线、智能电表组网
多站能力 允许连接多个收发器,可利用单一 RS485 接口建立设备网络 支持 “一主多从” 或 “多主多从” 的组网架构,简化了多设备串口通信的硬件设计

RS485 是工业通信领域的核心标准,通过差分信号(两根线的电压差表示数据)实现强抗干扰和长距离传输,同时具备多设备组网能力,是楼宇自控、电力监控、工业物联网等场景中设备互连的主流技术之一。

RS485 的信号特性

特性 说明 背景与优势
差分信号传输 采用差分信号,两线间电压差 + 2V~+6V 表示逻辑 “1”,-2V~-6V 表示逻辑 “0” 差分信号通过 “两线电压差” 识别数据,能有效抵消共模噪声(如电磁干扰),大幅提升抗干扰能力
通信距离 可达 1500m 解决了 RS232 传输距离短的痛点,适用于工业现场、楼宇自控等长距离设备组网场景
电平兼容性 电平与 TTL 兼容,且电压范围降低,不易损坏接口电路芯片 可直接与单片机等 TTL 电平设备连接,减少电平转换的硬件成本,提升系统可靠性

RS485 通过差分信号技术,在抗干扰、传输距离、硬件兼容性上实现了突破,是工业通信、物联网多设备组网的核心标准之一,广泛应用于智能电表、传感器网络、工业自动化产线等场景。

RS485 的接口特性

特性 说明 背景与意义
拓扑结构 采用两线制,总线式拓扑结构,同一总线上可同时存在多个节点 支持 “一主多从” 或 “多主多从” 的组网模式,简化了多设备串口通信的硬件布线,适用于工业物联网、智能电网等多节点场景
通信模式 半双工工作方式(因两线制需复用差分信号线,发送和接收不能同时进行) 编程时需处理收发切换逻辑(如通过使能引脚控制收发方向),虽牺牲了全双工的同时收发能力,但换来了总线式组网的低成本和易扩展性

RS485 的两线制总线拓扑和半双工模式,是其实现长距离多设备组网的核心设计:总线式结构让几十甚至上百个设备可共享同一通信链路,半双工的收发切换则通过软件逻辑即可灵活控制,这使得 RS485 成为工业现场、楼宇自控等领域中 “多设备远距离互连” 的首选串口标准之一。

IIC

核心信息 说明 背景与应用
推出背景 由 Philips 公司于八十年代初推出 为解决芯片间短距离、低速通信的硬件复杂度问题,设计的串行总线标准
通信特性 串行、半双工总线,适用于近距离、低速的芯片间通信 常见于单片机与传感器(如温湿度传感器)、存储芯片(如 EEPROM)的板级互连
硬件结构 两根双向信号线:SDA(数据线,用于收发数据)、SCL(时钟线,用于通信双方时钟同步) 硬件设计简单,仅需两根线即可实现多设备互连,大幅降低成本
应用领域 因硬件简单、成本低,在嵌入式、消费电子、工业控制等领域广泛应用 例如手机中的传感器通信、家电的板内芯片交互、工业设备的参数配置等场景

IIC 总线凭借 “两线制、低成本、多设备组网” 的优势,成为板级芯片间短距离通信的主流标准之一,尤其在对硬件复杂度和成本敏感的嵌入式系统中应用极为广泛。

IIC 总线的多主机与通信机制

特性 说明 背景与优势
多主机总线 总线上的器件可分为主机和从机,主机有权发起 / 结束通信,从机仅能被主机呼叫;且支持多个主机同时竞争总线,具备冲突检测和仲裁功能 解决了多设备同时通信的冲突问题,提升总线的灵活性和可靠性,适用于多主控设备的场景(如多单片机协同系统)
设备地址 每个器件有唯一的 7bit 地址,且可在主机 / 从机角色间切换(同一时刻仅一个主机) 支持多设备动态组网,器件增减不影响其他设备工作,简化了系统的可扩展性设计
收发角色 通信时发送数据的为发送器,接收数据的为接收器 角色可动态切换,满足双向通信需求,如主机向从机写数据时主机是发送器,从机是接收器;从机向主机读数据时角色反转

IIC 总线的多主机设计和灵活寻址机制,使其在板级多设备低速通信场景中具备极强的适应性,例如智能手表中传感器与主控的互连、工业设备中多模块的参数配置等,都是通过 IIC 的多主机和仲裁能力实现稳定通信的。

IIC 总线通信流程

步骤 说明 作用
1. 主机发送起始信号 主机发起通信,启用 IIC 总线 标记通信的开始,通知总线上的设备准备接收数据
2. 主机发 送从机地址与方向 主机发送 1 字节数据,包含从机地址(7bit)和数据 传输方向(读 / 写) 明确要通信的从机设备,以及后续数据是 “主机写给从机” 还是 “从机读给主机”
3. 从机发送应答信号 被寻址的从机回复应答信号 确认从机已收到地址,通信可继续
4. 发送器发送 1 字节数据 发送方(主机或从机)传输 1 字节数据 完成单字节数据的交互
5. 接收器发送应答信号 接收方回复应答信号 确认数据已收到,可继续传输下一字节
……(循环步骤 4、5) 按需重复数据发送与应答过程 实现多字节数据的连续传输
n. 主机发送停止信号 主机结束通信,释放 IIC 总线 标记通信的结束,总线回到空闲状态

这一流程是 IIC 总线实现 “设备寻址 - 数据交互 - 总线释放” 的核心机制,确保了多设备间通信的有序性和可靠性,例如单片机读取 IIC 接口的温湿度传感器数据、向 EEPROM 存储参数等场景,均遵循此流程完成通信。

IIC 总线寻址方式

特性 说明 作用
数据类型 总线上传送的广义数据既包含地址,也包含真正的通信数据 实现 “设备寻址” 与 “数据交互” 的一体化传输,简化总线通信逻辑
地址字节结构 主机发送的首字节数据中,高 7 位为从机地址,最低位(第 8 位)表示数据传输方向:‘0’ 为 “主机发送数据(写给从机)”,‘1’ 为 “主机接收数据(从从机读取)” 明确通信的目标从机及数据流向,让多设备共享总线时能准确识别自身是否被寻址
从机寻址逻辑 总线上所有从机接收地址字节后,将自身 7 位地址与该字节高 7 位比较,地址匹配的从机被寻址,再根据第 8 位确定自身为 “发送器” 或 “接收器” 实现多从机环境下的精准设备选择,确保数据仅在目标设备间交互

这种寻址方式是 IIC 总线支持 “一主多从” 组网的核心设计,例如在同时连接温湿度传感器、加速度传感器、EEPROM 的系统中,主机可通过不同的 7 位地址精准控制每个设备,实现数据的有序收发。

IIC 总线的起始信号和停止信号

信号类型 定义 作用
起始信号 SCL 为高电平时,SDA 由高变低 主机发起通信,标记总线占用状态,通知从机准备接收数据
停止信号 SCL 为高电平时,SDA 由低变高 主机结束通信,释放总线至空闲状态,让其他设备可发起新通信
发起方与总线状态 均由主机发出;起始信号后总线占用,停止信号后总线空闲 确保多设备共享总线时的通信有序性,避免总线冲突

这两种信号是 IIC 总线 “启动 - 结束” 通信的核心标识,例如单片机与 IIC 传感器通信时,通过起始信号开始数据交互,通信完成后以停止信号释放总线,保障了多设备环境下的总线资源合理分配。
在这里插入图片描述

IIC 总线的字节传送与应答

特性 说明 作用
字节结构 每个字节为 8 位长度,数据传送时先传最高位,后传低位 统一数据传输的位序,确保收发双方对数据的解析一致
应答机制 发送器发送完 1 字节数据后,接收器必须发送 1 位应答位回应 确认数据已成功接收,保障通信的可靠性,若无应答则可判定通信异常
帧长度 一帧共 9 位(8 位数据 + 1 位应答) 实现 “数据传输 - 接收确认” 的完整交互单元,让多字节通信可逐帧校验

这种 “8 位数据 + 1 位应答” 的帧结构,是 IIC 总线确保数据可靠传输的关键设计,例如单片机向 IIC 接口的 EEPROM 写入数据时,每发送 1 字节都会等待 EEPROM 的应答位,以此确认数据写入成功。
在这里插入图片描述

IIC 总线的数据传输时序

时钟阶段 数据操作 说明
SCL 低电平期间 发送器向 SDA 发送 1 位数据 此阶段 SDA 信号可变化,用于发送方更新数据位
SCL 高电平期间 接收器从 SDA 读取 1 位数据 此阶段 SDA 信号必须保持稳定,确保接收方读取数据的准确性

这种时序设计是 IIC 总线实现 “同步数据收发” 的核心机制:低电平让发送方有时间更新数据,高电平让接收方稳定读取数据,从而在两根线(SDA、SCL)上实现可靠的串行通信,例如单片机与 IIC 存储芯片交互时,就是通过这种时序完成数据的准确读写。

实用案例 三轴加速度传感器MPU6050

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码仅供参考

/**********************************************************
* 函数功能:I2C向特定地址写一个字节
* 输入参数:
*           slave_addr:   I2C从机地址
*           addr:         芯片内部寄存器地址
*           data:         写入的数据
**********************************************************/
void iic_write (unsigned char slave_addr, unsigned char addr, unsigned char data)
{
    /*对时钟源进行512倍预分频 打开IIC中断(每次完成一个字节的收发后中断标志位会自动置位)*/
    I2C5.I2CCON = I2C5.I2CCON | (1<<6) | (1<<5);

    /*设置IIC模式为主机发送模式 使能IIC发送和接收*/
    I2C5.I2CSTAT = 0xd0;
    /*将第一个字节的数据写入发送寄存器 即从机地址和读写位(MPU6050-I2C地址+写位0)*/
    I2C5.I2CDS = slave_addr<<1;
    /*设置IIC模式为主机发送模式 发送起始信号后启用总线 使能IIC发送和接收*/
    I2C5.I2CSTAT = 0xf0;

    /*等待从机接受完一个字节后产生应答信号(应答后中断挂起位自动置位)*/
    while(!(I2C5.I2CCON & (1<<4)));
    
        /*将要发送的第二个字节数据(即MPU6050内部寄存器的地址)写入发送寄存器*/
    I2C5.I2CDS = addr;
    /*清除中断挂起标志位 开始下一个字节的发送*/
    I2C5.I2CCON = I2C5.I2CCON & ~(1<<4);
    /*等待从机接受完一个字节后产生应答信号(应答后中断挂起位自动置位)*/
    while(!(I2C5.I2CCON & (1<<4)));

    /*将要发送的第三个字节数据(即要写入到MPU6050内部指定的寄存器中的数据)写入发送寄存器*/
    I2C5.I2CDS = data;
    /*清除中断挂起标志位 开始下一个字节的发送*/
    I2C5.I2CCON = I2C5.I2CCON & ~(1<<4);
    /*等待从机接受完一个字节后产生应答信号(应答后中断挂起位自动置位)*/
    while(!(I2C5.I2CCON & (1<<4)));

    /*发送停止信号 结束本次通信*/
    I2C5.I2CSTAT = 0xD0;
}

/**********************************************************
* 函数功能:I2C从特定地址读取1个字节的数据
* 输入参数:
*           slave_addr:I2C从机地址
*           addr:芯片内部寄存器地址
* 返回参数:
*           unsigned char:读取的数值
**********************************************************/
unsigned char iic_read(unsigned char slave_addr, unsigned char addr)
{
    unsigned char data = 0;

    
      // 对时钟源进行512倍预分频,打开IIC中断(每次完成一个字节的收发后中断标志位会自动置位)
    I2C5.I2CCON = I2C5.I2CCON | (1<<6) | (1<<5);

    /*设置IIC模式为主机发送模式,使能IIC发送和接收*/
    I2C5.I2CSTAT = 0xd0;
    /*将第一个字节的数据写入发送寄存器,即从机地址和读写位(MPU6050-I2C地址+写位0)*/
    I2C5.I2CDS = slave_addr<<1;
    /*设置IIC模式为主机发送模式,发送起始信号后启用总线,使能IIC发送和接收*/
    I2C5.I2CSTAT = 0xf0;

    /*等待从机接受完一个字节后产生应答信号(应答后中断挂起位自动置位)*/
    while(!(I2C5.I2CCON & (1<<4)));

    /*将要发送的第二个字节数据(即要读取的MPU6050内部寄存器的地址)写入发送寄存器*/
    I2C5.I2CDS = addr;
    /*清除中断挂起标志位,开始下一个字节的发送*/
    I2C5.I2CCON = I2C5.I2CCON & ~(1<<4);
	    /*等待从机接受完一个字节后产生应答信号(应答后中断挂起位自动置位)*/
    while(!(I2C5.I2CCON & (1<<4)));

    /*清除中断挂起标志位 重新开始一次通信 改变数据传送方向*/
    I2C5.I2CCON = I2C5.I2CCON & ~(1<<4);

    /*将第一个字节的数据写入发送寄存器 即从机地址和读写位(MPU6050-I2C地址+读位1)*/
    I2C5.I2CDS = slave_addr << 1 | 0x01;
    /*设置IIC为主机接收模式 发送起始信号 使能IIC收发*/
    I2C5.I2CSTAT = 0xb0;
    /*等待从机接收到数据后应答*/
    while(!(I2C5.I2CCON & (1<<4)));

    /*禁止主机应答信号(即开启非应答 因为只接收一个字节) 清除中断标志位*/
    I2C5.I2CCON = I2C5.I2CCON & ~(1<<7) & ~(1<<4);
      /*等待接收从机发来的数据*/
    while(!(I2C5.I2CCON & (1<<4)));
    /*将从机发来的数据读取*/
    data = I2C5.I2CDS;

    /*直接发起停止信号结束本次通信*/
    I2C5.I2CSTAT = 0x90;
    /*清除中断挂起标志位*/
    I2C5.I2CCON = I2C5.I2CCON & ~(1<<4);
    /*延时等待停止信号稳定*/
    mydelay_ns(10);

    return data;
}
void MPU6050_Init ()
{
    iic_write(SlaveAddress, PWR_MGMT_1, 0x00);    //设置使用内部时钟8M
    iic_write(SlaveAddress, SMPLRT_DIV, 0x07);    //设置陀螺仪采样率
    iic_write(SlaveAddress, CONFIG, 0x06);        //设置数字低通滤波器
    iic_write(SlaveAddress, GYRO_CONFIG, 0x18);   //设置陀螺仪量程+-2000度/s
    iic_write(SlaveAddress, ACCEL_CONFIG, 0x0);   //设置加速度量程+-2g
}

主函数

int main()
{
    unsigned char zvalue_h,zvalue_l;                  //存储读取结果
    short int zvalue;

    /*设置GPB_2引脚和GPB_3引脚功能为I2C传输引脚*/
    GPB.CON = (GPB.CON & ~(0xF<<12)) | 0x3<<12;      //设置GPB_3引脚功能为I2C_5_SCL
    GPB.CON = (GPB.CON & ~(0xF<<8)) | 0x3<<8;        //设置GPB_2引脚功能为I2C_5_SDA

    //uart_init();                                    //初始化串口
    MPU6050_Init();                                  //初始化MPU6050

    printf("\n********** I2C test!! **********\n");
    while(1)
    {
        zvalue_h = iic_read(SlaveAddress, GYRO_ZOUT_H);  //获取MPU6050-Z轴角速度高字节
        zvalue_l = iic_read(SlaveAddress, GYRO_ZOUT_L);  //获取MPU6050-Z轴角速度低字节
        zvalue = (zvalue_h<<8)|zvalue_l;                 //获取MPU6050-Z轴角速度

        printf(" GYRO-Z :Hex: %d \n", zvalue);           //打印MPU6050-Z轴角速度
        mydelay_ms(100);
    }
    return 0;
}

SPI

总线简介

特性 说明 背景与应用
定义 SPI(Serial Peripheral Interface),即串行外设接口 由摩托罗拉公司推出,是一种高速、全双工、同步的串行通信总线标准
通信模式 主从方式工作,通常有一个主设备和一个或多个从设备 主设备通过时钟和片选信号控制从设备,实现一对一或一对多的设备通信
硬件引脚 至少 4 根线:MISO(主入从出)、MOSI(主出从入)、SCLK(时钟)、CS(片选) 引脚数量少,布线方便,适合高密度电路设计
性能优势 高速、全双工、同步 广泛应用于需要高速数据传输的场景,如闪存存储(如 SPI Flash)、传感器(如 AD 采集芯片)、显示模块(如 OLED 屏幕)等

SPI 总线凭借高速、全双工的特性,在嵌入式系统、消费电子等领域被大量采用,例如单片机与高速 AD 芯片的通信、智能手表中闪存的读写等场景,都依赖 SPI 的高效数据传输能力。
在这里插入图片描述

SPI 总线通信过程

特性 说明 技术意义
数据位序 先传送高位,后传送低位;数据线高电平表示逻辑‘1’,低电平表示逻辑‘0’ 统一数据传输的位序规范,确保主从设备对数据的解析一致
应答机制 一个字节传送完成后无需应答,可直接开始下一个字节传送 简化通信流程,提升数据传输效率,适用于高速场景
同步时序 时钟线在上升沿 / 下降沿发送数据,紧接着的下降沿 / 上升沿读取数据;8 个时钟周期完成 1 字节传输 实现主从设备的严格时序同步,保障高速全双工通信的可靠性(如 SPI Flash 的高速读写)

SPI 的通信过程设计,使其在高速数据传输场景中极具优势,例如单片机与高速图像传感器、工业级 AD/DA 芯片的通信,均依赖其 “无应答、同步时序、高位优先” 的特性实现高效数据交互。
在这里插入图片描述

SPI 总线的极性(CPOL)与相位(CPHA)

参数 定义 取值与说明
极性(CPOL) 表示 SCLK 空闲时的电平状态 - CPOL=0:空闲时 SCLK 为低电平- CPOL=1:空闲时 SCLK 为高电平
相位(CPHA) 表示数据采样的时刻 - CPHA=0:每个时钟周期的第一个时钟沿采样- CPHA=1:每个时钟周期的第二个时钟沿采样
工作模式 由 CPOL 和 CPHA 组合决定,共 4 种模式 需与从设备的时序要求严格匹配,否则会导致数据传输错误

SPI 的极性和相位是实现主从设备时序同步的核心配置,例如与 SPI Flash 通信时,需确认芯片手册中规定的 CPOL/CPHA 模式(如常见的模式 0:CPOL=0、CPHA=0),才能保障数据的正确读写。

要点 说明 工程意义
从设备的模式特性 特定从设备出厂时被设计为某一种固定工作模式(由 CPOL 和 CPHA 组合决定) 从设备的硬件时序不可修改,需主设备适配其模式
主从模式的一致性 主设备的工作模式必须与从设备保持一致 若模式不匹配,数据采样和发送的时序会错位,导致通信失败
主设备的配置操作 使用从设备时,需对主设备的 CPOL 和 CPHA 进行配置 确保主从设备的时钟极性、采样时刻完全同步,保障数据传输的可靠性

在实际工程中,例如使用 SPI 接口的 OLED 屏幕或传感器时,必须查阅其芯片手册确认默认工作模式(CPOL/CPHA 取值),再配置主设备(如单片机)的 SPI 控制器与之匹配,否则会出现 “能通信但数据乱码” 的问题。

IIC 与 SPI 的异同对比

维度 IIC SPI
相同点 - 均采用串行、同步的通信方式- 均采用 TTL 电平,传输距离和应用场景类似- 均采用主从方式工作
不同点 - 半双工通信(同一时间仅能收或发)- 有应答机制(接收方需回复应答位确认数据)- 通过广播从机地址寻址(总线共享,多从机时需地址匹配)- 时钟极性和相位固定 - 全双工通信(可同时收发数据)- 无应答机制(数据传输后无需确认)- 通过片选(CS)信号寻址(每个从机独立片选,一对一控制)- 时钟极性(CPOL)和相位(CPHA)可配置(支持 4 种工作模式)

这种差异决定了二者的适用场景:IIC 适合多从机、低速率的场景(如传感器组网);SPI 适合高速、全双工的场景(如高速存储、显示模块)。

I2C 和 SPI 的通信速度核心差异:SPI 普遍比 I2C 快,且 SPI 速度上限更高、灵活性更强。

一、I2C 的通信速度

  • 标准模式:100 kbps(最基础常用,兼容性强)。
  • 快速模式:400 kbps(主流提升档,满足多数中速需求)。
  • 高速模式:3.4 Mbps(部分高端器件支持,需专用硬件)。
  • 超高速模式:5 Mbps(极少数场景使用,依赖特殊协议)。
  • 关键限制:受总线电容、线材长度影响大,长距离传输时速度会明显下降。

二、SPI 的通信速度

  • 速度范围:通常为 1 Mbps~50 Mbps,部分高性能器件可达到 100 Mbps 以上。
  • 核心特点:速度由主机时钟(SCLK)决定,只要器件支持,可灵活调整时钟频率。
  • 关键优势:无总线电容严格限制,短距离传输时能稳定维持高速,且全双工通信不影响速度发挥。

三、核心对比总结

特性 I2C SPI
速度上限 最高 5 Mbps(超高速) 常见 50 Mbps,最高超 100 Mbps
实际常用速度 100 kbps~400 kbps 10 Mbps~20 Mbps(主流场景)
速度影响因素 总线电容、线材长度 器件规格、时钟频率
式:3.4 Mbps(部分高端器件支持,需专用硬件)。
  • 超高速模式:5 Mbps(极少数场景使用,依赖特殊协议)。
  • 关键限制:受总线电容、线材长度影响大,长距离传输时速度会明显下降。

二、SPI 的通信速度

  • 速度范围:通常为 1 Mbps~50 Mbps,部分高性能器件可达到 100 Mbps 以上。
  • 核心特点:速度由主机时钟(SCLK)决定,只要器件支持,可灵活调整时钟频率。
  • 关键优势:无总线电容严格限制,短距离传输时能稳定维持高速,且全双工通信不影响速度发挥。

三、核心对比总结

特性 I2C SPI
速度上限 最高 5 Mbps(超高速) 常见 50 Mbps,最高超 100 Mbps
实际常用速度 100 kbps~400 kbps 10 Mbps~20 Mbps(主流场景)
速度影响因素 总线电容、线材长度 器件规格、时钟频率
Logo

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

更多推荐