久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 4738|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

[原創(chuàng)]51一個(gè)24C讀寫函數(shù),支持檢測(cè)器件型號(hào)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:43499 發(fā)表于 2012-8-2 21:39 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
 

        這個(gè)程序我檢測(cè)過24C02,24C16,24C04,24C64,24C32,均未出錯(cuò)。也沒有毀損器件內(nèi)部數(shù)據(jù)的問題。可靠性比較好。在我的編程器中已經(jīng)使用。此程序write by 萬致遠(yuǎn),在sdcc v3.1.0中無錯(cuò)誤/warning編譯。死太慘89C52中通過。

上代碼:


/* FILE 24C.C
Write by 萬致遠(yuǎn)
*/
#include <hwconfig.h>
#include <type-def.h>
#include <delay.h>
#include <i2c.h>
#include <24c.h>
#define AT24C02_DeviceAdd_W 0xa0    //器件地址(寫)
#define AT24C02_DeviceAdd_R 0xa1    //器件地址(讀)
#define ADD_TYPE_8    0
#define ADD_TYPE_16    1
#define AT24C01        0
#define AT24C02        1
#define AT24C04        2
#define AT24C08        3
#define AT24C16        4
#define AT24C32        5
#define AT24C64        6
#define AT24C128    7
#define AT24C256    8
#define AT24C512    9
#define AT24C1024    10
#define SCAN_ERROR    0xFF
ULONG __code Length_Chip[11]={
0x7f,0xff,0x1ff,0x3ff,0xfff,0x7ff,0x1fff,0x3fff,0x7fff,0xffff,0x1ffff
};//各類ROM的容量表~    
BYTE __code TEST_DATA[2]={0xAA,0xBB};    //測(cè)試數(shù)據(jù)
#define W_DELAY 4   //4 ms DELAY         
//----------------------------------------------
//24C操作函數(shù),頁寫。
//IIC_ADDR器件地址
//Address 16BIT地址
//TYPE    地址模式
//Data指針
//Len長度
//本函數(shù)不支持翻頁,請(qǐng)自行翻頁,控制IIC_Addr
BOOL RW24(BYTE IIC_Addr,UINT Address,BOOL Type,BYTE *Data,BYTE Len)
{
    BYTE i=0;
    //----------------------------選中芯片程序開始-----------
    I2C_Start();    // 啟動(dòng)I2C總線
    I2C_Write8Bit(IIC_Addr & 0xFE);                    // 發(fā)送器件地址(寫)1111 1110
    if( I2C_Check_Ack() == 0 )                        // 檢測(cè)從機(jī)應(yīng)答
            {I2C_Stop();return 0;      }
    if (Type==ADD_TYPE_8)
    {//8位地址的話
        I2C_Write8Bit(Address);                   // 發(fā)送將要處理的數(shù)據(jù)的地址,8位
    }
    else
    {//16位地址的話
        I2C_Write8Bit(((Address & 0xFF00)>>8));            //發(fā)送高八位地址
        if( I2C_Check_Ack() == 0 )                        // 檢測(cè)從機(jī)應(yīng)答
            {I2C_Stop();return 0;      }
        I2C_Write8Bit((Address & 0xFF));    //低八位地址發(fā)送
    }
    if( I2C_Check_Ack() == 0 )                        // 檢測(cè)從機(jī)應(yīng)答
            {I2C_Stop();return 0;      }
    //---------------------------------結(jié)束-------------------
    if((IIC_Addr & 0x01)==1)
    {//是讀操作
        *Data=0xFF;                                    //FF=NULL
        I2C_Start();                                 // 再次啟動(dòng)IIC總線
        I2C_Write8Bit(IIC_Addr);                    //發(fā)送讀出地址
        if( I2C_Check_Ack() == 0 )                // 檢測(cè)從機(jī)應(yīng)答
            {I2C_Stop();return 0;      }
        *Data = I2C_Read8Bit();                        // 讀取第一個(gè)數(shù)據(jù)
        Data++;
        for(i=1;i<Len;i++)
        {
            I2C_Send_Bit_0();//發(fā)送ACK
            *Data = I2C_Read8Bit();    //讀取數(shù)據(jù)
            Data++;//指針加一
        }                    
        I2C_Send_Bit_1();                             // 產(chǎn)生NAK信號(hào)結(jié)束讀取數(shù)據(jù)            
        I2C_Stop();    
        return 1;
    }
    else
    {//是寫操作
        for(i=0;i<Len;i++)
        {
            I2C_Write8Bit(*Data);
            //I2C_Write8Bit(0xff);
            if(I2C_Check_Ack()==0) {I2C_Stop();return 0;}
            Data++;
        }
        I2C_Stop();
        Delay_ms(W_DELAY);//加延時(shí)啊……要不然寫不進(jìn)……型號(hào)也會(huì)判斷錯(cuò)誤……5~6MS
        return 1;
    }
}
//---------------------------------------------------------------------------------------
//測(cè)試24C系列8BIT地址的一頁,檢測(cè)24C02~24C16
BOOL Page_Test(BYTE Page)
{
    BYTE tmp[3];
    RW24(AT24C02_DeviceAdd_R,0x00,ADD_TYPE_8,&tmp[0],1);//讀出原來數(shù)據(jù)
    RW24(AT24C02_DeviceAdd_R|Page,0x00,ADD_TYPE_8,&tmp[1],1);
    RW24(AT24C02_DeviceAdd_W,0x00,ADD_TYPE_8,&TEST_DATA[1],1);//修改數(shù)據(jù)寫入00單元1頁
    RW24(AT24C02_DeviceAdd_W|Page,0x00,ADD_TYPE_8,&TEST_DATA[0],1);//修改數(shù)據(jù)寫入00單元2頁
    RW24(AT24C02_DeviceAdd_R,0x00,ADD_TYPE_8,&tmp[2],1);//讀入
    RW24(AT24C02_DeviceAdd_W,0x00,ADD_TYPE_8,&tmp[0],1);//寫回?cái)?shù)據(jù)
    if(tmp[2]==0xAA)
    {//24C02
        //RW24(AT24C02_DeviceAdd_W,0x00,ADD_TYPE_8,&tmp[0],1);//寫回?cái)?shù)據(jù)
        return TRUE;
    }
                //RW24(AT24C02_DeviceAdd_W,0x00,ADD_TYPE_8,&tmp[0],1);//寫回?cái)?shù)據(jù)
    RW24(AT24C02_DeviceAdd_W|Page,0x00,ADD_TYPE_8,&tmp[1],1);    
    return FALSE;
}
//------------------------------------------------------------------------------------------------------
//--檢測(cè)24C32器件的地址溢出
//BOOL RW24(BYTE IIC_Addr,UINT Address,BOOL Type,BYTE *Data);
//ADDRESS 2為猜測(cè)的最高地址
BOOL Write_Test(UINT Address2,BOOL Add_Type)
{
    BYTE tmp[3];
    RW24(AT24C02_DeviceAdd_R,0,Add_Type,&tmp[0],1);//讀出0x0000單元數(shù)據(jù)
    RW24(AT24C02_DeviceAdd_R,Address2,Add_Type,&tmp[1],1);//讀出0x1000單元數(shù)據(jù)
    RW24(AT24C02_DeviceAdd_W,0,Add_Type,&TEST_DATA[1],1);//改變?cè)袛?shù)據(jù),避免干擾
    RW24(AT24C02_DeviceAdd_W,Address2,Add_Type,&TEST_DATA[0],1);//寫入0xAA到單元去,產(chǎn)生地址溢出
    RW24(AT24C02_DeviceAdd_R,0,Add_Type,&tmp[2],1);//讀出0000單元內(nèi)容
    RW24(AT24C02_DeviceAdd_W,0,Add_Type,&tmp[0],1);//寫回?cái)?shù)據(jù)
    if(tmp[2]==0xAA)//先前改變的數(shù)據(jù),如果產(chǎn)生溢出可以檢測(cè)到
    {
                //RW24(AT24C02_DeviceAdd_W,0x0000,Add_Type,&tmp[0],1);//寫回被(1)步驟更改的數(shù)據(jù)
                return TRUE;//返回正確
    }
            //RW24(AT24C02_DeviceAdd_W,0x0000,ADD_TYPE_16,&tmp[0],1);//寫回?cái)?shù)據(jù)
    RW24(AT24C02_DeviceAdd_W,Address2,Add_Type,&tmp[1],1);//寫回?cái)?shù)據(jù)
    return FALSE;
}
//------------調(diào)用此函數(shù)返回芯片類型
BYTE Test24()
{//測(cè)試24系列的容量
//24C16:Address=1010 P2 P1 P0 R/W

    BYTE tmp[3];
    //
     // read:
    //  8 Bit series: |start|address_w|address|start|address_r|data|stop|
     // 16 bit series:|start|address_w|address|address|start|address_r|data|stop|
    //  TEST:         |START|address_w|address|start|address_r|data|stop|
    //  write:
    //  8bit series:  |start|address_w|address|data|stop|
    //  16bit series: |start|address_w|address|address|data|stop|
     // 
     tmp[0]=0xff;
    if(RW24(AT24C02_DeviceAdd_R,0x00,ADD_TYPE_8,&tmp[0],1)==TRUE)//讀出0單元
    {//判斷是否是8bit series
        RW24(AT24C02_DeviceAdd_W,0x00,ADD_TYPE_8,&TEST_DATA[1],1);//寫入AA
        RW24(AT24C02_DeviceAdd_R,0x00,ADD_TYPE_8,&tmp[1],1);//再次讀出        
        if(tmp[1]==0xBB)
        {//8bit series無誤
        //我發(fā)現(xiàn)我還是在實(shí)際上出錯(cuò)了%……實(shí)際上寫頁還是寫的進(jìn)可是只有一個(gè)頁……
            RW24(AT24C02_DeviceAdd_W,0x00,ADD_TYPE_8,&tmp[0],1);//寫回?cái)?shù)據(jù),RW搞錯(cuò)了
            //測(cè)試是否24C01
            //24C01的地址范圍從0~127(0~7F),OK,向80H讀出,然后寫一個(gè)數(shù)據(jù)
            /*RW24(AT24C02_DeviceAdd_R,0x0000,ADD_TYPE_8,&tmp[0],1);//讀出0x0000單元數(shù)據(jù)【0】
            RW24(AT24C02_DeviceAdd_R,0x0080,ADD_TYPE_8,&tmp[1],1);//讀出0x80單元數(shù)據(jù)【1】
            RW24(AT24C02_DeviceAdd_W,0x0000,ADD_TYPE_8,&TEST_DATA[1],1);//寫入0000單元防止原來數(shù)據(jù)干擾
            RW24(AT24C02_DeviceAdd_W,0x0080,ADD_TYPE_8,&TEST_DATA[0],1);//寫入0000單元防止原來數(shù)據(jù)干擾
            RW24(AT24C02_DeviceAdd_R,0x0000,ADD_TYPE_8,&tmp[2],1);//寫入0000單元防止原來數(shù)據(jù)干擾
            RW24(AT24C02_DeviceAdd_W,0x0000,ADD_TYPE_8,&tmp[0],1);//寫回0單元數(shù)據(jù)
            if(tmp[2]==0xAA)
            {//24C01

                return AT24C01;
            }*/
            if(Write_Test(0x80,ADD_TYPE_8))
            {
                return AT24C01;
            }
                //這應(yīng)該是24C02 etc……絕對(duì)不可能是24C01,除非器件的80H單元正好壞了
                //24C16:Address=1010 P2 P1 P0 R/W
                //RW24(AT24C02_DeviceAdd_W,0x00,ADD_TYPE_8,&tmp[0],1);//寫回原來的數(shù)據(jù)到0x80
                //RW24(AT24C02_DeviceAdd_W,0x80,ADD_TYPE_8,&tmp[1],1);//寫回原來的數(shù)據(jù)0x00
                //----------------------------------------------------------------
                //MAX——PAGE 02 04  08  16
                //         000 001 011 111
                //-------TEST 24C02
                if(Page_Test(0x02))
                {
                    return AT24C02;
                }
                if(Page_Test(0x06))
                {
                    return AT24C04;
                }
                if(Page_Test(0x0E))
                {
                    return AT24C08;
                }
                return AT24C16;    
        }
        else
        {//AT24C32的地址范圍從0~4095(0xFFF)
        //AT24C64從0~8191(0x1FFF)
        //AT24C128從0~16383(0x3FFF)
        //AT24C256從0~32767(0x7FFF)
        //AT24C512從0~65535(0xFFFF)
        //AT24C1024從0~65535(0xFFFF),地址中多一個(gè)P1選擇位
        //從小試到大
        //測(cè)試24C1024
        //1010 0010 = 0x02
        //就是產(chǎn)生傳說中的地址溢出了……
        //-----24C1024
            if(RW24(AT24C02_DeviceAdd_R | 0x02,0xFFFF,ADD_TYPE_16,&tmp[0],1))//讀出第二頁的0xFFFE
            {//成功代表是24C1024
                return AT24C1024;
            }
        //優(yōu)化算法
        //-----24C32
            if(Write_Test(0x1000,ADD_TYPE_16))
            {
                return AT24C32;
            }
        //24C64
            if(Write_Test(0x2000,ADD_TYPE_16))
            {
                return AT24C64;
            }
        //24C128
            if(Write_Test(0x4000,ADD_TYPE_16))
            {
                return AT24C128;
            }
        //24C256
            if(Write_Test(0x8000,ADD_TYPE_16))
            {
                return AT24C32;
            }
            //-------------24C512*/
            return  AT24C512;

        }
        
    }
    else
    {
        return SCAN_ERROR;
    }
}

萬致遠(yuǎn)原創(chuàng),轉(zhuǎn)載注明出處:http://www.rwzy.co.cc

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:43499 發(fā)表于 2012-8-2 21:40 | 只看該作者
 這個(gè)在我的編程器項(xiàng)目KMPROG中應(yīng)用成功。
如果需要使用STC"1T"的單片機(jī)請(qǐng)適量加延時(shí)。
另外需要I2C.H
[此貼子已經(jīng)被作者于2012-8-2 21:40:26編輯過]
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 欧美日韩1区2区 | 精品视频一二区 | 在线播放精品视频 | 日本一区二区三区四区 | 视频在线一区二区 | 美女一级毛片 | 91视频久久 | 中文字幕精品一区二区三区精品 | 五月天国产 | 中文久久 | 激情国产视频 | 成人午夜在线 | av小说在线 | 欧美日韩国产高清 | 拍真实国产伦偷精品 | 精品欧美乱码久久久久久 | 久久中文字幕电影 | 日日操av| 五月婷亚洲 | 91av在线免费观看 | 国产成人免费视频 | 中文字幕在线播放第一页 | 欧美视频一区 | 欧美乱做爰xxxⅹ久久久 | 精品欧美一区二区精品久久久 | 欧美日韩国产在线观看 | 亚洲一区中文字幕 | 国产精品久久久久久久久久久免费看 | 国产一区日韩在线 | 午夜免费 | 天天看天天操 | 色综合一区二区 | 精品九九九 | 盗摄精品av一区二区三区 | 激情欧美一区二区三区中文字幕 | h片在线观看免费 | 97成人精品 | 久久精彩视频 | 欧美精品一区二区三区四区五区 | 欧美freesex黑人又粗又大 | 国产精品完整版 |