4.1 主机发送/从机接收I2C子程序流程图
图2和图3给出了主机发送,从机接收I2C子程序流程图,通过 I2C总线 发送/接收数据时,I2C总线的控制寄存器的中断位必须先置位,为了避免因为某种原因不能使控制寄存器的中断位置位而导致程序进入死循环,作者在I2C总线通信程序发送/接收数据前编写了中断循环等待和错误处理程序,大大提高了程序的可靠性,具体程序如下:
应用I2C总线发送数据时,作者采用了状态位查询方法,并且给出了错误标志置位、错误跳出程序,下面的程序是发送从机地址的部分程序:
程序中的flag=0表示从机地址发送成功,flag=1表示从机地址发送失败,当TWSR寄存器中的状态码为0x18时,表明从机地址已发送,并且接收到ACK,同时错误标志“flag”置0,下一步通过心发送数据,当TWSR寄存器中的状态码为0x20时,表明从机地址已发送,但是接收到NO ACK,同时错误标志”flag”置1,下一步执行“if(flag)continue;”语句,结束本次循环,当TWSR寄存器中的状态码为0x38时,表明从机地址仲裁失败,同时错误标志“flag”置1,下一步执行“if(flag) continue;"语句,结束本次循环。总线将释放,并进入未寻址从机模式,总线空闲后将发送“start”。程序中“if(flag)continue;”语句使得当数据发送失败时,结束本次循环,返回到开始等待发送命令,这样避免了由于偶尔数据发送失败造成整个程序无法运行,甚至整个设备无法运行,因而,用“if(flag)continue;”语句结束错误传输。可提高I2C通信的质量,同时也提高了使用I2C总线通信的设备的效率。
4.2 编程中的注意事项
a)在主机或从机初始化时,一定要设定数据传输方向;
b)由于每次发送/接收数据时TWCR寄存器的中断标志位必须置位,因此程序中要有等待TWCR寄存器中断位置位程序,同时,为了避免由于某种原因导致中断位不能置位造成等待程序进入死循环,在等待中断位置位程序中要有等待超时返回程序。
c)I2C总线的使用,除了基本的启动、结束、应答、非应答子程序外,还应有应答位检查、发送和接收单字节、发送和接收多字节等子程序。
5 结论
作者在程序流程的每个关键部分都设置了错误查询和错误处理,使得I2C程序能够从错误中自动恢复,避免了由于I2C通信导致的错误而使得系统无法正常工作,文中还给出了部分发送子程序和编程注意事项。对于图2和图3的I2C通信流程,作者已在多个科研项目中进行了编程使用。实践证明,按上述流程编写I2C通信程序,主从单片机之间的通信非常可靠。
本文作者创新点:程序流程的每个关键部分都设置了错误查询和错误处理,使心通信能够从错误中自动恢复,提高了使用I2C通信的可靠性,并且给出了避免死循环的错误处理程序。