SuperAPI AI 工具集

spi-i2c-baremetal

编程与开发

查看项目

更新于 10-15 15:31

技能介绍

SPI 与 I2C(裸机)

用途

为传感器和存储芯片实现 SPI 与 I2C 主模式驱动:时钟配置、相位/极性(SPI)、START/ACK 序列(I2C),以及常见的面向寄存器的读写事务模式。

适用场景

  • 读取 I2C 传感器(WHO_AM_I 寄存器)
  • SPI flash 或显示屏的点亮启动
  • 调试 NACK 或 SCL 卡死
  • 用最小代码替换 HAL_I2C/SPI

工作流程

  1. SPI 主模式(STM32)

模式 0:CPOL=0,CPHA=0 —— 需核对从机数据手册

SPI1->CR1 = SPI_CR1_MSTR | SPI_CR1_SSM | SPI_CR1_SSI | (3 << SPI_CR1_BR_Pos); /* 波特率分频 */ SPI1->CR1 |= SPI_CR1_SPE;

uint8_t spi_xfer(SPI_TypeDef *spi, uint8_t tx) { while (!(spi->SR & SPI_SR_TXE)) ; *(volatile uint8_t *)&spi->DR = tx; while (!(spi->SR & SPI_SR_RXNE)) ; return *(volatile uint8_t *)&spi->DR; }

CS(GPIO 位操作):

GPIO_CS_LOW(); spi_xfer(SPI1, reg | 0x80); /* 读 */ uint8_t val = spi_xfer(SPI1, 0xFF); GPIO_CS_HIGH();

  1. I2C 主模式——寄存器读取

START → 地址+写 → 寄存器 → 重复 START → 地址+读 → 数据 → STOP

bool i2c_read_reg(I2C_TypeDef *i2c, uint8_t dev7, uint8_t reg, uint8_t *out) { if (!i2c_start(i2c)) return false; if (!i2c_tx(i2c, (dev7 << 1) | 0)) return false; if (!i2c_tx(i2c, reg)) return false; if (!i2c_restart(i2c)) return false; if (!i2c_tx(i2c, (dev7 << 1) | 1)) return false; out = i2c_rx(i2c, false); / 最后一字节 NACK */ i2c_stop(i2c); return true; }

按参考手册轮询 SB、ADDR、TXE、RXNE、BTF 标志位。

  1. 常见协议

模式 | 总线

寄存器 + 写数据 | I2C/SPI

0x80 | reg 读取(最高位置 1) | SPI

16 位大端长度前缀 | SPI flash

  1. 智能体用法

/spi-i2c-baremetal I2C read of register 0x0F from device 0x68

常见问题

现象 | 原因 | 修复

I2C NACK | 7 位地址错误(数据手册写的是 8 位) | 地址移位;检查 R/W 位

SPI 数据异常 | CPOL/CPHA 不匹配 | 对照从机模式表

总线 SCL 被拉低卡死 | 从机时钟拉伸/故障 | 总线恢复(发送时钟脉冲)

CS 毛刺 | CS 时序与时钟不匹配 | 首个 SCK 前拉低 CS

相关技能

skills/baremetal/gpio-baremetal —— CS、SDA、SCL 引脚

skills/baremetal/peripherals-from-datasheet —— 时序要求

skills/kernel-dev/bus-drivers-i2c-spi —— Linux 内核侧

限制

以上内容基于所提供资料;关于其他平台的具体支持、完整代码实现、收费或授权方式,资料暂未提供。