這三個引腳其實是地址,如果需要一個單片機上帶一堆at24c02,就需要很多地址。這裏不需要,所以全接地
————————————————————————————
i2c總線就這三根,wp給他接地讓他不保護,
——————————————————————
2048位,也就是256個字節。
——————————————————————————————
時鐘高電平時數據線下降沿是開始,上升沿是結束
————————————————————————
傳送1位數據時,先把數據準備好,然後再給時鐘信號
——————————————————————
每個字節完了都是一個應答信號,低電平爲應答,高電平不是應答。記得把總線釋放,也就是置一
——————————————————————
前4個固定1010,後三個全部接地,也是0.最後一個1讀0寫
0xa0 //寫
0xa1 //讀
——————————————————————————
寫命令:
寫一個字節:
先來一個起始,就是上邊說的時鐘高電平的時候,數據線來個下降沿
然後是器件地址,10100000,發送過去之後就是一個器件的應答,低電平表示接受到
然後8位字地址,發完一個應答
然後發8位數據,發送完畢又是一個應答。
最後發一個停止,就是數據上升沿時鐘高電平
一個字節就寫進去了
uchar writeByte(uchar dat, uchar add){
SDA = 1;
SCL = 1;
SDA = 0;
for(i = 0; i < 8; i++)
{
SDA = add & 0x01;
SCL = 1;
SCL = 0;
SDA = 0;
dat >>= 1;
}
SDA = 1;
SCL = 0;
SCL = 1;
uchar j;
while(SDA)
{
if(j > 5)
{
return 0;
}
j++;
delay();
}
for(i = 0; i < 8; i++)
{
SDA = dat & 0x01;
SCL = 1;
SCL = 0;
SDA = 0;
dat >>= 1;
}
SDA = 0;
SCL = 1;
SDA = 1;
先發高位
————————————————————
頁寫其實就是一次寫好幾個字節,at24c02每頁8個字節。如果你送了超過8個字節,它不會超出當前頁,他會從頭又開始,把前面的覆蓋掉。
————————————————————————————
讀就很簡單了
一樣,只不過地址最後一位置一。
不需要應答信號,直接給停止就行
這個是當前地址讀,就是挨個讀,只讀這個頁,讀完了重新讀這頁
先讀也是高位
寫和讀都是高位先來
————————分割線————————
開始寫代碼了
#include "at24c02.h"
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
#define DELAY_TIME 5
void IIC_Delay(unsigned char i)
{
do{_nop_();}
while(i--);
}
//總線啓動條件
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 0;
}
//總線停止條件
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//發送應答
void IIC_SendAck(bit ackbit)
{
SCL = 0;
SDA = ackbit; // 0:應答,1:非應答
IIC_Delay(DELAY_TIME);
SCL = 1;
IIC_Delay(DELAY_TIME);
SCL = 0;
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//等待應答
bit IIC_WaitAck(void)
{
bit ackbit;
SCL = 1;
IIC_Delay(DELAY_TIME);
ackbit = SDA;
SCL = 0;
IIC_Delay(DELAY_TIME);
return ackbit;
}
//通過I2C總線發送數據
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++)
{
SCL = 0;
IIC_Delay(DELAY_TIME);
if(byt & 0x80) SDA = 1;
else SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 1;
byt <<= 1;
IIC_Delay(DELAY_TIME);
}
SCL = 0;
}
//從I2C總線上接收數據
unsigned char IIC_RecByte(void)
{
unsigned char i, da;
for(i=0; i<8; i++)
{
SCL = 1;
IIC_Delay(DELAY_TIME);
da <<= 1;
if(SDA) da |= 1;
SCL = 0;
IIC_Delay(DELAY_TIME);
}
return da;
}
這是系統給的,自己只需要寫一個收發。收發這裏注意一下,如果發現讀寫有問題,那就改一下延時試試,在每一個命令之間加延時。因爲這個芯片不快。
void sendByte(uchar dat, uchar add)
{
IIC_Start();
IIC_SendByte(0xa0);IIC_Delay(DELAY_TIME);
IIC_WaitAck();IIC_Delay(DELAY_TIME);
IIC_SendByte(add);IIC_Delay(DELAY_TIME);
IIC_WaitAck(); IIC_Delay(DELAY_TIME);
IIC_SendByte(dat);IIC_Delay(DELAY_TIME);
IIC_WaitAck();IIC_Delay(DELAY_TIME);
IIC_Stop();IIC_Delay(DELAY_TIME);
IIC_Delay(DELAY_TIME);
}
uchar readByte(uchar add)
{
uchar dat;
IIC_Start();
IIC_SendByte(0xa0);IIC_Delay(DELAY_TIME);
IIC_WaitAck();IIC_Delay(DELAY_TIME);
IIC_SendByte(add);IIC_Delay(DELAY_TIME);
IIC_WaitAck();IIC_Delay(DELAY_TIME);
IIC_Start();
IIC_SendByte(0xa1);IIC_Delay(DELAY_TIME);
IIC_WaitAck();IIC_Delay(DELAY_TIME);
dat = IIC_RecByte();IIC_Delay(DELAY_TIME);
IIC_Delay(DELAY_TIME);IIC_Delay(DELAY_TIME);
IIC_Stop();
IIC_Delay(DELAY_TIME);
return dat;
}
這個延時就很精髓。
直接調用就能讀寫