• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 新聞中心

    EEPW首頁 > 嵌入式系統 > 設計應用 > I^2C總線EEPROM編程心得

    I^2C總線EEPROM編程心得

    作者: 時間:2016-11-28 來源:網絡 收藏
    相比起學校教材所用的8031+鎖存器+存儲芯片的組合搭建(不過貌似這種組合只有教科書才用),8952+AT24CXX的組合已經完全夠用而且可以很明確地將AT24CXX功能定位在掉電數據存儲。
    自己在進行電子鐘的編程中,將AT24C02作為了鬧鐘定時保存的存儲,因為操作方便,很適合作為程序附加功能的拓展,比如電子密碼儲存部件等等。對于沒接觸過的人來說,唯一頭痛的就是I^2C總線的軟件模擬編程,雖然只有SCL和SDA兩條通訊線以及高低電平,上下沿幾種狀態加以組合,但是單調得難以理解,尤其延時應該是多少,應答怎么實現這些問題都很困擾。I^2C總線是AT24CXX硬件自帶,而常見8952不自帶的,所以進行交互通訊時,需要在8952上運行軟件模擬。相關的原理解釋網上很多,這里建立在理解了原理的基礎上,進行程序分析:在保證程序能正常工作的前提下,進行了延時最短處理

    //24C02的初始化
    void c02_init()
    {
    scl=1;
    sda=1;
    }
    //開啟I^C總線
    void start()
    {
    sda=1;
    nop();
    scl=1;
    nop();
    sda=0;
    nop();
    scl=0;
    nop();
    }
    //停止I^2C總線
    void stop()
    {
    sda=0;
    nop();
    scl=1;
    nop();
    sda=1;
    nop();
    }

    本文引用地址:http://www.czjhyjcfj.com/article/201611/323083.htm

    //前面總線開關操作和初始化好理解,看著說明書的原理波形就能夠寫出

    //發送8位數據

    //之前還真不知道數據是這樣一位位賦值傳遞的
    void s_byte(uchar s_dat)
    {
    uchar i;
    for(i=0;i<8;i++)
    {
    s_dat<<=1;//最高位再左移就會寫入到 CY
    scl=0;
    nop();
    sda=CY;//如此類推將每次左移讀CY值,直到讀完8位
    scl=1;//SCL=1,保留數據。SCL=0,改變數據。
    nop();
    }
    scl=0;
    nop();
    sda=1;
    nop();
    }

    //讀取8位數據
    uchar r_byte()
    {
    uchar i,k=0;
    for(i=0;i<8;i++)
    {
    scl=1;
    nop();
    k<<=1;
    if(sda)
    {
    k++;
    }
    scl=0;
    nop();
    }
    return k;
    }

    //從件應答
    void ack()
    {
    uchar i;
    scl=1;
    nop();

    scl=0;
    //參考了很多程序還是這個好理解,有應答時SDA==0跳出,沒有應答等待i累加完畢也退出。

    //但是應答這樣用貌似沒有什么意義。在無應答時,是不是該轉入其他操作?

    while((sda==1)&&i<(200))i++;
    scl=0;
    nop();
    }

    //寫入函數

    void c02_write(uchar w_add,uchar w_dat)
    {
    start();
    s_byte(0xa0);
    ack();
    s_byte(w_add);
    ack();
    s_byte(w_dat);
    ack();
    stop();
    delay(5);
    }

    //讀取函數,這個是任意地址的讀取函數。包含了當前地址讀取的操作
    uchar c02_read(uchar r_add)
    {
    start();
    //這里要注意,向從件寫入一個地址(r_add),讓接收器件自己比對是否相同.故先送一個寫入驅動(0xa0)

    s_byte(0xa0);
    ack();
    s_byte(r_add);
    ack();

    //進行讀寫入驅動前,都要重新開啟總線 start();
    start();

    //確定了地址之后,才進行真正的寫入操作。
    s_byte(0xa1);
    ack();
    return r_byte();
    stop();
    delay(10);
    }

    其中應答很多人說可有可無,假如EEPROM是作為實現單一功能的主要元件,比如密碼鎖的存儲器,必須做到功能的盡善盡美,我覺得是要的。假如像我一樣作為電子鐘許多附加程序的其中一個,為了節省運算時間,無奈地不應答也能接受吧?吧?吧?不知道哩……

    最后使用write(w_add,w_dat);和read(r_add);就可以方便調用了。記得在這兩個函數使用前先調用初始化函數。



    評論


    技術專區

    關閉
    主站蜘蛛池模板: 南川市| 定州市| 扶沟县| 嘉峪关市| 历史| 都安| 邹城市| 重庆市| 津南区| 交口县| 承德县| 金乡县| 儋州市| 蕲春县| 谷城县| 枣阳市| 凤翔县| 肃宁县| 峡江县| 鲁甸县| 名山县| 措勤县| 高雄县| 师宗县| 江油市| 淮滨县| 横山县| 石嘴山市| 克拉玛依市| 高碑店市| 乌拉特后旗| 邢台县| 莱阳市| 平原县| 武强县| 乌苏市| 达尔| 五莲县| 仙居县| 临泽县| 冷水江市|