AT24C02是一個2K位序列CMOS E2PROM, 內部含有256個8位元位元組,CATALYST公司的先進CMOS技術實質上減少了器件的功耗。AT24C02有一個8位元組頁寫緩衝器。該器件通過IIC匯流排介面進行操作,有一個專門的防寫功能。
與 400KHz I2C 匯流排相容 。
1.8 到 6.0 伏工作電壓範圍
低功耗 CMOS 技術
防寫功能 當 WP 為高電平時進入防寫狀態
頁寫緩衝器
自定時擦寫週期
1,000,000 程式設計/擦除週期
可儲存資料 100 年
8 腳 DIP SOIC 或 TSSOP 封裝
溫度範圍 商業級 工業級和汽車級
寫操作
讀操作(讀之前要進行一邊寫操作才能獲取地址)
/*
引腳說明
SCL -- PB8
SDA -- PB9
*/
#define SCL PBout(8)
#define SDA_IN PBin(9)
#define SDA_OUT PBout(9)
void Iic_Init(void) //IIC引腳設定
{
GPIO_InitTypeDef GPIO_InitStruct; //結構體
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); //使能GPIO B組時鐘
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9; //引腳8 9
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; //輸出模式
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; //輸出推輓
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //輸出速度
GPIO_Init(GPIOB, &GPIO_InitStruct);
//匯流排空閒
SCL = 1;
SDA_OUT = 1;
}
//引腳模式變更
void Iic_Sda_Mode(GPIOMode_TypeDef mode)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //第9號引腳
GPIO_InitStructure.GPIO_Mode = mode; //輸入/輸出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推輓輸出,增強驅動能力,引腳的輸出電流更大
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //引腳的速度最大為100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //沒有使用內部上拉電阻
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
//啟動訊號
void Iic_Start(void)
{
Iic_Sda_Mode(GPIO_Mode_OUT);
//匯流排空閒
SCL = 1;
SDA_OUT = 1;
delay_us(5);
//啟動訊號
SDA_OUT = 0;
delay_us(5);
SCL = 0;
}
//停止訊號
void Iic_Stop(void)
{
Iic_Sda_Mode(GPIO_Mode_OUT);
SCL = 0;
SDA_OUT = 0;
delay_us(5);
SCL = 1;
delay_us(5);
SDA_OUT = 1;
}
//引腳傳送一位資料
void Iic_Send_Ack(u8 ack)
{
Iic_Sda_Mode(GPIO_Mode_OUT);
SCL = 0;
/*準備資料*/
//發資料1
if(ack == 1)
{
SDA_OUT = 1; //引腳輸出
}
//發資料0
if(ack == 0)
{
SDA_OUT = 0; //引腳輸出
}
delay_us(5);
SCL = 1;
delay_us(5);
SCL = 0;
}
//引腳傳送一個位元組資料
void Iic_Send_Byte(u8 data)
{
u8 i;
Iic_Sda_Mode(GPIO_Mode_OUT);
SCL = 0;
//0 1 1 1 1 0 0 0
for(i=0; i<8; i++)
{
/*準備資料*/
//發資料1
if(data & (1<<(7-i)))
{
SDA_OUT = 1; //引腳輸出
}
//發資料0
else
{
SDA_OUT = 0; //引腳輸出
}
delay_us(5);
SCL = 1;
delay_us(5);
SCL = 0;
}
}
//接受一位資料
u8 Iic_Rcv_Ack(void)
{
u8 ack;
Iic_Sda_Mode(GPIO_Mode_IN);
SCL = 0;
delay_us(5);
SCL = 1;
delay_us(5);
if(SDA_IN == 1) //引腳為電平為1
{
ack = 1;
}
if(SDA_IN == 0) //引腳為電平為1
{
ack = 0;
}
SCL = 0;
return ack;
}
//接受一個位元組資料
u8 Iic_Rcv_Byte(void)
{
u8 i, data = 0; //0 0 0 0 0 0 0 0 比如有資料:1 1 0 0 1 0 0 0
Iic_Sda_Mode(GPIO_Mode_IN);
SCL = 0;
//0 1 1 1 1 0 0 0
for(i=0; i<8; i++)
{
delay_us(5);
SCL = 1;
delay_us(5);
//接受資料
if(SDA_IN == 1) //引腳為電平為1
{
data |= (1<<(7-i));
}
SCL = 0;
}
return data;
}
void AT24c02_Write(u8 addr, u8 *write_buff, u8 len)
{
u8 ack;
//啟動訊號
Iic_Start();
//傳送裝置地址
Iic_Send_Byte(0xA0);
ack = Iic_Rcv_Ack();
if(ack == 1)
{
printf("ack failure\n");
return ;
}
//傳送寫資料起始地址
Iic_Send_Byte(addr);
ack = Iic_Rcv_Ack();
if(ack == 1)
{
printf("ack failure\n");
return ;
}
//資料:hello
while(len--)
{
//傳送資料
Iic_Send_Byte(*write_buff);
ack = Iic_Rcv_Ack();
if(ack == 1)
{
printf("ack failure\n");
return ;
}
write_buff++;
}
Iic_Stop();
printf("write finish\n");
}
void AT24c02_Read(u8 addr, u8 *read_buff, u8 len)
{
u8 ack;
//啟動訊號
Iic_Start();
//傳送裝置地址
Iic_Send_Byte(0xA0);
ack = Iic_Rcv_Ack();
if(ack == 1)
{
printf("ack failure\n");
return ;
}
//傳送寫資料起始地址
Iic_Send_Byte(addr);
ack = Iic_Rcv_Ack();
if(ack == 1)
{
printf("ack failure\n");
return ;
}
//啟動訊號
Iic_Start();
//傳送裝置地址
Iic_Send_Byte(0xA1);
ack = Iic_Rcv_Ack();
if(ack == 1)
{
printf("ack failure\n");
return ;
}
//資料:hello 5
while(len--)
{
*read_buff = Iic_Rcv_Byte();
if(len > 0)
Iic_Send_Ack(0); //傳送有效應答
read_buff++;
}
Iic_Send_Ack(1);
Iic_Stop();
printf("read finish\n");
}