AT24C系列是常見的EEPROM儲存晶片, 常用於儲存引數及掉電記憶的資料
與其他記憶體件相比
因為這些特點, AT24C常用於一些容量小但是穩定性要求高, 並且需要反覆擦寫的場景.
AT24C的裝置地址都是一個位元組, 以二進位制1010
開頭, 通過A0,A1,A2這三個pin進行調整. 根據容量不同, 裝置地址和定址範圍有區別
這個系列的儲存地址只有一個位元組, 所以記憶體定址只有256位元組(2048 bit), 對於AT24C01, AT24C02可以直接定址, 對於更大容量的型號, 需要結合裝置地址對記憶體地址分page存取
存取AT24C時I2C匯流排的頻率不能太高.
對於DIP8封裝, 接線方式都是一樣的, 測試使用的是 STC8H3K64S2, 可以直接替換為 STC8H 其它型號, 除了下面的4個pin, 還需要選擇將A0, A1, A2 接GND或接VCC
P32 -> SCL
P33 -> SDA
GND -> GND
3.3V -> VCC
這個例子演示了單位元組儲存地址系列型號的存取方式
#include "fw_hal.h"
// 設定地址 0xA0, 對應A0,A1,A2三個pin都接地, 測試中根據自己的接線修改
#define AT24C_ADDR 0xA0
__CODE int8_t dat[20] = {0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB};
// I2C初始化
void I2C_Init(void)
{
// 主裝置模式
I2C_SetWorkMode(I2C_WorkMode_Master);
/**
* I2C 匯流排頻率 = FOSC / 2 / (__prescaler__ * 2 + 4) 這裡設成最大值0x3F
*/
I2C_SetClockPrescaler(0x3F);
// 選擇I2C埠
I2C_SetPort(I2C_AlterPort_P32_P33);
// 啟用 I2C
I2C_SetEnabled(HAL_State_ON);
}
// GPIO初始化
void GPIO_Init(void)
{
// SDA
GPIO_P3_SetMode(GPIO_Pin_3, GPIO_Mode_InOut_QBD);
// SCL
GPIO_P3_SetMode(GPIO_Pin_2, GPIO_Mode_Output_PP);
}
int main(void)
{
uint8_t offset, i, buf[20];
SYS_SetClock();
// 開啟 UART1, baud 115200 with Timer2, 1T mode, no interrupt
UART1_Config8bitUart(UART1_BaudSource_Timer2, HAL_State_ON, 115200);
GPIO_Init();
I2C_Init();
// 對地址0x00連續寫入12個位元組
I2C_Write(AT24C_ADDR, 0x00, dat, 12);
while(1)
{
// 分4次, 起始地址遞增, 每次連續讀出6個位元組並通過串列埠輸出
for (offset = 0; offset < 4; offset++)
{
I2C_Read(AT24C_ADDR, offset, buf, 6);
for (i = 0; i < 6; i++)
{
UART1_TxHex(buf[i]);
UART1_TxChar(':');
}
UART1_TxString(" ");
SYS_Delay(10);
}
UART1_TxString("\r\n");
// 間隔1秒
SYS_Delay(1000);
}
}
程式碼地址
這個例子演示了雙位元組儲存地址系列型號的存取方式
#include "fw_hal.h"
// AT24C device address, change according to the voltage level of A0/A1/A2
#define AT24C_ADDR 0xA0
// Test data
__CODE int8_t dat[20] = {0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB};
void I2C_Init(void)
{
// Master mode
I2C_SetWorkMode(I2C_WorkMode_Master);
/**
* I2C clock = FOSC / 2 / (__prescaler__ * 2 + 4)
*/
I2C_SetClockPrescaler(0x3F);
// Switch alternative port
I2C_SetPort(I2C_AlterPort_P32_P33);
// Start I2C
I2C_SetEnabled(HAL_State_ON);
}
void GPIO_Init(void)
{
// SDA
GPIO_P3_SetMode(GPIO_Pin_3, GPIO_Mode_InOut_QBD);
// SCL
GPIO_P3_SetMode(GPIO_Pin_2, GPIO_Mode_Output_PP);
}
int main(void)
{
uint8_t offset, i, buf[20];
SYS_SetClock();
// UART1 configuration: baud 115200 with Timer2, 1T mode, no interrupt
UART1_Config8bitUart(UART1_BaudSource_Timer2, HAL_State_ON, 115200);
GPIO_Init();
I2C_Init();
// 與AT24C08範例的區別在於使用了16bit地址
I2C_Write16BitAddr(AT24C_ADDR, 0x0000, dat, 12);
while(1)
{
for (offset = 0; offset < 4; offset++)
{
// 與AT24C08範例的區別在於使用了16bit地址
I2C_Read16BitAddr(AT24C_ADDR, 0x0000|offset, buf, 6);
for (i = 0; i < 6; i++)
{
UART1_TxHex(buf[i]);
UART1_TxChar(':');
}
UART1_TxString(" ");
SYS_Delay(10);
}
UART1_TxString("\r\n");
SYS_Delay(1000);
}
}
程式碼地址