检测AT24CXX的自写入周期结束
扫描二维码
随时随地手机看文章
AT24CXX的自写入周期是“小于5ms”,所以可以用延时函数延时5ms解决。
痛点:写延时函数可以用软件延时和定时器延时。软件延时,时间是多少,需要借助示波器才能看出来精确时间,没有示波器,或者用示波器看,都是很麻烦,而且如果单片机主频一改变,软件延时的值又需要改变。定时器延时占用一个定时器,浪费单片机资源。还有,万一由于AT24CXX由于自身问题,突然延长了本次的写入时间,再加上写程序的时候没有考虑到这一点,整个系统就完蛋了。
解决办法:看写入时序,单片机向AT24CXX发送起始信号,再发送一个地址数据后,AT24CXX会返回一个ACK信号,如果自写入周期没有结束,就不会返回一个ACK信号,所以,我们可以观察有没有这个ACK来判断自写入周期是否结束。这样的话,不管24CXX的自写入周期是多长时间,都可以立即进行再写入一个数据或者进行读操作,提高程序的效率。
下面是用STM32库函数写的程序,实现步骤就是上面解决办法所讲的。
voidWaitWriteCycleOver(void){do{/*发送开始信号*/I2C_GenerateSTART(I2C1,ENABLE);/*读SR1寄存器,用于清除开始标志*/I2C_ReadRegister(I2C1,I2C_Register_SR1);/*发送器件地址*/I2C_Send7bitAddress(I2C1,0xA0,I2C_Direction_Transmitter);/*检测是否成功发送器件地址*/}while(!(I2C_ReadRegister(I2C1,I2C_Register_SR1)&I2C_FLAG_ADDR));/*清除ACK标志*/I2C_ClearFlag(I2C1,I2C_FLAG_AF);/*发送停止信号*/I2C_GenerateSTOP(I2C1,ENABLE);}
看完后,你会对程序有若干疑问:
疑问1:为什么不检测ACK而检测ADDR?
因为我们用的是硬件I2C,检测ACK的事情,就由硬件完成了,SR1中的ADDR置位,就说明硬件检测到了ACK,否则,就没有检测到ACK。
疑问2:为什么要单独清除ACK,不清除其它标志位?
因为ACK位需要软件清除,其它位读一下,就自动清除了。