分享單片機編程步驟,c51單片機編程教程

自己學習記錄用,有些亂,

1、IIC,eeprom24c02驅動配置

本實驗是基於EEPROM的24C02驅動配置的編程,主要記錄一些編程的重點節點的理解:

1、IIC驅動配置:精準的時鐘配置,計算每一步所需要的指令周期,相加是10us。

c51單片機嵌入式開發總結2

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

c51單片機嵌入式開發總結2

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

c51單片機嵌入式開發總結2

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

c51單片機嵌入式開發總結2

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

c51單片機嵌入式開發總結2

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

c51單片機嵌入式開發總結2

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

c51單片機嵌入式開發總結2
c51單片機嵌入式開發總結2

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

c51單片機嵌入式開發總結2

2、24C02或者24C16進行字節、頁讀取、頁存取

  1. void i2cStart(void) //開始時序
  2. {
  3. SDA=1;
  4. SCL=1;
  5. _delay(2); //延時2μs
  6. SDA=0;
  7. _delay(2);
  8. SCL=0;
  9. }
  1. void i2cStop(void) //結束時序
  2. {
  3. SDA=0;
  4. _delay(2);
  5. SCL=1;
  6. _delay(2);
  7. SDA=1;
  8. }
  1. void i2cAck_MCU(void) //應答時序
  2. {
  3. SDA=0;
  4. _delay(2);
  5. SCL=1;
  6. _delay(2);
  7. SCL=0;
  8. _delay(2);
  9. SDA=1;
  10. _delay(4);
  11. }
  1. void i2cNoAck_MCU(void) //非應答時序
  2. {
  3. SDA=1;
  4. _delay(2);
  5. SCL=1;
  6. _delay(2);
  7. SCL=0;
  8. _delay(2);
  9. }

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

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
投稿專員的頭像投稿專員
上一篇 2024-12-10 18:46
下一篇 2024-12-10 18:46

相關推薦

發表回復

登錄後才能評論