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

SPI学习(QA)

硬件SPI+DMA驱动方式

SPI+DMA驱动方式最快

HAL_SPI_Transmit_DMA

HAL_SPI_Transmit_DMA函数调用后此函数快速返回(非阻塞),CPU 可立即执行其他任务。

uint8_t tx_buf[100] = {0x01, 0x02, ...}; // 提前准备好数据
HAL_SPI_Transmit_DMA(&hspi1, tx_buf, 100); // 启动DMA发送,立即返回

等待传输完成(可选,非阻塞)

传输完成后,DMA 会触发中断,HAL 库会调用回调函数

// DMA传输完成后,此回调函数会被中断触发
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) {if (hspi == &hspi1) {// 处理传输完成逻辑(如启动下一次发送)}
}

HAL_SPI_TxCpltCallback 通知 CPU。若需同步等待(不推荐,会浪费 CPU),可轮询 SPI 状态,但无需死等,可配合超时机制

// 不推荐:轮询等待(阻塞CPU)
while (HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY) {// 可添加超时判断,避免死等
}

为什么不需要死等?

DMA 独立工作:一旦启动,DMA 控制器会自动按配置从缓冲区取数据发送,CPU 无需参与,死等会浪费 CPU 资源。
缓冲区访问安全:启动 DMA 后,禁止修改缓冲区数据(DMA 可能正在读取),但 “写入缓冲区” 是在启动前完成的,启动后无需操作缓冲区,因此无需等待。
异常处理:若传输卡住,可通过 DMA 超时中断或轮询状态检测,而非死等。

硬件SPI

HAL_SPI_Transmit 和 HAL_SPI_Transmit_IT

HAL_SPI_Transmit 和 HAL_SPI_Transmit_IT 都是 STM32 HAL 库中用于 SPI 发送数据的函数,但核心区别在于 工作方式(同步阻塞 vs 异步中断)

  1. 工作方式
    HAL_SPI_Transmit:同步阻塞方式。函数调用后,CPU 会一直等待 SPI 外设完成所有数据的发送(逐字节发送,直到 Size 计数为 0),期间 CPU 无法执行其他任务,直到发送完成后函数才返回。
    HAL_SPI_Transmit_IT:异步中断方式。函数仅启动发送过程(配置参数、使能中断)后立即返回,后续发送过程由硬件中断驱动(无需 CPU 干预),发送完成后通过 HAL_SPI_TxCpltCallback 回调函数通知。

想都不用想,硬件SPI方式的话,HAL_SPI_Transmit_IT肯定是最好的,速度最快不堵塞

// 同步发送(阻塞)
HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);// 异步发送(中断)
HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);

差异点:HAL_SPI_Transmit 多了一个 Timeout 参数(超时时间,单位:ms),用于指定最大等待时间,超时未完成则返回 HAL_TIMEOUT。

特性HAL_SPI_Transmit(同步)HAL_SPI_Transmit_IT(异步)
CPU阻塞,直到发送完成非阻塞,启动后立即释放 CPU
完成通知函数返回即表示完成通过 HAL_SPI_TxCpltCallback 回调
超时机制支持 Timeout 参数无超时参数(需手动处理异常)
数据缓冲区访问发送期间可修改(但不建议)发送期间不可修改(中断可能访问)
代码复杂度低(线性逻辑)较高(需处理回调和状态同步)

HAL_SPI_Transmit_IT中断是发送完成后回调还是发送开始就回调?

HAL_SPI_TxCpltCallback 是 SPI 数据发送完成后 才会被调用的回调函数,并非发送开始时触发。
具体来说,当通过 HAL_SPI_Transmit_IT 启动异步发送后,SPI 外设会在后台通过中断逐字节发送数据,直到所有数据(即 Size 参数指定的长度)全部发送完毕,硬件会触发 “传输完成(TC)” 中断。此时,HAL 库的中断服务程序(ISR)会最终调用 HAL_SPI_TxCpltCallback,通知用户 “整个发送过程已完成”。
因此,该回调函数的触发时机是 发送操作彻底结束后,可以在此处执行发送完成后的后续逻辑(如释放缓冲区、启动下一次传输等)。

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

相关文章:

  • 怎么用数据仓库来进行数据治理?
  • Linux_6:FTP云盘项目
  • Spring Boot spring.factories文件详细说明
  • 网站seo文章免费asp地方门户网站系统
  • 《信息存储与管理》逻辑串讲
  • dify TTS部署 GPT-SoVITS
  • kotlin中SharedFlow的简单使用
  • Kotlin 中的 inline 和 reified 关键字
  • 开封府景点网站及移动端建设情况精品资源共享课网站建设 碧辉腾乐
  • 战场目标检测:Faster R-CNN与RegNetX-800MF融合实现建筑物人员坦克车辆识别_2
  • 易语言黑月编译器:提升编程效率与性能优化 | 深入解析易语言开发中的工具应用与技巧
  • Vibe Coding - 从Vibe Coding到Spec Coding_AI编码范式的进化之路
  • 宣化网站建设青岛网站制作推广平台
  • 【多模态大模型面经】 BERT 专题面经
  • Node.js 开发实战:从入门到精通
  • 草莓病害智能识别与分类_Cascade-RCNN_HRNetV2p-W18-20e_COCO实现
  • 改造多模块!!无法使用三方依赖的异常处理
  • JMeter 自动化实战:自动生成文件并传参接口的完整方案
  • AutoSAR实战:RTA-OS Counters操作系统计数器详解
  • FCAF3D: Fully Convolutional Anchor-Free 3D Object Detection论文精读
  • 北京市轨道交通建设管理有限公司网站企业网站建设合同书模板
  • 做图表的网站大连关键词
  • Vue 3中集成GIS(地理信息系统)
  • 进程基本概念
  • Java模拟算法题目练习
  • Mac远程控制新篇章:UU远程被控端深度测评
  • WordPress插件--菜单登录后可见的插件
  • 电商数据分析报告
  • Rust与主流编程语言客观对比:特性、场景与实践差异
  • C语言编译器有哪些 | 选择最适合的编译器提高开发效率