硬體和軟體相容i2c協議的24Cxx系列EEPROM儲存空間

來源:互聯網
上載者:User

標籤:

源:硬體和軟體相容i2c協議的24Cxx系列EEPROM儲存空間

 

硬體上由於24c01的A0A1A2管腳不允許懸空,故暫時的想法是相容24c02 ---24c16

使用一個dip8封裝的晶片插座,A0 A1 A2管腳都懸空即可,換晶片方便

軟體上24c02地址只有8位,而其他型號是大於8位的,故地址參數使用16位

256個位元組作為一個大頁,即largePage,測試晶片24c04空間有512位元組

 

上代碼,求測試和討論

#include "MY51.H"//轉載請註明:http://xouou.iteye.com  求測試討論//stc89c52rc,11.0592MHz晶振sbit sda=P2^0;        //匯流排串連口定義sbit scl=P2^1;        //匯流排串連口定義void delayus()         //需要4個機器周期,大概4.34us{    ;                //晶振頻率11.0592M,機器周期為1.085微秒}void iic_start()      //啟動訊號{    sda=1;    scl=1;    delayus();        //sda和scl同為高電平保持4.7us以上    _nop_();        //1.085us,共5.78us    sda=0;             //下降沿    delayus();        //sda低電平保持4us以上    ,這裡是4.34us滿足要求}void iic_stop()        //停止訊號{    sda=0;_nop_();    //準備狀態    scl=1;    delayus();        //該狀態穩定時間要求保持4us以上    sda=1;            //scl高電平期間,sda來一個上升沿    delayus();        //sda保持4.7us以上,4.34加上函數返回時間大於4.7us                    //注:此時scl和sda都為1    }void iic_sendByte(u8 byteData) //mcu發送一個位元組{    u8 i;    u8 temp=byteData;    for(i=0;i<8;i++)    {        temp=temp<<1;    //移動後最高位到了PSW寄存器的CY位中        scl=0;             //準備        _nop_();         //穩定一下        sda=CY;             //將待發送的資料一位位的放到sda上        _nop_();        scl=1;             //每一個高電平期間,ic器件都會將資料取走        _nop_();            }    scl=0;                 //如果寫成scl=1;sda=1就是停止訊號,不能這麼寫    _nop_();                    sda=1;                 //釋放匯流排,資料匯流排不用時要釋放    _nop_();}u8 iic_readByte()             //讀一個位元組{    u8 i,temp;    scl=0;                    //準備讀資料    _nop_();    sda=1;                    //釋放匯流排    _nop_();    for(i=0;i<8;i++)    {        scl=1;                //mcu開始取資料        delayus();            //scl為高電平後,ic器件就會將1位元據送到sda上                            //總共用時不會大於4.34us,然後就可以讓mcu讀sda了        temp=(temp<<1)|sda; //讀一位儲存到temp中        scl=0;        delayus();            }    return temp;}bool iic_checkACK()          //處理應答訊號{    u8 errCounts=255;       //定義逾時量為255次    scl=1;    _nop_();        while(sda)              //在一段時間內檢測到sda=0的話認為是應答訊號    {            if(0==errCounts)        {            scl=0;          //鉗住匯流排            _nop_();            return FALSE; //沒有應答訊號        }        errCounts--;    }    scl=0;                 //鉗住匯流排,為下1次通訊做準備     _nop_();    return TRUE;         //成功處理應答訊號}void iic_init()             //匯流排初始化{    scl=1;    sda=1;    delayus();}void iic_sendACK(bool b_ACK)  //發送應答或非應答訊號{    scl=0;            //準備    _nop_();    if(b_ACK)        //ACK    發送應該訊號    {        sda=0;    }    else            //unACK    發送非應答訊號    {        sda=1;    }    _nop_();    scl=1;    delayus();         //大於4us的延時    scl=0;            //鉗住scl,以便繼續接收資料        _nop_();}void AT24Cxx_writeByte(u16 address,u8 dataByte)//向24cxx寫一位元組資料{    u8 largePage     = address/256;      //24c04是512位元組(定址範圍0~511),largePage最大值是1    u8 addressOffset = address%256;   //largePage=0的話位址範圍是(0~255)    iic_start();    iic_sendByte(0xa0|(largePage<<1));//控制字,前4位固定1010,後三位是器件地址,末位0是寫    iic_checkACK();                      //mcu處理應答訊號    iic_sendByte(addressOffset);        //指定要寫入的器件內地址在    largePage塊中的位移    iic_checkACK();    iic_sendByte(dataByte);           //寫資料    iic_checkACK();    iic_stop();    delayms(2);        //按位元組寫入時,24cxx在接收到停止訊號後將資料擦寫到內部,這需要時間    //並且在這段時間內不會響應匯流排上的任何請求,故讓mcu有2毫秒以上的等待    }void AT24Cxx_writeData(u16 address,u8 numBytes,u8* buf)//寫入任意長度資料(最大256位元組){    while(numBytes--)    {        AT24Cxx_writeByte(address++,*buf++);    }}void AT24Cxx_readData(u16 beginAddr,u8 dataSize,u8* buf)//讀取任意長度位元組到緩衝區buf中{    u8 largePage     = beginAddr/256;    //計算largePage,256位元組為一大頁    u8 addressOffset = beginAddr%256;    //計算相對於largePage的位移    iic_start();                          //起始訊號    iic_sendByte(0xa0|(largePage<<1));    //控制字,寫    iic_checkACK();                        //處理應答訊號    iic_sendByte(addressOffset);        //要讀取的目標地址位移    iic_checkACK();                        //處理應答訊號        iic_start();                           //發送起始訊號    iic_sendByte(0xa1|(largePage<<1));    //控制字,讀    iic_checkACK();                        //處理應答訊號    while(dataSize--)                    //讀取dataSize個位元組,最大256個位元組    {                                    //dataSize用u16類型會暴掉ram的        *buf++=iic_readByte();            //讀取一個個位元組並儲存到緩衝區buf中        iic_sendACK(dataSize);          //發送應答,當dataSize為0時mcu發送非應答    }    iic_stop();                            //發送停止訊號}void main()//測試{    u8 buf[3];                                        //接受資料的緩衝區    u8 arr[7]={0x06,1,2,3,4,0x55,0x33};                //待寫入的資料                            iic_init();                                        //匯流排初始化    AT24Cxx_writeData(0x00+256,sizeof(arr),arr);    //向指定地址處開始寫入7位元組的資料    P1=0xff;                                         //調試代碼,用P1口的led顯示    delayms(1000);                                     //調試代碼    AT24Cxx_readData(0x00+256,sizeof(buf),buf);       //從指定地址開始讀3個位元組    P1=buf[2];    //也就是2                                    //led燈顯示數值                                                while(1)    {        P1=~P1;        delayms(500);            } }

 

//my51.h中主要用到#include <reg52.h>#include "mytype.h"void delayms(u16 ms)     //軟延時函數{    u16 i,j;    for(i=ms;i>0;i--)    {        for(j=113;j>0;j--)        {}    }}

 

對代碼進行了改進 去掉了在寫資料時的 delayms(2);這句軟延時代碼低效 ,而且沒有保障 改成加一個檢測函數 bool check_icWriteComplete()   //檢測eeprom是否對內部擦寫完成 {  iic_start();  iic_sendByte(0xa0);  return iic_checkACK(); }

 

硬體和軟體相容i2c協議的24Cxx系列EEPROM儲存空間(轉)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.