前馈神经网络入门:从正向传播到反向传播的完整图解
2026/10/2 9:09:16
今天解决:没应答怎么办?SDA 卡在低电平怎么救?
每传 1 字节后的第 9 个时钟:
| 谁 | 含义 |
|---|---|
| 从机 ACK(低) | 收到了 |
| 主机读完 NACK(高) | 再不读了,准备结束 |
| 现象 | 可能原因 |
|---|---|
| 地址就没应答 | 地址错(注意 7 位 vs 含 R/W 的写法)、没接好、没上拉 |
| 传一半 NACK | 从机忙、数据不对 |
| SDA 一直为低 | 从机当时正在发数据被强行打断,卡住总线 |
从机把 SDA 拉死时,主机可以:
#include"stm32f4xx.h"#include<stdbool.h>/* 简化:手动 SCL 时钟 + 恢复(脚位按板子改) */staticvoidscl_pulse(void){GPIO_SetBits(GPIOB,GPIO_Pin_6);for(volatileinti=0;i<50;i++){}GPIO_ResetBits(GPIOB,GPIO_Pin_6);for(volatileinti=0;i<50;i++){}}voidi2c_bus_recover(void){inti;/* 假设已把 SDA/SCL 切到 GPIO 开漏输出 */for(i=0;i<9;i++){scl_pulse();}/* 再造一个 STOP:SCL 高时 SDA 上升(示意) */GPIO_ResetBits(GPIOB,GPIO_Pin_7);for(volatileintk=0;k<50;k++){}GPIO_SetBits(GPIOB,GPIO_Pin_6);for(volatileintk=0;k<50;k++){}GPIO_SetBits(GPIOB,GPIO_Pin_7);/* STOP */}带超时的“等待应答”思路:
boolwait_flag_timeout(volatileuint32_t*flag,uint32_tms_max){uint32_tn=ms_max*1000u;while(n--){if(*flag){returntrue;}}returnfalse;/* 超时,走恢复/报错 */}| 误区 | 正解 |
|---|---|
| 读完还发 ACK | 应 NACK 再 STOP |
| 失败就 while 死等 | 必须超时 |
| 恢复只重新 init 不拉时钟 | 从机可能仍占着 SDA |
| 地址 8 位当 7 位用 | 写法混用会找不到设备 |
作者:shuifanyu
标签:I2CACK总线恢复