0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

通過IIC總線讀寫AT24C512存儲(chǔ)器

CHANBAEK ? 來源:小小硬件工程師 ? 作者:小小硬件工程師 ? 2023-11-09 10:00 ? 次閱讀

今天要講的是通過IIC總線來讀寫AT24C512存儲(chǔ)。我們?cè)陂_發(fā)一些項(xiàng)目的時(shí)候,如果要求對(duì)有些參數(shù)進(jìn)行存儲(chǔ),且掉電不丟失的話,我們就需要一些外部存儲(chǔ)器件,比如說今天要講的AT24C512存儲(chǔ)器。下面就來看一下今天的例程吧!

一、硬件電路

實(shí)現(xiàn)仿真電路如下,圖中U1為AT89C51,其中U1掃描P1口的輸入,并根據(jù)不同的按鍵執(zhí)行不同的操作,并顯示運(yùn)行結(jié)果。本實(shí)驗(yàn)中,液晶模塊掛接在單片機(jī)的總線上,用讀(RD)和寫(WR)信號(hào)實(shí)現(xiàn)數(shù)據(jù)的傳輸;用U2即74LS373鎖存低位地址(A0~A1)U4為24C02器件,其A0、A1、A2引腳接地,故其寫地址為0xa0,讀地址為0xa1。SCK接P3.4,SDA接P3.5。WP接地。另外原理圖中增加了IIC調(diào)試器。

圖片

二、軟件程序

C程序:

#include < reg51.h >
#include < absacc.h >


#define REG0   XBYTE[0x0000]  //LCD寫指令寄存器的地址,可根據(jù)配置修改
#define REG1   XBYTE[0x0001]  //LCD讀出數(shù)據(jù)到D0~D7的地址,可根據(jù)配置修改
#define REG2   XBYTE[0x0002]  //LCD寫數(shù)據(jù)寄存器的地址,可根據(jù)配置修改
#define REG3   XBYTE[0x0003]  //LCD讀數(shù)據(jù)寄存器的地址,可根據(jù)配置修改


unsigned char bdata busyflag;
unsigned char dat,datn;


unsigned char word1[16]={" This programm "};  //第1行顯示緩存
unsigned char word2[16]={"  by LiXueli "};    //第2行顯示緩存
code unsigned char word3[16]={"www.bitc.edu.cn!"};  //用于固定顯示的數(shù)據(jù),固化到ROM
code unsigned char word4[16]={"bitclxl@126.com!"};  //用于固定顯示的數(shù)據(jù),固化到ROM中
code unsigned char word5[16]={"  Wellcome To "};  //用于固定顯示的數(shù)據(jù),固化到ROM中
code unsigned char word6[16]={" Proteus Tools!"};  //用于固定顯示的數(shù)據(jù),固化到ROM中


sbit busyflag_7=busyflag^7;
sbit p10=P1^0;
sbit p11=P1^1;
sbit p12=P1^2;
sbit p13=P1^3;
sbit p14=P1^4;
sbit p15=P1^5;
sbit p16=P1^6;
sbit p17=P1^7;
//////////////////////////////////////start of IIC ////////////////////////////
#define uchar unsigned char
#define uint  unsigned int
#include "reg51.h"
#include "intrins.h"


sbit  Scl=P3^4;  //串行時(shí)鐘
sbit  Sda=P3^5;  //串行數(shù)據(jù)






/*發(fā)送起始條件*/
void Start(void)        /*起始條件*/
{
        Sda=1;
        Scl=1;
        _nop_ ();
        _nop_ ();
        _nop_ ();
        _nop_ ();
        Sda=0;
        _nop_ ();
        _nop_ ();
        _nop_ ();
        _nop_ ();
}
void Stop(void) /*停止條件*/
{
        Sda=0;
        Scl=1;
        _nop_ ();
        _nop_ ();
        _nop_ ();
        _nop_ ();
        Sda=1;
        _nop_ ();
        _nop_ ();
        _nop_ ();
        _nop_ ();
}
void Ack(void)  /*應(yīng)答位*/
{
        Sda=0;
        _nop_ ();
        _nop_ ();
        _nop_ ();
        _nop_ ();
        Scl=1;
        _nop_ ();
        _nop_ ();
        _nop_ ();
        _nop_ ();
        Scl=0;
}
void  NoAck(void)       /*反向應(yīng)答位*/
{
        Sda=1;
        _nop_ ();
        _nop_ ();
        _nop_ ();
        _nop_ ();
        Scl=1;
        _nop_ ();
        _nop_ ();
        _nop_ ();
        _nop_ ();
        Scl=0;
}
void Send(uchar Data)   /*發(fā)送數(shù)據(jù)子程序,Data為要求發(fā)送的數(shù)據(jù)*/
{
        uchar BitCounter=8;       /*位數(shù)控制*/
        uchar temp;     /*中間變量控制*/
        do
        {
           temp=Data;
           Scl=0;
           _nop_ ();
           _nop_ ();
           _nop_ ();
           _nop_ ();
           if((temp&0x80)==0x80)/* 如果最高位是1*/
                Sda=1;
           else
                Sda=0;
           Scl=1;
           temp=Data< 1;        /*RLC*/
           Data=temp;
           BitCounter--;
         }while(BitCounter);
         Scl=0;
}
uchar Read(void) /*讀一個(gè)字節(jié)的數(shù)據(jù),并返回該字節(jié)值*/
{
        uchar temp=0;
        uchar temp1=0;
        uchar BitCounter=8;
        Sda=1;
        do{
          Scl=0;
          _nop_ ();
          _nop_ ();
          _nop_ ();
          _nop_ ();
          Scl=1;
          _nop_ ();
          _nop_ ();
          _nop_ ();
          _nop_ ();
          if(Sda)       /*如果Sda=1;*/
                temp=temp|0x01;  /*temp的最低位置1*/
          else
                temp=temp&0xfe;  /*否則temp的最低位清0*/
          if(BitCounter-1)
          {   temp1=temp< 1;
              temp=temp1;
          }
          BitCounter--;
        }while(BitCounter);
        return(temp);
}
void WrToROM(uchar Data[],uchar Address,uchar Num)//寫入一組數(shù)據(jù)到AT24C02中
{     //參數(shù)為數(shù)組的首地址,數(shù)據(jù)在AT24C02中的開始地址,數(shù)據(jù)個(gè)數(shù)
     uchar i=0;
     uchar *PData;
     PData=Data;
     Start();        
     Send(0xa0);    //A0、A1、A2接地,固AT24C02的寫地址為0XA0
     Ack();
     Send(Address);  
     Ack();
     for(i=0;i< Num;i++)
     {
        Send(*(PData+i));
        Ack();
     }
     Stop();
}
void  RdFromROM(uchar Data[],uchar Address,uchar Num)//讀出一組數(shù)據(jù)到AT24C02中
     //參數(shù)為數(shù)組的首地址,數(shù)據(jù)在AT24C02中的開始地址,數(shù)據(jù)個(gè)數(shù)
{
     uchar i=0;
     uchar *PData;
     PData=Data;
     for(i=0;i< Num;i++)
     {
        Start();
        Send(0xa0); //A0、A1、A2接地,固AT24C02的寫地址為0XA0
        Ack();
        Send(Address+i);
        Ack();
        Start();
        Send(0xa1); //A0、A1、A2接地,固AT24C02讀地址為0XA1
        Ack();
        *(PData+i)=Read();
        Scl=0;
        NoAck();
        Stop();
   }
}
/////////////////////////////////END of IIC/////////////////////////////////
void busy()    //查詢LCD是否忙碌子程序
{
  do
  {
    busyflag=REG1;
  }while(busyflag_7);
}
void wrc(unsigned char wcon)  //寫控制指令子程序
{
  busy();
  REG0=wcon;
}
void wrd(unsigned char wdat)  //寫數(shù)據(jù)寄存器子程序
{
  busy();
  REG2=wdat;
}
void rdd()  //讀數(shù)據(jù)寄存器子程序
{
  busy();
  dat=REG3;
}
void lcdint()  //LCD初始化子程序
{
  wrc(0x38);  
  wrc(0x01);
  wrc(0x06);
  wrc(0x0c);
}
void wrn(unsigned char word[])  //連續(xù)寫n個(gè)字符數(shù)據(jù)到LCD的數(shù)據(jù)寄存器中
{
  unsigned char i;
  for(i=0;i< 16;i++)
  {
    wrd(word[i]);
  }
}
void main()
{
    unsigned char i;
    lcdint();  //初始化
    wrc(0x80);  //顯示第1行的第1個(gè)字符
    wrn(word1);
    wrc(0xc0);  //顯示第2行的第1個(gè)字符
    wrn(word2);


        while(1)
    {
            if(p10==0) //判斷P1.0是否按下,寫入數(shù)據(jù)到EEPROM中
      {
        for(i=0;i< 16;i++)
          word1[i]='d';
        WrToROM(word1,0x00,16);
        wrc(0x80);
        wrn(word1);


      }
      if(p11==0) //判斷P1.1是否按下,并顯示數(shù)據(jù)
      {
        RdFromROM(word2,0x00,16);
        WrToROM(word2,0x80,16);
        wrc(0x80);
        wrn(word1);
        wrc(0xc0);
        wrn(word2);
      }
      if(p12==0) //判斷P1.2是否按下,并顯示數(shù)據(jù)
      {
        wrc(0x80);
        wrn(word3);
        wrc(0xc0);
        wrn(word4);
      }
      if(p13==0) //判斷P1.3是否按下,并顯示數(shù)據(jù)
      {
        wrc(0x80);
        wrn(word5);
        wrc(0xc0);
        wrn(word6);
      }
      if(p14==0) //判斷P1.4是否按下,并顯示數(shù)據(jù)
      {
        wrc(0x80);
        wrn(word3);
        wrc(0xc0);
        wrn(word4);
      }
      if(p15==0) //判斷P1.5是否按下,并顯示數(shù)據(jù)
      {
        wrc(0x80);
        wrn(word5);
        wrc(0xc0);
        wrn(word6);
      }
      if(p16==0)//判斷P1.6是否按下,并顯示數(shù)據(jù)
      {
        wrc(0x80);
        wrn(word3);
        wrc(0xc0);
        wrn(word4);
      }
      if(p17==0)//判斷P1.7是否按下,并顯示數(shù)據(jù)
      {
        wrc(0x80);
        wrn(word5);
        wrc(0xc0);
        wrn(word6);
      }
    }
}

三、仿真展示

程序很簡(jiǎn)單,小伙伴們可以根據(jù)需要自己修改程序,然后進(jìn)行驗(yàn)證哦!

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 單片機(jī)
    +關(guān)注

    關(guān)注

    6030

    文章

    44489

    瀏覽量

    631960
  • 存儲(chǔ)器
    +關(guān)注

    關(guān)注

    38

    文章

    7430

    瀏覽量

    163514
  • IIC總線
    +關(guān)注

    關(guān)注

    1

    文章

    66

    瀏覽量

    20273
  • AT24C512
    +關(guān)注

    關(guān)注

    0

    文章

    7

    瀏覽量

    7275
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    在RTX51TINY系統(tǒng)上對(duì)at24c512中的數(shù)據(jù)讀取疑難??

       當(dāng)我在89s52外擴(kuò)的一個(gè)數(shù)據(jù)存儲(chǔ)器AT24C512)上用調(diào)試助手讀取里面的數(shù)據(jù)時(shí) 怎么丟了2/3的數(shù)據(jù)呢 ? 讀取用的是在rtx51tiny上用的是在
    發(fā)表于 03-15 09:36

    AVR AT24C512

    我用ATmega16在proteus中仿真TWI總線,在對(duì)AT24C512連續(xù)讀寫n字節(jié)時(shí)發(fā)現(xiàn),雖然AT24C512的地址會(huì)自動(dòng)移向下一個(gè)存儲(chǔ)
    發(fā)表于 11-04 11:47

    PIC16F877A在proteus中讀寫AT24C512

    此時(shí)把I2C DEBUGGER的SCL線連接到PIC16F877A和AT24C512的SCL線上,這樣PIC16F877A可以正常的寫AT24C512。當(dāng)PIC16F877A發(fā)送啟動(dòng)信號(hào)且正常啟動(dòng)
    發(fā)表于 12-30 16:09

    【NUCLEO-F412ZG試用體驗(yàn)】+AT24C512 IIC EEPROM+W25Q128 SPI FLASH兩 大初級(jí)存儲(chǔ)器實(shí)驗(yàn)

    AT24CXX系列是ATMEL公司研發(fā)的IIC總線通信的EEPROM(電子可擦除存儲(chǔ)器),XX的數(shù)字代表單元格數(shù)量,以今天用到的AT24C512
    發(fā)表于 02-18 20:00

    存儲(chǔ)器AT24C512電子資料

    概述:AT24C512雙列20腳和8腳塑料、貼片雙列、薄型貼面BGA封裝。
    發(fā)表于 04-14 06:57

    IIC及AT24C02的讀寫

    IIC及AT24C02的讀寫(單片機(jī)實(shí)驗(yàn))有問題歡迎私信哦課程設(shè)計(jì)(綜合實(shí)驗(yàn))內(nèi)容及要求通過IIC總線
    發(fā)表于 07-16 06:27

    如何使用IIC總線和AT24C02存儲(chǔ)芯片去讀寫代碼呢

    AT24C02存儲(chǔ)芯片有哪些功能特性?IIC總線有哪些特征呢?如何使用IIC總線和AT
    發(fā)表于 11-25 06:45

    stm32單片機(jī)是如何對(duì)EEPROM AT24C512進(jìn)行讀寫

    移植的正點(diǎn)原子的代碼,開始使用的AT24C02,讀寫沒問題,但是換了AT24C512之后發(fā)現(xiàn),寫入成功,但讀出的數(shù)據(jù)一直是FF,通過修改IIC
    發(fā)表于 11-26 08:32

    at24c512中文資料

    AT24C512是ATMEL公司生產(chǎn)的64KB串行電可擦的可編程存儲(chǔ)器,內(nèi)部有512頁,每一頁為128字節(jié),任一單元的地址為16位,地址范圍為0000-0FFFH.它采用8引腳封裝,具有結(jié)構(gòu)緊湊,
    發(fā)表于 08-13 16:24 ?904次下載
    <b class='flag-5'>at24c512</b>中文資料

    AT24C512存儲(chǔ)器在無線抄表中的應(yīng)用

    介紹_r AT24C512存儲(chǔ)器的特性、工作狀態(tài)和讀寫時(shí)序,并應(yīng)用于無線抄喪中.該芯片可 儲(chǔ)抄表系統(tǒng)所有的抄表信息,由此,增加系統(tǒng)的可靠性,降低系統(tǒng)成本及功耗.關(guān)鍵詞:
    發(fā)表于 10-06 09:09 ?18次下載

    單片機(jī)是如何對(duì)AT24C512中的數(shù)據(jù)進(jìn)行系統(tǒng)化管理的?

    AT24C512是Atmel公司生產(chǎn)的64KB串行電可擦的可編程存儲(chǔ)器,內(nèi)部有512頁,每一頁為128字節(jié),任一單元的地址為16位,地址范圍為0000~0FFFFH。它采用8引腳封裝,具有結(jié)構(gòu)緊湊
    發(fā)表于 07-31 07:28 ?2127次閱讀
    單片機(jī)是如何對(duì)<b class='flag-5'>AT24C512</b>中的數(shù)據(jù)進(jìn)行系統(tǒng)化管理的?

    模擬IIC讀寫總結(jié)之at24c512讀寫程序

    用at24c02改的at24c512的程序,包含主程序和模擬程序,可以直接用。還有問題總結(jié),包含奇數(shù)位亂碼問題和讀寫0xff問題。大佬請(qǐng)路過,新手請(qǐng)?zhí)接?。(用的瑞薩的片子,就不上項(xiàng)目了,你們也打不開,不懂得就問問吧)
    發(fā)表于 12-31 22:41 ?95次下載

    AT24C512C芯片介紹_AT24C512C芯片怎么燒寫程序

    AT24C512是Atmel公司生產(chǎn)的64KB串行電可擦的可編程存儲(chǔ)器,內(nèi)部有512頁,每一頁為128字節(jié),任一單元的地址為16位,地址范圍為0000~0FFFFH。
    發(fā)表于 01-09 16:21 ?1.9w次閱讀
    AT<b class='flag-5'>24C512C</b>芯片介紹_AT<b class='flag-5'>24C512C</b>芯片怎么燒寫程序

    stm32單片機(jī)讀寫EEPROM AT24C512

    移植的正點(diǎn)原子的代碼,開始使用的AT24C02,讀寫沒問題,但是換了AT24C512之后發(fā)現(xiàn),寫入成功,但讀出的數(shù)據(jù)一直是FF,通過修改IIC
    發(fā)表于 11-19 09:21 ?55次下載
    stm32單片機(jī)<b class='flag-5'>讀寫</b>EEPROM <b class='flag-5'>AT24C512</b>

    IIC及AT24C02的讀寫(單片機(jī)實(shí)驗(yàn))

    IIC及AT24C02的讀寫(單片機(jī)實(shí)驗(yàn))有問題歡迎私信哦課程設(shè)計(jì)(綜合實(shí)驗(yàn))內(nèi)容及要求通過IIC總線
    發(fā)表于 11-22 09:21 ?73次下載
    <b class='flag-5'>IIC</b>及AT<b class='flag-5'>24C</b>02的<b class='flag-5'>讀寫</b>(單片機(jī)實(shí)驗(yàn))