檢測AT24CXX的自寫入周期結(jié)束
AT24CXX的自寫入周期是“小于5ms”,所以可以用延時(shí)函數(shù)延時(shí)5ms解決。
痛點(diǎn):寫延時(shí)函數(shù)可以用軟件延時(shí)和定時(shí)器延時(shí)。軟件延時(shí),時(shí)間是多少,需要借助示波器才能看出來精確時(shí)間,沒有示波器,或者用示波器看,都是很麻煩,而且如果單片機(jī)主頻一改變,軟件延時(shí)的值又需要改變。定時(shí)器延時(shí)占用一個(gè)定時(shí)器,浪費(fèi)單片機(jī)資源。還有,萬一由于AT24CXX由于自身問題,突然延長了本次的寫入時(shí)間,再加上寫程序的時(shí)候沒有考慮到這一點(diǎn),整個(gè)系統(tǒng)就完蛋了。
解決辦法:看寫入時(shí)序,單片機(jī)向AT24CXX發(fā)送起始信號,再發(fā)送一個(gè)地址數(shù)據(jù)后,AT24CXX會(huì)返回一個(gè)ACK信號,如果自寫入周期沒有結(jié)束,就不會(huì)返回一個(gè)ACK信號,所以,我們可以觀察有沒有這個(gè)ACK來判斷自寫入周期是否結(jié)束。這樣的話,不管24CXX的自寫入周期是多長時(shí)間,都可以立即進(jìn)行再寫入一個(gè)數(shù)據(jù)或者進(jìn)行讀操作,提高程序的效率。
下面是用STM32庫函數(shù)寫的程序,實(shí)現(xiàn)步驟就是上面解決辦法所講的。
voidWaitWriteCycleOver(void){do{/*發(fā)送開始信號*/I2C_GenerateSTART(I2C1,ENABLE);/*讀SR1寄存器,用于清除開始標(biāo)志*/I2C_ReadRegister(I2C1,I2C_Register_SR1);/*發(fā)送器件地址*/I2C_Send7bitAddress(I2C1,0xA0,I2C_Direction_Transmitter);/*檢測是否成功發(fā)送器件地址*/}while(!(I2C_ReadRegister(I2C1,I2C_Register_SR1)&I2C_FLAG_ADDR));/*清除ACK標(biāo)志*/I2C_ClearFlag(I2C1,I2C_FLAG_AF);/*發(fā)送停止信號*/I2C_GenerateSTOP(I2C1,ENABLE);}
看完后,你會(huì)對程序有若干疑問:
疑問1:為什么不檢測ACK而檢測ADDR?
因?yàn)槲覀冇玫氖怯布蘒2C,檢測ACK的事情,就由硬件完成了,SR1中的ADDR置位,就說明硬件檢測到了ACK,否則,就沒有檢測到ACK。
疑問2:為什么要單獨(dú)清除ACK,不清除其它標(biāo)志位?
因?yàn)锳CK位需要軟件清除,其它位讀一下,就自動(dòng)清除了。