1.為什么需要EEPROM?
? ? ? ? 在單片機開發中,斷電數據保存是常見的需求。例如,智能家居設備的用戶設置、電子秤的校準參數等都需要在斷電后仍能保留。AT24C02作為一款IIC接口的EEPROM芯片,具備以下優勢:
- 非易失性存儲:斷電后數據不丟失。
- 容量適中:256字節(2Kb),適合存儲小規模數據。
- 接口簡單:僅需兩根信號線(SDA、SCL),節省單片機IO口資源。
2.AT24C02硬件解析
1.芯片特性
- 工作原理:2.7V~5.5V(兼容51單片機5V供電)。
- 存儲結構:分32頁,每頁八字節,支持頁寫入模式。
- 器件地址:高4位固定為1010,低四位由A0~A2引腳電平決定(默認接地地址為0xA0)。
2.硬件連接
?3.IIC協議核心原理
? ? ? ? IIC協議通過時序信號實現數據傳輸,需掌握以下關鍵操作:
1.起始信號與停止信號
????????在通信里,SCL 線高電平時,SDA 線從高到低是起始信號,從低到高是終止信號,都由主機發。起始信號一出現,總線被占用;終止信號發出后,總線恢復空閑。
void I2C_Start(void)
{I2C_SDA=1;I2C_SCL=1;I2C_SDA=0;I2C_SCL=0;
}
void I2C_Stop(void)
{I2C_SDA=0;I2C_SCL=1;I2C_SDA=1;
}
?2.數據有效性規定
????????I2C 總線傳輸數據時,時鐘信號高電平時,數據線數據要保持穩定,僅時鐘信號低電平時,數據線電平狀態才可改變。每次數據傳輸以字節為單位,且傳輸的字節數量不設上限。
void I2C_SendByte(unsigned char Byte)
{unsigned char i;for (i=0;i<8;i++){I2C_SDA=Byte&(0x80>>i);I2C_SCL=1;I2C_SCL=0;}
}
unsigned char I2C_ReceiveByte(void)
{unsigned char i,Byte=0x00;I2C_SDA=1;for(i=0;i<8;i++){I2C_SCL=1;if(I2C_SDA){Byte|=(0x80>>i);}I2C_SCL=0;}return Byte;
}
3.應答響應
?????????I2C 總線數據傳輸時,發送器件傳完一字節數據后,需緊跟校驗位。此校驗位由接收端控制 SDA 實現,是傳輸響應,分“應答(ACK)”和“非應答(NACK)”。 接收端收到字節數據或地址后,想繼續接收就發“應答(ACK)”低電平脈沖,發送方繼續發數據;想結束則發“非應答(NACK)”高電平脈沖,發送方產生停止信號。 每個字節 8 位,先傳最高位,后隨一位應答位,一幀共 9 位。若從機不對尋址信號應答,將數據線置高,主機發終止信號。從機接收中無法繼續,通過“非應答”通知主機結束。主機接收完最后一字節,用“非應答”結束,從機釋放 SDA 線。起始信號必需,結束和應答信號可選。
void I2C_SendAct(bit ActBit)
{I2C_SDA=ActBit;I2C_SCL=1;I2C_SCL=0;
}
unsigned char I2C_ReceiveAct(void)
{unsigned char ActBit;I2C_SDA=1;I2C_SCL=1;ActBit=I2C_SDA;I2C_SCL=0;return ActBit;
}
4.總線的尋址方式
4.AT24C02介紹
? ? ? ? AT24C02器件地址為7位,高四位固定為1010,低3位由A0/A1/A2信號的電平決定。因為傳輸地址或數據是以字節為單位傳送的,當傳送地址時,器件地址占7位,還有最后一位(最低位R/W)用來選擇讀寫方向,它與地址無關。其格式如下:
?
#define AT24C02_ADDRESS 0xA0?
????????本開發板已經將A0/A1/A2連接到GND,所以器件地址為1010000,即0x50(未計算最低位)。如果要對芯片進行寫操作時,R/W即為0,寫器件地址即為0xA0;如果要對芯片進行讀操作時,R/W即為1,此時讀器件地址為0xA1。開發板上也將WP引腳直接接在GND上,此時芯片允許數據正常讀寫。
? ? ? ? IIC總線時序如下:
1.寫入一個字節
// 向AT24C02指定地址寫入一個字節
void AT24C02_WriteByte(unsigned char WordAddress, unsigned char Data) {I2C_Start();I2C_SendByte(AT24C02_ADDRESS);if (I2C_ReceiveAct()) {// 應答錯誤處理,可根據需求添加更多邏輯return;}I2C_SendByte(WordAddress);if (I2C_ReceiveAct()) {return;}I2C_SendByte(Data);if (I2C_ReceiveAct()) {return;}I2C_Stop();
}
- 啟動 I2C 通信 (
I2C_Start()
):通過?I2C_Start
?函數產生 I2C 起始信號,標志著一次新的 I2C 通信開始。 - 發送設備地址 (
I2C_SendByte(AT24C02_ADDRESS)
):將 AT24C02 的設備地址發送到總線上。AT24C02_ADDRESS
?是 AT24C02 的 7 位設備地址加上讀寫位(寫操作時讀寫位為 0)。發送完設備地址后,調用?I2C_ReceiveAct
?函數檢查 AT24C02 是否返回了應答信號。如果沒有收到應答信號,說明通信可能出現問題,函數直接返回。 - 發送存儲地址 (
I2C_SendByte(WordAddress)
):將想要寫入數據的存儲地址發送到總線上。同樣,發送完后檢查 AT24C02 的應答信號。 - 發送要寫入的數據 (
I2C_SendByte(Data)
):將需要寫入到 AT24C02 中的數據發送到總線上,然后再次檢查應答信號。 - 停止 I2C 通信 (
I2C_Stop()
):通過?I2C_Stop
?函數產生 I2C 停止信號,結束本次通信。
2.讀取一個字節
unsigned char AT24C02_ReadByte(unsigned char WordAddress) {unsigned char Data;I2C_Start();I2C_SendByte(AT24C02_ADDRESS);if (I2C_ReceiveAct()) {return 0; // 應答錯誤,返回0}I2C_SendByte(WordAddress);if (I2C_ReceiveAct()) {return 0;}I2C_Start();I2C_SendByte(AT24C02_ADDRESS | 0x01);if (I2C_ReceiveAct()) {return 0;}Data = I2C_ReceiveByte();I2C_SendAct(1); // 發送非應答位I2C_Stop();return Data;
}
??????????????