由于I2C很重要,应用很广,所以认为有必要将I2C驱动的设计细节给一一“拎出来”,防止自己以后漏掉细节而导致通信失败!以下主要是基于I.MX6ULL的主机I2C驱动来总结的。
1.使用如下8个函数即可实现I2C通信
2.与I2C相关的5个16位寄存器
如下图按照驱动中对I2C寄存器的“动作频率”来排序,“动作”包含对寄存器置位、清零与判断。
①I2SR和I2CR是最常要进行“动作”的寄存器。
②IFDR寄存器只用了一次,即设置分频使用。
③IADR寄存器在主机驱动不用。
3.4个寄存器的位操作
按照操作频率从高到底排序。I2SR bit1要最常操作到。
①I2SR的bit1
I2C interrupt。
②I2DR的所有可用位域,也即Bit0-Bit7
如下函数操作到了I2DR寄存器。
③I2CR的Bit3
I2CR的Bit3为“Transmit acknowledge enable”位。置0表示在8位数据后,第9个时钟周期,发送一个Ack信号。置1表示不发Ack信号。在如下数据传输过程有操作到I2CR的Bit3。
④I2CR的Bit4
IC2CR的bit4控制着Transmit/Receive mode。0为Receive,1为Transmit。如下四个数据传输过程要操作到I2CR的bit4。
⑤I2CR的Bit7
仅在i2c_init函数使用。用于开启和关闭I2C
⑥I2SR的Bit4
尽在i2c_check_and_clear_error有用到,清零。用于清除仲裁丢失错误位。
⑦I2SR的Bit5
依据芯片手册的1467页,可以得到:检测到停止信号时,I2SR的Bit5跳变为0;检测到起始信号时,I2SR的Bit5跳变为1(个人认为言外之意即:检测起始信号前,Bit5状态必须为0)。
这就意味着,I2C总线不能无脑发送起始信号 和 重复起始信号。发送起始信号和重复起始信号前,一定要判断I2SR的bit5是否为0,若为1,那不好意思,您只能等等了。体现在代码中,就是如下语句:
⑧I2SR的Bit7
I2SR的bit7为“Data transferring bit”。0表示正在传输,需要等等。1表示传输完成,新的传输准备就绪。如下函数均将I2SR的bit7的值放于while循环中判断,若为0,则循环等待,知道bit为1,即传输完成。
⑨I2CR的bit5
I2CR的bit5为Master/Slave mode select bit。
⑩I2CR的bit2
I2CR的bit2为Repeat start。仅用于i2c_master_repeated_start函数中,用来产生重新开始信号。
⑪IFDR的所有位域,即bit0-bit5
设置分频值。