單片機常用芯片系列(四)——at24c02詳解

在這裏插入圖片描述在這裏插入圖片描述這三個引腳其實是地址,如果需要一個單片機上帶一堆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;
}

這個延時就很精髓。

直接調用就能讀寫

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章