自己學習記錄用,有些亂,
1、IIC,eeprom24c02驅動配置
本實驗是基於EEPROM的24C02驅動配置的編程,主要記錄一些編程的重點節點的理解:
1、IIC驅動配置:精準的時鐘配置,計算每一步所需要的指令周期,相加是10us。

2、IIC的起始信號配置,根據IIC的時序特性配置。

3、IIC終止信號配置,根據IIC的時序特性配置。

4、I2cSendByte(unsigned char dat): 通過I2C發送一個字節。在SCL時鐘信號高電平期間,保持發送信號SDA保持穩定。

5、I2cReadByte(),函數功能 : 使用I2c讀取一個字節

6、void At24c02Write(unsigned char addr,unsigned char dat) 函數功能 :向 24c02的一個地址寫入一個數據。

發送寫器件地址是根據24C02的電路特性和地址特性獲得。24C02是有E0,E1,E2尋址,根據下面兩圖片可知是8位尋址,因E0、E1、E2引腳接地,而是寫所以,R/W位為零。,即發送器件地址位0xa0,同理接收時,接收器件地址為0xa1.


7、unsigned char At24c02Read(unsigned char addr)函數功能 : 讀取24c02的一個地址的一個數據

2、24C02或者24C16進行字節、頁讀取、頁存取
- void i2cStart(void) //開始時序
- {
- SDA=1;
- SCL=1;
- _delay(2); //延時2μs
- SDA=0;
- _delay(2);
- SCL=0;
- }
- void i2cStop(void) //結束時序
- {
- SDA=0;
- _delay(2);
- SCL=1;
- _delay(2);
- SDA=1;
- }
- void i2cAck_MCU(void) //應答時序
- {
- SDA=0;
- _delay(2);
- SCL=1;
- _delay(2);
- SCL=0;
- _delay(2);
- SDA=1;
- _delay(4);
- }
- void i2cNoAck_MCU(void) //非應答時序
- {
- SDA=1;
- _delay(2);
- SCL=1;
- _delay(2);
- SCL=0;
- _delay(2);
- }
24C02/16存儲空間大小
24C02就是有2Kbit = 2000/8 = 250個字節,24C16就是有16kbit = 2000個字節,24C02一頁最多可以寫入8個字節,因此可以分成32頁,24C16一頁最多可以寫入16個字節,因此可以分成128頁。
1、字節寫操作
void WriteByte_24LC16B(unsigned char input)
{
unsigned char bit_count;
for(bit_count=8;bit_count!=0;bit_count–)
{
_delay(2);
SDA=(_Bool)(input&0x80);
_delay(2);
SCL=1;
_delay(2);
SCL=0;
input=input<<1;
_delay(2);
}
SDA=1;
SDA_CTRL=1;//這裡需要看自己使用的芯片設置SDA的IO口為輸入狀態,我用的是HT45F67芯片,SDA端口設置為輸入狀態,用於判斷SDA是否接到主機的應答信號
_delay(2);
SCL=1;
_delay(2);
if(SDA == 1)
ack = 0;
else
ack = 1;
SCL=0;
SDA_CTRL=0; //此處根據自己所使用的芯片將SDA所在的Io口設置為輸出狀態
}
void Write_24LC16B(unsigned char Wdata,unsigned int RomAddress)
{
unsigned char block;
WriteDeviceAddress=0B10100000;
block=RomAddress/256;
RomAddress=RomAddress%256;
WriteDeviceAddress=WriteDeviceAddress|(block<<1);
i2cStart();
WriteByte_24LC16B(WriteDeviceAddress);
WriteByte_24LC16B((unsigned char)RomAddress);
WriteByte_24LC16B(Wdata);
i2cStop();
_delay(5500);
}
2、字節讀操作
unsigned char ReadByte_24LC16B()
{
unsigned char bit_count,rbyte=0;
SDA=1;
SDA_CTRL=1;
_delay(10);
for(bit_count=8;bit_count!=0;bit_count–)
{
rbyte=rbyte<<1;
_delay(2);
SCL=1;
rbyte=rbyte|((unsigned char)(SDA));
_delay(2);
SCL=0;
_delay(2);
}
SDA_CTRL=0;
return(rbyte);
}
unsigned char Read_24LC16B(unsigned int RomAddress)
{
unsigned char output,block;
ReadDeviceAddress=0B10100001;
WriteDeviceAddress=0B10100000;
block=RomAddress/256;
RomAddress=RomAddress%256;
WriteDeviceAddress=WriteDeviceAddress|(block<<1);
ReadDeviceAddress=ReadDeviceAddress|(block<<1);
i2cStart();
WriteByte_24LC16B(WriteDeviceAddress);
WriteByte_24LC16B((unsigned char)RomAddress);
i2cStart();
WriteByte_24LC16B(ReadDeviceAddress);
output=ReadByte_24LC16B();
i2cNoAck_MCU();
i2cStop();
_delay(2000);
return(output);
}
3、頁寫操作
Wdata為輸入數組的首地址,RomAddress為需要進行存儲的地址,範圍在0~2047之間,cnt為一次需要寫入的字節個數,建議採用8的倍數的cnt,因為本函數不採用自動分頁,不是8的倍數會在超出頁寫入最多的字節數之後覆蓋掉原來的數。
void WritePage_24LC16B(unsigned char *Wdata,unsigned int RomAddress,unsigned char cnt)
{
unsigned char block;
WriteDeviceAddress=0B10100000;
block=RomAddress/256;
RomAddress=RomAddress%256;
WriteDeviceAddress=WriteDeviceAddress|(block<<1);
i2cStart();
WriteByte_24LC16B(WriteDeviceAddress);
WriteByte_24LC16B((unsigned char)RomAddress);
while(cnt–)
{
WriteByte_24LC16B(*Wdata++);
}
i2cStop();
}
注意:連續進行多頁寫操作,需要在WritePage_24LC16B函數後添加150μs以上的延遲,這段時間,24C02內部需要將數據存儲到芯片內部。
例子:
D_buffer[8] = {1,2,3,4,5,6,7,8};
WritePage_24LC16B(D_buffer,0,8);
_delay(150); //延遲150μs以及以上
WritePage_24LC16B(D_buffer,8,8);
4、頁讀操作
void ReadPage_24LC16B(unsigned char *Rdata,unsigned int RomAddress,unsigned char cnt)
{
unsigned char block;
ReadDeviceAddress=0B10100001;
WriteDeviceAddress=0B10100000;
block=RomAddress/256;
RomAddress=RomAddress%256;
WriteDeviceAddress=WriteDeviceAddress|(block<<1);
ReadDeviceAddress=ReadDeviceAddress|(block<<1);
i2cStart();
WriteByte_24LC16B(WriteDeviceAddress);
WriteByte_24LC16B((unsigned char)RomAddress);
i2cStart();
WriteByte_24LC16B(ReadDeviceAddress);
while(cnt>1)
{
*Rdata++ = ReadByte_24LC16B();
cnt–;
i2cAck_MCU();//發送完讀地址後,需要應答一下
}
*Rdata = ReadByte_24LC16B();
i2cNoAck_MCU();//讀取最後一個字節需要非應答
i2cStop();
_delay(2000);
原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/231073.html