本文整理 I2C 協定核心時序與基於 AT24C04 EEPROM 的完整 C 語言驅動程式碼,包含起始/停止信號、位元組收發、ACK/NACK 機制與頁面寫入流程,適合嵌入式開發者參考移植。
void AT24C04_Start(void) {
SDA = 1; SCL = 1; Delay5us();
SDA = 0; Delay5us(); // 產生下降沿
SCL = 0; Delay5us();
}
void AT24C04_Stop(void) {
SDA = 0; SCL = 1; Delay5us();
SDA = 1; Delay5us(); // 產生上升沿
}
void AT24C04_SendByte(BYTE dat) {
BYTE i;
for (i = 0; i < 8; i++) {
dat <<= 1; // 移出最高位到 Carry
SDA = CY; // 輸出資料位
SCL = 1; Delay5us();
SCL = 0; Delay5us();
}
AT24C04_RecvACK(); // 等待從機 ACK
}
BYTE AT24C04_RecvByte(void) {
BYTE i, dat = 0;
SDA = 1; // 釋放總線,準備讀取
for (i = 0; i < 8; i++) {
dat <<= 1;
SCL = 1; Delay5us();
dat |= SDA; // 讀取資料位
SCL = 0; Delay5us();
}
return dat;
}
// 主機發送 ACK/NACK (讀取時使用)
void AT24C04_SendACK(bit ack) {
SDA = ack; SCL = 1; Delay5us();
SCL = 0; Delay5us();
}
// 主機接收從機 ACK (寫入時使用)
bit AT24C04_RecvACK(void) {
SCL = 1; Delay5us();
CY = SDA; // 讀取 ACK 位
SCL = 0; Delay5us();
return CY; // 0=ACK, 1=NACK
}
void AT24C04_WritePage(void) {
BYTE i;
AT24C04_Start();
AT24C04_SendByte(0xA0); // 裝置地址 + 寫位元 (0)
AT24C04_SendByte(0x00); // 記憶體位址 (低位元組)
for (i = 0; i < 16; i++) {
AT24C04_SendByte(TESTDATA[i]);
}
AT24C04_Stop();
}
SDA/SCL 宏定義與 Delay5us() 為目標平台對應實作t_HD;STA、t_SU;STA、t_HIGH/t_LOW 等時序參數I2C 以兩線實現多主多從通訊,掌握「起始/停止條件、位元組傳輸、ACK 機制」三大核心,即可實作任意 I2C 裝置驅動。AT24C04 為經典練習晶片,理解其頁面寫入與位址自動遞增特性,對開發其他 EEPROM、感測器、RTC 等 I2C 裝置極具參考價值。