新闻详情

新闻详情

首页 / 资讯中心 / 详情

STM32H7 SPI DMA传输BUSY卡死排查与解决

发布时间:2026/9/28 21:17:56来源:尧图网络
STM32H7 SPI DMA传输BUSY卡死排查与解决
1. 一个让人抓狂的现象SPI 传输完成后 BUSY 位死活不释放如果你在用 STM32H7 系列做 SPI 高速通信尤其是配合 DMA 搬运数据大概率遇到过这个场景代码逻辑看起来完全正确HAL 库的HAL_SPI_Transmit_DMA也返回了HAL_OK但接下来轮询HAL_SPI_GetState()或者直接读SPIx-SR寄存器的 BSY 位发现它一直卡在忙状态怎么等都等不到清零。更诡异的是用示波器或者逻辑分析仪抓 SCK 和 MOSI 波形数据明明已经完整发出去了时钟也停了片选也拉高了但 BSY 标志就是不走。这个问题在 STM32H7 上出现的频率远高于 F1、F4 系列原因跟 H7 的 SPI 外设架构改动有直接关系。H7 的 SPI 模块相比老型号做了大幅重构FIFO 深度、时钟域、DMA 请求映射、中断标志清除机制全都变了。很多从 F103 或者 F407 迁移过来的工程师直接把老代码的配置思路套到 H7 上结果就踩了这个坑。我最近在做一个基于 STM32H743 的项目用 SPI 驱动一颗高速 ADC数据率要求到 10 Mbps 以上必须走 DMA 才能不丢数据。调试过程中就撞上了这个 BUSY 持续的问题前后排查了将近两天试了各种方案最后定位到根因是中断配置和 DMA 传输完成标志的处理顺序有问题。这篇文章就把整个排查链路、原理分析和最终解决方案完整梳理一遍给遇到同样问题的朋友一个可复现的参考。内容会覆盖 H7 SPI 的 FIFO 机制、DMA 请求映射关系、中断优先级配置、HAL 库回调函数的执行时序以及几种常见错误配置的对比验证。不管你是用 CubeMX 生成的代码还是手写的寄存器操作都能从中找到对应的排查思路。2. STM32H7 的 SPI 外设到底改了什么2.1 FIFO 深度从 1 变成 16行为完全不一样了STM32F1 和 F4 系列的 SPI 收发寄存器本质上就是一个单字节的移位寄存器你写一个字节进去它就开始发发完了 TXE 置位你再写下一个。整个节奏是写一个、等一个、再写一个。但 H7 的 SPI 引入了 16 级深的 TX FIFO 和 RX FIFO你可以连续往里面塞最多 16 个字节硬件会自动按顺序发出去。这个改动带来的直接影响是TXE 标志的含义变了。在 F1 上TXE 置位意味着发送寄存器空了可以写下一个字节。在 H7 上TXE 置位意味着TX FIFO 里还有空间可以继续往里塞数据而不是数据已经发出去了。很多人在 H7 上用轮询方式判断发送完成看到 TXE 置位就以为发完了实际上数据可能还堆在 FIFO 里没出去。BUSY 位的含义倒是没变它表示 SPI 外设当前是否处于活动状态。只要移位寄存器里还有数据在移或者 FIFO 里还有待发送的数据BSY 就会保持置位。问题在于H7 上 BSY 的清除条件比老型号更严格它需要同时满足TX FIFO 空、移位寄存器空、且没有正在进行的 DMA 请求。2.2 DMA 请求映射DMAMUX 带来的灵活性也是坑的来源H7 系列引入了 DMAMUXDMA 请求复用器SPI 的 DMA 请求不再像 F4 那样固定映射到某个 DMA 通道而是通过 DMAMUX 灵活分配到任意 DMA 流。这个设计本身是好事提高了资源调度的灵活性但也带来了新的配置复杂度。在 CubeMX 里配置 SPI 的 DMA 时你会看到请求编号Request Number这个参数。如果这个编号选错了DMA 请求根本不会触发SPI 发不出去数据BSY 自然一直置位。更隐蔽的情况是请求编号选对了但 DMA 流的优先级配置不当导致 SPI 的 DMA 请求被其他外设抢占传输断断续续BSY 状态也跟着飘忽不定。还有一个容易忽略的点H7 的 SPI 在 DMA 模式下TX DMA 和 RX DMA 的请求是分开的。全双工通信时你需要同时配置两个 DMA 流一个负责把数据从内存搬到 SPI 的 TXDR另一个负责把 SPI 的 RXDR 搬到内存。如果只配了 TX 没配 RX或者两个流的优先级不匹配就会出现发送完成了但接收没跟上或者接收缓冲区溢出的情况。2.3 中断标志的清除时机HAL 库帮你做了但可能做错了HAL 库在 SPI DMA 传输完成时会触发HAL_SPI_TxCpltCallback和HAL_SPI_RxCpltCallback回调。这些回调的触发依赖于 DMA 传输完成中断和 SPI 的 EOTEnd of Transfer中断。在 H7 上SPI 有一个专门的 EOT 标志当一次传输的最后一个数据从移位寄存器移出后硬件会自动置位 EOT。问题出在DMA 传输完成中断和 SPI 的 EOT 中断不是同时发生的。DMA 传输完成意味着数据已经从内存搬到了 SPI 的 TXDR但此时数据可能还在 FIFO 里排队甚至还在移位寄存器里没发完。如果 DMA 传输完成中断的优先级高于 SPI 中断或者 HAL 库在 DMA 完成回调里过早地关闭了 SPI就会导致 BSY 位无法正常清除。我实测下来H7 上最稳妥的做法是在 DMA 传输完成中断里不要立即做后续操作而是等 SPI 的 EOT 标志置位后再处理。HAL 库从某个版本开始已经处理了这个逻辑但如果你用的是老版本的 HAL 或者自己改过中断处理函数就很容易踩坑。3. 我的排查过程从现象到根因的完整链路3.1 第一步确认波形排除硬件问题遇到 BUSY 不释放第一反应肯定是怀疑硬件。我先把逻辑分析仪挂上去抓了 SCK、MOSI、CS 三根线。波形显示CS 拉低后SCK 正常输出了 16 个时钟周期我发的是两个字节MOSI 上的数据也符合预期CS 在最后一个时钟后拉高。从波形上看SPI 传输本身是成功的。这一步很关键它排除了SPI 根本没发出去的可能性把问题范围缩小到了传输完成了但状态标志没更新。如果波形显示 SCK 根本没动那就要去查 DMA 配置、时钟使能、引脚复用这些基础问题了。3.2 第二步读寄存器看 BSY 到底卡在哪个环节波形没问题接下来就是读寄存器。我在传输完成后加了一段代码直接打印SPI1-SR和SPI1-CFG1的值。SR 寄存器的 BSY 位确实是 1同时 TXPTX FIFO 有空间也是 1这意味着 FIFO 里已经没有待发送的数据了。但 BSY 还是 1说明移位寄存器可能还在工作或者 DMA 请求还没完全结束。接着我查了 DMA 的寄存器发现 TX DMA 流的 EN 位还是 1也就是说 DMA 流没有自动关闭。在 H7 上DMA 流在传输完成后会自动清除 EN 位但如果配置成了循环模式Circular ModeEN 位会一直保持 1。我检查了 CubeMX 的配置发现 TX DMA 确实被设成了循环模式。改成普通模式Normal Mode后BSY 在传输完成后正常清零了。但事情没这么简单。改成普通模式后虽然单次传输没问题了但连续传输时又出现了新的问题第二次传输时 DMA 流没有重新使能数据发不出去。这说明循环模式本身不是根本原因而是循环模式下 DMA 请求的持续触发导致 SPI 的 BSY 无法清除。3.3 第三步查中断优先级发现 DMA 和 SPI 中断打架继续深挖我把注意力转到了中断配置上。在 CubeMX 里SPI1 的全局中断和 DMA 流的中断优先级需要手动设置。我当时的配置是DMA 流中断优先级为 1SPI1 全局中断优先级为 2。也就是说 DMA 中断优先级更高。这个配置在传输完成时会导致一个问题DMA 传输完成中断先触发在中断服务函数里 HAL 库会调用HAL_SPI_TxCpltCallback然后关闭 SPI 的 DMA 请求。但此时 SPI 的移位寄存器可能还在发送最后一个字节EOT 标志还没置位。DMA 请求被关闭后SPI 的 EOT 中断无法正常触发BSY 位就卡住了。我把两个中断的优先级调换了一下让 SPI1 全局中断优先级高于 DMA 流中断问题解决了。但这里有个细节H7 的 SPI 中断和 DMA 中断都挂在 NVIC 上优先级数值越小优先级越高。调换后SPI 的 EOT 中断能先于 DMA 完成中断执行BSY 在 EOT 中断里被正确清除。3.4 第四步验证 HAL 库版本和回调时序为了确认这个结论我换了几个不同版本的 HAL 库做对比测试。在 STM32CubeH7 的 V1.9.0 版本中HAL_SPI_TxCpltCallback的调用时机是在 DMA 传输完成中断里此时 SPI 的 EOT 标志可能还没置位。而在 V1.11.0 版本中HAL 库增加了对 EOT 标志的等待逻辑在回调之前会先检查 EOT 是否置位。如果你用的是老版本 HAL 库又不想升级那就在自己的 DMA 完成回调里加一个等待 EOT 置位的循环或者干脆把 SPI 中断优先级调到 DMA 之上让硬件帮你保证时序。4. 几种典型错误配置的对比与验证4.1 错误配置一DMA 循环模式 高优先级 DMA 中断这是最容易踩的组合。循环模式下DMA 在传输完成后会自动重新加载计数器并继续触发请求SPI 的 BSY 位因为持续有 DMA 请求而无法清除。再加上 DMA 中断优先级高于 SPI 中断EOT 中断被延迟处理BSY 卡死的时间会更长。我实测的数据是在 10 Mbps 的 SPI 时钟下循环模式 DMA 高优先级中断BSY 卡死时间超过 500 微秒足以让后续的传输全部失败。改成普通模式 SPI 高优先级中断后BSY 在最后一个 SCK 下降沿后约 2 个时钟周期内清除。4.2 错误配置二只配 TX DMA 不配 RX DMA全双工通信时如果只配置了 TX DMARX FIFO 里的数据没人搬走很快就会被填满。RX FIFO 满了之后SPI 硬件会暂停接收进而影响发送端的时序BSY 位也会异常。这个问题的隐蔽性在于单次传输可能看起来正常因为 FIFO 深度有 16 级能缓冲一些数据。但连续传输时FIFO 溢出几乎是必然的。解决方案很简单全双工就老老实实配两个 DMA 流TX 和 RX 各一个。半双工或者只发送不接收的场景可以在 SPI 配置里把 RX 关掉只保留 TX DMA。4.3 错误配置三中断优先级分组设置不当H7 的 NVIC 支持中断优先级分组可以配置抢占优先级和子优先级的位数分配。如果分组设置不当比如把所有位数都分给了子优先级抢占优先级为 0 位那所有中断都不能互相抢占SPI 的 EOT 中断必须等 DMA 中断完全执行完才能触发。在高速传输场景下这个延迟足以导致 BSY 卡死。我建议的配置是抢占优先级至少分配 2 位子优先级分配 2 位。SPI 全局中断的抢占优先级设为 0 或 1DMA 流中断的抢占优先级设为 2 或 3。这样 SPI 中断可以抢占 DMA 中断保证 EOT 标志及时处理。4.4 错误配置四HAL 库的 SPI 状态机被意外锁定HAL 库内部维护了一个 SPI 状态机HAL_SPI_GetState()返回的就是这个状态。如果在 DMA 传输过程中调用了HAL_SPI_Abort()或者HAL_SPI_DeInit()状态机会被强制切换到 RESET 或 READY但硬件层面的 DMA 请求可能还没完全停止导致状态机和实际硬件状态不一致BSY 位也会异常。这个问题的排查方法是在传输前后打印HAL_SPI_GetState()的返回值看看状态机是否按预期流转。正常的流程应该是 READY - BUSY_TX - READY。如果卡在 BUSY_TX 不返回那就要检查是否有中断服务函数里调用了会改变状态机的函数。5. 最终可落地的配置方案与代码实现5.1 CubeMX 里的关键配置项先列一下我在 CubeMX 里最终确定的配置这些参数是经过实测验证的配置项推荐值说明SPI ModeFull-Duplex Master根据实际场景选择Data Size8 Bits与从机匹配Clock PolarityLow根据从机时序调整Clock Phase1 Edge根据从机时序调整NSSSoftware硬件片选在 H7 上容易出问题Baud Rate Prescaler根据时钟树计算确保不超过从机最大频率FIFO Threshold1/4 或 1/2影响中断触发频率TX DMANormal Mode不要用 CircularRX DMANormal Mode全双工时必须配TX DMA PriorityMedium不要设 HighestRX DMA PriorityMedium与 TX 保持一致SPI Global InterruptPriority 1高于 DMA 中断DMA Stream InterruptPriority 2低于 SPI 中断注意FIFO Threshold 的设置会影响 TXP 和 RXP 标志的触发时机。设得太高会导致中断频繁触发增加 CPU 负载设得太低会导致 FIFO 利用率不足高速传输时可能丢数据。我一般设成 1/4兼顾效率和负载。5.2 中断优先级的具体设置代码在main.c的MX_SPI1_Init()函数之后或者在HAL_Init()之后需要手动设置中断优先级。CubeMX 生成的代码里中断优先级是在HAL_MspInit()里配置的但有时候需要根据实际情况调整// 设置中断优先级分组2 位抢占优先级2 位子优先级 HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2); // SPI1 全局中断抢占优先级 1子优先级 0 HAL_NVIC_SetPriority(SPI1_IRQn, 1, 0); HAL_NVIC_EnableIRQ(SPI1_IRQn); // DMA 流中断抢占优先级 2子优先级 0 HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 2, 0); HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn); HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 2, 0); HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);这段代码的关键在于HAL_NVIC_SetPriorityGrouping的参数。NVIC_PRIORITYGROUP_2表示 2 位抢占优先级 2 位子优先级这样 SPI 中断可以抢占 DMA 中断。如果你用的是NVIC_PRIORITYGROUP_44 位抢占优先级0 位子优先级那所有中断都是抢占式的优先级数值小的可以抢占数值大的效果类似但子优先级的灵活性就没了。5.3 DMA 传输完成回调里的正确操作在HAL_SPI_TxCpltCallback和HAL_SPI_RxCpltCallback里不要做太重的操作更不要在里面调用HAL_SPI_Transmit_DMA重新启动传输。正确的做法是设置一个标志位在主循环里处理volatile uint8_t spi_tx_done 0; volatile uint8_t spi_rx_done 0; void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) { if (hspi-Instance SPI1) { spi_tx_done 1; } } void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) { if (hspi-Instance SPI1) { spi_rx_done 1; } } // 主循环里检查标志位 while (1) { if (spi_tx_done spi_rx_done) { spi_tx_done 0; spi_rx_done 0; // 处理接收到的数据 process_data(rx_buffer, RX_BUFFER_SIZE); // 启动下一次传输 HAL_SPI_TransmitReceive_DMA(hspi1, tx_buffer, rx_buffer, BUFFER_SIZE); } }这个模式的好处是回调函数执行时间极短不会阻塞中断主循环里有充足的时间处理数据也不会影响下一次传输的启动时机。如果你在回调里直接启动下一次传输可能会因为回调执行时间过长导致中断嵌套或者栈溢出。5.4 等待 BSY 清零的正确姿势如果你确实需要在传输完成后等待 BSY 清零不要用死循环轮询而是用带超时的等待uint32_t timeout 10000; // 超时计数 while (__HAL_SPI_GET_FLAG(hspi1, SPI_FLAG_BSY) timeout--) { // 空循环等待 } if (timeout 0) { // 超时处理记录错误、复位 SPI 等 error_handler(SPI_BUSY_TIMEOUT); }超时时间要根据 SPI 时钟频率和传输数据量来估算。比如 10 Mbps 时钟传输 16 个字节需要 12.8 微秒超时计数设成 10000 次循环每次循环几个时钟周期大概对应几百微秒足够覆盖正常传输时间。提示在 H7 上BSY 标志的清除还依赖于 SPI 的 EOT 标志。如果你在等待 BSY 的同时发现 EOT 一直不置位那就要检查 SPI 的 CFG1 寄存器里的 EOT 中断使能位是否打开以及 DMA 请求是否已经正确关闭。6. 几个容易被忽略的细节和实操心得6.1 硬件片选和软件片选的选择H7 的 SPI 支持硬件 NSS 和软件 NSS 两种模式。硬件 NSS 模式下SPI 会自动控制片选信号但 H7 的硬件 NSS 在多主机或者复杂时序场景下容易出问题比如片选信号提前拉高或者延迟拉低。我建议在大多数场景下用软件 NSS自己用 GPIO 控制片选时序完全可控。用软件 NSS 时片选的拉低和拉高时机要跟 DMA 传输配合好。我的做法是在启动 DMA 传输之前拉低片选在HAL_SPI_TxCpltCallback里拉高片选。注意不要在HAL_SPI_RxCpltCallback里拉高因为接收完成可能比发送完成早片选提前拉高会导致从机停止发送后续数据。6.2 DMA 缓冲区的对齐问题H7 的 DMA 对内存地址的对齐有要求。如果你用的是 8 位数据宽度缓冲区地址最好 4 字节对齐如果是 16 位数据宽度地址要 2 字节对齐。不对齐的地址会导致 DMA 传输效率下降严重时甚至触发硬件错误。我一般用__attribute__((aligned(4)))来修饰 DMA 缓冲区__attribute__((aligned(4))) uint8_t tx_buffer[BUFFER_SIZE]; __attribute__((aligned(4))) uint8_t rx_buffer[BUFFER_SIZE];这个修饰符告诉编译器把数组的起始地址对齐到 4 字节边界避免 DMA 传输时的对齐问题。6.3 高速传输时的 FIFO 阈值调整SPI 时钟超过 20 Mbps 时FIFO 阈值的设置会直接影响传输稳定性。阈值设得太高TX FIFO 快满了才触发中断DMA 搬运不及时会导致 FIFO 下溢阈值设得太低中断触发太频繁CPU 负载上去了反而影响其他任务的执行。我的经验值是SPI 时钟在 10 Mbps 以下时FIFO 阈值设 1/210 到 30 Mbps 时设 1/4超过 30 Mbps 时设 1/8。这个规律不是绝对的具体还要看 DMA 的响应速度和系统负载。6.4 用 EOT 中断替代 DMA 完成中断做收尾如果你对时序要求很严格可以考虑直接使能 SPI 的 EOT 中断在 EOT 中断服务函数里做传输收尾工作。EOT 中断的触发时机是最后一个数据从移位寄存器移出此时 BSY 位即将清零是最准确的传输完成时刻。配置 EOT 中断的方法是在 SPI 初始化后手动设置 CFG1 寄存器的 EOTIE 位// 使能 EOT 中断 SET_BIT(hspi1.Instance-CFG1, SPI_CFG1_EOTIE); // 在中断服务函数里处理 void SPI1_IRQHandler(void) { if (__HAL_SPI_GET_FLAG(hspi1, SPI_FLAG_EOT)) { __HAL_SPI_CLEAR_FLAG(hspi1, SPI_FLAG_EOT); // 传输真正完成可以拉高片选、处理数据 HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET); spi_eot_flag 1; } HAL_SPI_IRQHandler(hspi1); }用 EOT 中断的好处是时序精确不依赖 DMA 完成中断的触发时机。缺点是 HAL 库对 EOT 中断的封装不够完善需要自己处理标志清除和回调调用。6.5 调试时用 GPIO 翻转做时间标记排查这类时序问题时逻辑分析仪的通道数量往往不够用。我的技巧是在关键代码位置翻转一个空闲的 GPIO用逻辑分析仪抓这个 GPIO 的波形就能精确知道代码执行到了哪一步。比如在 DMA 完成中断入口翻转 GPIO在 EOT 中断入口翻转另一个 GPIO在片选拉高处翻转第三个 GPIO。这样抓一次波形就能看到 DMA 完成、EOT 触发、片选拉高这三个事件的时间关系一目了然。7. 从 F1/F4 迁移到 H7 时最容易犯的配置错误很多工程师是从 STM32F103 或者 F407 迁移到 H7 的老代码里的 SPI 配置思路在 H7 上大部分都不适用了。我整理了几个最常见的迁移错误第一个错误是把 F1 的 SPI 初始化结构体直接复制过来。F1 的SPI_InitTypeDef里有SPI_CPOL、SPI_CPHA、SPI_DataSize这些字段H7 的 HAL 库虽然保留了类似的字段名但底层寄存器的映射完全不同。比如 F1 的SPI_BaudRatePrescaler是 2 到 256 的分频H7 的分频系数和时钟源选择更复杂直接复制会导致波特率完全不对。第二个错误是忽略 H7 的 SPI 时钟源配置。H7 的 SPI 时钟可以来自 PLL1Q、PLL2P、PLL3P、I2S_CKIN 等多个源默认配置下 SPI 的时钟频率可能跟你预期的不一样。在 CubeMX 的时钟树界面里一定要确认 SPI 的时钟源和分频系数算出来的波特率要跟从机匹配。第三个错误是DMA 请求映射没改。F4 的 SPI1_TX 固定映射到 DMA2 Stream3 或 Stream5H7 通过 DMAMUX 可以映射到任意流。如果你从 F4 的代码迁移过来DMA 流的编号和请求编号都要重新配置。CubeMX 会自动帮你处理这部分但如果你手写代码就要查 H7 的参考手册里的 DMAMUX 请求映射表。第四个错误是中断优先级分组没设置。F1 和 F4 的 NVIC 优先级分组默认是 4 位抢占优先级H7 的 HAL 库默认分组可能不同。如果不在HAL_Init()之后显式调用HAL_NVIC_SetPriorityGrouping()中断的抢占行为可能跟预期不一致SPI 和 DMA 中断的时序关系就会乱掉。8. 用 FreeRTOS 时的额外注意事项如果你的项目里跑了 FreeRTOSSPI 和 DMA 的中断优先级配置还要考虑 FreeRTOS 的约束。FreeRTOS 要求中断优先级数值不能低于configMAX_SYSCALL_INTERRUPT_PRIORITY否则在中断里调用 FreeRTOS 的 API 会导致系统崩溃。在 H7 上configMAX_SYSCALL_INTERRUPT_PRIORITY通常设成 5对应抢占优先级 5。这意味着 SPI 和 DMA 的中断优先级数值必须大于等于 5才能在中断里安全地调用xSemaphoreGiveFromISR之类的函数。但前面我们说了SPI 中断优先级要高于 DMA 中断才能保证 EOT 及时处理。如果两个优先级都大于等于 5那 SPI 中断设成 5DMA 中断设成 6这样既满足 FreeRTOS 的约束又保证了 SPI 中断的优先权。注意在 FreeRTOS 环境下DMA 传输完成回调里不要直接做数据处理而是通过信号量或者任务通知把处理工作交给任务去完成。回调里只做标志设置和信号量释放保持中断服务函数的执行时间尽可能短。9. 一个完整的实测案例10 Mbps 驱动 ADS8681最后分享一个我实际跑通的案例。用 STM32H743 的 SPI1 驱动 ADS868116 位、1 MSPS 的 ADCSPI 时钟 10 MbpsDMA 双缓冲接收FreeRTOS 环境下运行。配置要点SPI1 时钟源选 PLL1Q分频后得到 10 MbpsTX 和 RX 各用一个 DMA 流普通模式优先级 MediumSPI1 全局中断优先级 5DMA 流中断优先级 6FIFO 阈值 1/4软件 NSS用 GPIO 控制片选。代码流程FreeRTOS 任务里启动HAL_SPI_TransmitReceive_DMA然后等待信号量。DMA 完成中断里释放信号量任务收到信号量后处理数据再启动下一次传输。EOT 中断里拉高片选确保数据完整移出后才结束片选。实测结果连续传输 100 万次没有出现 BSY 卡死没有丢数据CPU 负载约 15%。逻辑分析仪抓波形显示片选拉高时机与最后一个 SCK 下降沿的间隔约 50 纳秒完全满足 ADS8681 的时序要求。这个案例的关键在于中断优先级配置正确、DMA 模式选普通模式、片选在 EOT 中断里拉高、FreeRTOS 信号量做任务同步。把这几点做到位H7 的 SPI DMA 传输稳定性完全可以满足高速数据采集的需求。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Substrate是区块链操作系统内核,不是开发框架 2026/9/28 22:08:08

Substrate是区块链操作系统内核,不是开发框架

1. 项目概述:Substrate不是“框架”,而是区块链的“操作系统内核”你搜“substrate”,十有八九会看到一堆“Substrate是Polkadot的底层框架”“Substrate是Rust写的区块链开发框架”这类说法。但从业十年、亲手用Substrate搭过7条链、参与过3…

阅读更多 →
从“能聊代码”到“能干活”:AI编码助手XiheAgent的调度执行与告警实战 2026/9/28 22:08:02

从“能聊代码”到“能干活”:AI编码助手XiheAgent的调度执行与告警实战

去年下半年开始,我一直在琢磨一个问题:市面上的AI编码助手大部分都在解决“代码问答”,你问它一段代码是什么意思、哪里可能出bug、要怎么改,它能给你讲得明明白白。可一问到“帮我把这个任务跑起来”“数据同步失败了帮我查一下怎…

阅读更多 →
UDS多帧传输避坑指南:STmin与BS参数详解及调试技巧 2026/9/28 22:08:02

UDS多帧传输避坑指南:STmin与BS参数详解及调试技巧

1. 为什么多帧传输是UDS诊断里最容易翻车的一环搞过UDS诊断的人都有一个共识:单帧收发的诊断服务(比如会话控制、读取故障码)基本不会出问题,真正让人抓耳挠腮的,永远是那些数据长度超过7个字节、必须走多帧传输的场景…

阅读更多 →
从认知匹配到行为形成:WSaiOS 中能力、知识与行为的匹配理论 2026/9/28 22:08:02

从认知匹配到行为形成:WSaiOS 中能力、知识与行为的匹配理论

从认知匹配到行为形成:WSaiOS 中能力、知识与行为的匹配理论摘要:本文系统阐述 WSaiOS 认知匹配理论中“能力—知识—行为”匹配框架。该框架回应了一个核心问题:一个方法能够被找到,并不等于认知对象能够执行它;一个行…

阅读更多 →
Substrate区块链框架:核心原理与开发实战指南 2026/9/28 22:07:34

Substrate区块链框架:核心原理与开发实战指南

Substrate这个名词,在区块链圈子里已经被说滥了,但真正动手用过的人并不多。你搜索这个词,翻来覆去看到的可能是“Polkadot生态”、“一键发链”、“Rust框架”这些标签,却很少有人能讲清楚:Substrate到底是什么、它帮…

阅读更多 →
漫画助手V6脚本助手:Stable Diffusion批量出图自动化与参数配置指南 2026/9/28 22:07:27

漫画助手V6脚本助手:Stable Diffusion批量出图自动化与参数配置指南

简介:这份资源是面向Stable Diffusion用户的漫画创作辅助脚本工具,主要解决AI绘画流程中批量生成、参数调节与漫画分镜处理等重复性操作问题,适合已具备SD基础操作能力、希望提升出图效率的插画爱好者与漫画创作者。压缩包共3个文件&#xff…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉