起始和终止条件函数默认了,在调用前SCL已经确保为0了,这样才能改变SDA,但是第一次起始条件较为特殊,我们初始化引脚默认为高电平空闲状态,此时SCL虽然未确保低电平,但是确保了SDA为高电平,这样保证了不会误判,因为SDA只能从高电平下降为低电平,为什么会这样?因为在第一次起始条件前,我们会默认其空闲状态(即SDA,CLK均为高电平),注意SDA,CLK都是确定值;而在后续的电平变化中,我们只能保证SCL在函数调用前确定为低电平,因为CLK是一直由主机控制的,也就是说,只有主机可以改变SCL的电平,从机不会;但是SDA就不一样了,在数据交换的过程中,主机会释放SDA的控制权,那么此时SDA的电平是由从机控制的,主机负责接收,也就是说,这个主机接收到的SDA电平,是不确定的,所以在主机每次发送命令或数据前,需要自己首先改变SDA的电平(SCL此时已提前置为低),然后再改变SCL,接着改变SDA,形成上升或下降沿,最后的最后一定不要忘了将SCL提前拉低,为下次的iic函数调用,做好铺垫。
终止条件函数,(SCL此时已提前置为低)先拉低SDA,再拉高SCL,最后拉高SDA形成上升沿,终止IIC通讯。终止条件后,SCL,SDA都回归到高电平,即空闲状态。
关于SDA控制权变化的几个节点有:
- 主机发送从机读写地址命令后,释放SDA控制权(SDA拉高),等待从机应答信号。
- 主机发送完从机寄存器地址后,释放SDA控制权(SDA拉高),等待从机应答信号。
- 主机发送完一个字节后,释放SDA控制权(SDA拉高),等待从机应答信号。(这一条其实已涵盖了前两条)
- 主机接收完一个字节后,从机释放SDA控制权(SDA拉高),主机发送应答信号。(我们编写的是主机IIC函数,从机不用管)
- 在整个IIC通讯过程中,时钟信号CLK的控制权一直在主机手里,所以在主机的IIC函数中,函数退出前一定不要忘了将CLK提前拉低,为下次的iic函数调用,做好铺垫。(终止函数不用铺垫)
无论应答信号是0还是1,应答完都要放手,所以SDA还是高电平,所以不需要拉低SDA啊