当前位置: 首页 > news >正文

嵌软面试——通信协议

一、UART/USART

Q1: UART的通信帧格式是怎样的?

  • 答案
    每帧数据包含:

    • 起始位(1位,低电平)

    • 数据位(5~9位,通常8位)

    • 校验位(可选,奇偶校验)

    • 停止位(1~2位,高电平)

    • 示例起始位(0) + 数据位(0x55) + 无校验 + 停止位(1)

Q2: 为什么UART是“异步”通信?

  • 答案

    • 无时钟线(SCL),依赖双方预设的波特率(Baud Rate)同步采样数据。

    • 每个数据帧通过起始位重新同步时序。

1. 同步(Synchronous)

  • 定义:任务按顺序执行,必须等待前一个任务完成后才能开始下一个任务。

  • 特点

    • 阻塞式:调用方必须等待被调用方的结果返回后才能继续执行。

    • 顺序性强:任务严格按照代码编写的顺序执行。

    • 简单直观:逻辑清晰,易于理解和调试。

  • 例子

    • 同步函数调用:函数A调用函数B,必须等B执行完毕并返回结果后,A才能继续。

    • 排队取餐:必须等前一个人取完餐,才能轮到你。

 

2. 异步(Asynchronous)

  • 定义:任务可以独立执行,调用方无需等待被调用方的结果,而是通过回调、事件或通知等方式在完成后处理结果。

  • 特点

    • 非阻塞式:调用方发起请求后可以继续执行其他任务,无需等待。

    • 并发性高:适合处理耗时操作(如网络请求、文件读写)。

    • 复杂度高:需要通过回调、Promise、async/await等机制处理结果。

  • 例子

    • 异步编程:JavaScript中的setTimeout、Ajax请求。

    • 点餐后拿号:下单后可以去做其他事,餐好了会通知你。

 它们的核心区别在于任务执行的顺序性和依赖性,以及是否需要等待

 

2. 硬件设计

Q3: UART最少需要几根线?电平标准有哪些?

  • 答案

    • 最少 2根线(TX发送、RX接收),全双工通信。

    • 电平标准

      • TTL UART:3.3V/5V(MCU直接使用)

      • RS232:±12V(长距离,需电平转换芯片如MAX232)

      • RS485:差分信号(抗干扰,多设备共享总线)

Q4: 如何实现UART的长距离通信(>1m)

  • 答案

    • 转换为RS485(差分信号,抗干扰,支持千米级传输)或光隔离(防高压干扰)。

3. 软件实现

Q5: UART如何检测数据传输错误?

  • 答案

    • 奇偶校验:检查数据位中“1”的个数是否符合奇/偶规则。

    • 帧错误:停止位未检测到高电平。

    • 溢出错误:接收缓冲区未及时读取,新数据覆盖旧数据。

Q6: UART接收数据时如何避免溢出?

  • 答案

    • 使用FIFODMA减少CPU中断负载。

    • 提高中断优先级,及时读取接收缓冲区(如STM32的HAL_UART_Receive_IT())。

Q7: 为什么调试日志常用UART而不用SPI/I2C?

  • 答案

    • UART连接简单(仅需TX/RX),无需时钟同步,适配大多数终端工具(如PuTTY)。

    • SPI/I2C需协议解析,适合设备间通信,不适合人机交互。

Q8: UART的波特率误差允许范围是多少?

  • 答案

    • 通常要求误差<3%(如9600bps时,实际波特率需在9312~9888bps之间)。

    • 误差过大会导致采样点偏移,数据错位。

Q9: USART和UART的区别是什么?

  • 答案

    • UART:纯异步(无时钟线)。

    • USART:可配置为同步模式(带SCLK时钟线)或异步模式(同UART)。

    • 同步模式:常用于高速通信或需要严格时序的场景(如SPI兼容模式)。

Q10: USART的同步模式下,时钟(SCLK)由谁提供?

  • 答案

    • 主设备提供时钟(类似SPI),从设备根据时钟边沿采样数据。

Q11: USART的硬件流控(Hardware Flow Control)是什么?

  • 答案

    • 通过RTS(Request to Send)CTS(Clear to Send)信号线控制数据流,防止缓冲区溢出。

    • 应用场景:高速通信(如GPS模块连续输出数据)。

Q12: 如何用USART模拟SPI?

  • 答案

    • 配置USART为同步主模式(SCLK输出),通过TX发送数据,RX接收数据(半双工SPI)。

Q13: 什么场景下会选择USART而非UART?

  • 答案

    • 需要同步通信(如驱动SPI设备但硬件SPI引脚不足)。

    • 需要硬件流控(如高速Modem通信)。

        

面试技巧

  • 举例说明
    “我在项目中用UART连接GPS模块(NMEA-0183协议),波特率9600,无校验位。遇到数据丢失后,发现是MCU中断优先级过低,改用DMA解决。”

  • 陷阱问题

    • “UART能实现多设备通信吗?”

      • 可以,但需软件协议(如MODBUS)或硬件切换(如多路复用器)。

    • “USART的同步模式和SPI有何区别?”

      • USART同步模式通常为半双工,SPI为全双工;SPI有CS片选信号,USART无。

二、IIC协议

1. 核心特性

  • 两根线

    • SCL(Serial Clock):时钟线,由主设备控制。

    • SDA(Serial Data):双向数据线。

  • 多主多从:支持多个主设备(通过仲裁机制避免冲突)。

  • 半双工:同一时刻只能发送或接收数据。

  • 地址寻址:每个从设备有唯一7位或10位地址。

2. 关键问题

Q1: I2C的起始(START)和停止(STOP)条件如何定义?

  • 答案

    • START:SCL高电平时,SDA从高→低跳变。

    • STOP:SCL高电平时,SDA从低→高跳变。

Q2: I2C的7位地址格式是怎样的?如何区分读/写操作?

  • 答案

    • 地址位(7位) + 读写位(1位):

      • 0:主设备写数据到从设备。

      • 1:主设备从从设备读数据。

    • 示例:地址0x68(7位:1101000)的写操作字节为 0xD0(11010000)。

Q3: 为什么I2C需要上拉电阻?阻值如何计算?

  • 答案

    • 原因:I2C设备为开漏输出(只能拉低,不能主动拉高),需外部电阻提供高电平。

    • 计算

      • 最小值:Rp(min) = (Vdd - Vol) / Iol(避免电流过大)。

      • 最大值:Rp(max) = tr / (0.8473 × Cbus)(满足上升时间)。

    • 典型值:3.3V系统常用3.3kΩ~4.7kΩ(标准模式100kHz)。

Q4: I2C总线电容过大会导致什么问题?如何解决?

  • 答案

    • 问题:信号上升时间变长,可能违反时序(如SCL频率高时采样错误)。

    • 解决

      1. 减小上拉电阻(但需注意驱动能力)。

      2. 使用I2C缓冲器(如PCA9515)隔离电容。

Q5: I2C如何实现多主设备仲裁?

  • 答案

    • 线与逻辑:所有主设备监听SDA,若发现自身发送的电平与总线实际电平不一致(即其他主设备拉低),则退出竞争。

    • 仲裁过程:从地址位开始比较,低电平优先。

Q6: I2C总线上拉电阻接3.3kΩ,但通信失败,可能原因?

  • 答案

    • 总线电容过大(如导线过长、设备过多),导致上升时间不足。

    • 从设备地址冲突或未响应。

    • 主设备未正确处理ACK/NACK。

Q7: I2C的完整数据传输流程是怎样的?

  • 答案

    1. 主设备发送START条件。

    2. 发送从设备地址 + 读写位。

    3. 从设备回复ACK(拉低SDA)。

    4. 传输数据(每字节后跟ACK/NACK)。

    5. 主设备发送STOP条件。

Q8: 如何用代码实现I2C的起始信号?

void I2C_Start() {SDA_High();  // SDA=1SCL_High();  // SCL=1Delay();SDA_Low();   // SDA=0 (START)Delay();SCL_Low();   // SCL=0
}

Q9: I2C从设备无ACK响应,如何排查?

  • 答案

    1. 检查从设备地址是否正确(示波器抓取地址字节)。

    2. 确认从设备供电和复位正常。

    3. 检查总线是否被意外拉低(如设备故障导致SDA锁死)。

Q10: I2C适合哪些场景?举例说明。

  • 答案

    • 低速、省引脚的设备:传感器(BME280)、EEPROM(AT24C02)、RTC(DS3231)。

    • 多设备共享总线:如一块PCB上挂载多个传感器。

Q11: I2C和SPI在驱动OLED时如何选择?

  • 答案

    • I2C:引脚少(仅2线),但速率低(通常≤400kHz),适合小屏或静态显示。

    • SPI:速率高(可达MHz级),适合刷新率高的动态显示。

Q12: I2C和UART谁更适合长距离通信?

  • 答案

    • UART+RS485:更适合长距离(差分信号抗干扰)。

    • I2C通常用于板内通信(<1m),长距离需加缓冲器。

Q13: “I2C总线上拉电阻用1kΩ行不行?

  • 答案

    • 需计算:若总线电容大(如100pF),1kΩ可能导致上升时间不足(标准模式要求tr≤1μs)。

Q14: “I2C可以热插拔吗?”

  • 答案

    • 不推荐!热插拔可能导致总线电平紊乱,需设计热插拔保护电路(如TI的I2C缓冲器)。

三、SPI协议

1. 核心特性

  • 全双工通信:数据同时收发(MOSI和MISO独立)。

  • 同步时钟:主设备控制SCLK,严格时序同步。

  • 四线制(标准SPI):

    • SCLK:时钟线(主→从)。

    • MOSI(Master Out Slave In):主设备发送,从设备接收。

    • MISO(Master In Slave Out):从设备发送,主设备接收。

    • CS/SS(Chip Select):片选信号(低电平有效,每个从设备独立一根)。

Q1: SPI的四种工作模式(CPOL/CPHA)是什么?如何选择?

  • 答案

    • CPOL(Clock Polarity):时钟空闲状态。

      • 0:SCLK空闲时为低电平。

      • 1:SCLK空闲时为高电平。

    • CPHA(Clock Phase):数据采样边沿。

      • 0:在SCLK的第一个边沿(上升或下降)采样。

      • 1:在SCLK的第二个边沿采样。

        

Q2: SPI是全双工还是半双工?为什么?

  • 答案

    • 全双工,因为MOSI和MISO可同时传输数据(主设备发送时,从设备也可回复)

Q3: SPI最多能接多少个设备?如何扩展?

  • 答案

    • 理论限制:受主设备CS引脚数量限制(通常MCU提供4~8个专用CS)。

    • 扩展方法

      1. 译码器扩展(如74HC138):用3个GPIO生成8个CS信号(2^N扩展)。

      2. 菊花链(Daisy Chain):所有从设备共享CS,数据级联(需设备支持,如某些ADC)。

      3. SPI切换器(如模拟开关ADG704):动态切换总线路径

Q4: SPI的片选信号(CS)可以共用吗?为什么?

  • 答案

    • 不能共用(除非菊花链模式),因为:

      • 所有从设备的MISO会冲突(多个输出短路)。

      • 主设备无法区分数据来源。

Q5: SPI长距离通信(>10cm)需要注意什么?

  • 答案

    • 降低SCLK频率(减少信号失真)。

    • 使用差分SPI(如LVDS)或加缓冲器(如SN74LVC4245)。

    • 缩短走线长度,避免平行布线(减少串扰)。

Q6: SPI的时钟频率如何设置?受什么因素限制?

  • 答案

    • 设置方法:通过主设备时钟分频(如STM32的SPI_BaudRatePrescaler)。

    • 限制因素

      1. 从设备支持的最高频率(如Flash芯片通常支持50MHz)。

      2. 总线电容(导线越长,最大频率越低)。

Q7: SPI通信时MISO无数据,如何排查?

  • 答案

    1. 检查CS信号是否已拉低(从设备未使能)。

    2. 确认时钟模式(CPOL/CPHA)匹配。

    3. 测量SCLK和MOSI波形(示波器抓取时序)。

Q8: 为什么Flash芯片常用SPI而不用I2C?

  • 答案

    • SPI速率远高于I2C(如W25Q128支持104MHz,I2C仅400kHz)。

    • Flash需频繁读写大数据块,SPI的全双工特性更高效。

Q9: “SPI可以没有MISO线吗?

  • 答案

    • 可以!如果仅需主设备发送数据(如驱动LED屏),可省略MISO(单工模式)。

Q10: “SPI的CS信号可以一直拉低吗?

  • 答案

    • 不建议!CS拉低期间从设备会持续消耗功率,且可能干扰其他设备。应在数据传输间隙释放CS。

http://www.dtcms.com/a/303428.html

相关文章:

  • 7.项目起步(1)
  • 1.vue体验
  • 快速构建基于React.js的用户注册与登录的Web应用程序
  • vue element 封装表单
  • 代码随想录算法训练营第三十三天
  • 7.28PBR技术
  • Linux系统编程——数据库
  • 介绍一下static关键字
  • Sum-rate计算
  • 【代码解读】通义万相最新视频生成模型 Wan 2.2 实现解析
  • 同态滤波算法详解:基于频域变换的光照不均匀校正
  • 栈算法之【用栈实现队列】
  • 凸优化:凸函数的一些常用性质
  • OpenLayers 综合案例-量测工具
  • 【Zustand】从复杂到简洁:Zustand 状态管理简化实战指南
  • 图解系统的学习笔记--硬件结构
  • 告别繁琐 Mapper!Stream-Query 正式入驻 GitCode 平台
  • GPFS文件系统更换磁盘
  • 企业级JWT验证最佳方案:StringUtils.hasText()
  • AD中放置过孔阵列
  • Python 异常 (Exception) 深度解析
  • 如何获取我当前的IP地址
  • 掌握 ArkTS 复杂数据绑定:从双向输入到多组件状态同步
  • AWS MemoryDB 可观测最佳实践
  • Python Pandas.merge_ordered函数解析与实战教程
  • 全球首个1米高精度特大城市开放空间数据集(Tif)
  • 力扣刷题977——有序数组的平方
  • 热门JavaScript库“is“等软件包遭npm供应链攻击植入后门
  • “菜鸟的java代码日记“ DAY3——跳跃游戏(中等)
  • DBAPI的SQL实现模糊查询的3种方案