uchar I2C_SendByte(uchar dat, uchar ack)函数其中与ack相关的部分是
while(I2C_SDA && (ack == 1))//等待应答,也就是等待从设备把I2C_SDA拉低
{
b++;
if(b > 200) ** //如果超过200us没有应答发送失败,或者为非应答,表示接收结束
**{
I2C_SCL = 0;
I2C_Delay10us();
return 0;
}
}
I2C_SCL = 0;
I2C_Delay10us();
在main中有
I2C_SendByte(0xa0, 1);//发送写器件地址
I2C_SendByte(addr, 1);//发送要写入内存地址
I2C_SendByte(dat, 0)_; //发送数据
为什么发送数据时 ack为0了不为1,以及这个ack代表什么意义,ack不是从机将sda下拉的信号吗?
while(I2C_SDA && (ack == 1)) 这里的含义是 根据传入的 ack 来决定是否需要 应答, I2C_SendByte(dat, 0)_; 传入的 参数是 0 , 就是不需要对方给应答 , 前面2条 指令需要对方应答 。
你说的是否是发送数据开始的时序电平,建议用示波器抓波形分析,除了开始和结束时序外,8位一应答。
https://www.amobbs.com/forum.php?mod=viewthread&tid=5561563&ordertype=1
https://blog.csdn.net/u012780337/article/details/17711359
主机和从机是相对的,如果这里是单片机和E2PROM通信的话,MCU就是主机,E2PROM就从机。
ACK就应答的意思,/* while(I2C_SDA && (ack == 1))*/ 的意思就是等待数据线为高,即单片机把一个字节的数据发完了,再把数据线拉低,然后等待E2PROM把数据线拉高,如果拉高了就是从机(E2PROM)有应答,如果等待时间到了后没有拉高就是从机(E2PROM)无应答。
出现无应答的情况就是I2C总线出错或者从机(E2PROM)正在忙碌状态。
这里是 ack 是传入的 参数, 属于 变量 , 不是 硬件 ack , 我也是很努力的在指导你哦, 希望采纳我的答案 。
1.从写入器件地址到写入内存地址再到最后写入数据,从程序上看这是一个同步IO操作,及你的I2C_SendByte()是一个同步IO操作函数,
前面MCU与外挂E2PROM进行的只是外挂E2PROM的寄存器操作(表明器件地址与内存地址),外挂E2PROM执行时间很快,所以代码作者
是可以也有必要确认ACK的,但是到了最后进行的外挂E2PROM写操作,是涉及到E2PROM擦除和写入的,一般NVM的擦除时间都比较长,
MCU一直在这里等待外挂E2PROM擦写数据是不明智的,所以作者可以选择做好的擦写数据不确认ACK,直接跳过。
题者可以考虑去了解下嵌入式相关异步IO,就明白了。【以上属于个人愚见,请参考】