新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 關于51單片機模擬IIC總線的程序

        關于51單片機模擬IIC總線的程序

        作者: 時間:2016-11-26 來源:網(wǎng)絡 收藏
        下面是一個關于IIC總線的程序,用的是51單片機做控制器,對24c16的EEPROM進行數(shù)據(jù)的讀寫,由于51沒有IIC總線接口,所以需要根據(jù)IIC的協(xié)議模擬它進行數(shù)據(jù)傳輸。IIC是一中同步串口總線,scl為時鐘線,sda為數(shù)據(jù)線;scl為低時sda的數(shù)據(jù)允許變化,scl為高時sda的數(shù)據(jù)必須保持穩(wěn)定。同一個IIC總線根據(jù)器件地址的不同可以同時對多個器件進行讀寫,例如可以同時接8個24c16系列的EEPROM。

        本文引用地址:http://www.104case.com/article/201611/321664.htm

        下面的程序是一個時鐘程序,當斷電時將數(shù)據(jù)將保存在24c16中。重新上電后先讀出24c16中存的數(shù)據(jù),之后一直對24c16進行寫操作,這樣斷電就可以保持最后次數(shù)據(jù)在14c16里面了。

        對24c16系列的EEPROM寫的過程:起始信號 寫器件地址 應答寫地址 應答 寫數(shù)據(jù).....無應答 停止

        對24c16系列的EEPROM寫的過程:起始信號寫器件地址 應答寫地址 應答 重新開始 寫器件+1 應答 讀出數(shù)據(jù)停止

        #include
        #define uchar unsigned char
        sbit sda=P2^1;
        sbit scl=P2^0;
        sbit p1_0=P1^0;
        sbit p1_1=P1^1;
        sbit p1_2=P1^2;
        uchar a,tt;
        uchar tem=0;
        uchar code table[]={
        0x3f,0x06,0x5b,0x4f,
        0x66,0x6d,0x7d,0x07,
        0x7f,0x6f,0x77,0x7c,
        0x39,0x5e,0x79,0x71};
        void delay()
        { ;; }
        void start()//開始信號,scl在高電平時sda由高變低產(chǎn)生開始信號
        {
        sda=1;
        delay();
        scl=1;
        delay();
        sda=0;
        delay();
        }

        void stop()//停止信號,scl在高電平時sda由低變高產(chǎn)生停止信號

        {
        sda=0;
        delay();
        scl=1;
        delay();
        sda=1;
        delay();
        }

        void respons()//應答,sda為高時表示從機有應答,沒有就默認應答
        {
        uchar i;
        scl=1;
        delay();
        while((sda==1)&&(i<250))i++;
        scl=0;
        delay();
        }

        void init()//初始化定時器
        {
        sda=1;
        delay();
        scl=1;
        delay();
        TMOD=0x01;
        TH0=(65536-50000)/256;
        TH0=(65536-50000)%6;
        EA=1;
        ET0=1;
        TR0=1;
        p1_1=1;
        p1_0=1;
        }

        void write_byte(uchar date)//寫一個字節(jié)
        {
        uchar i,temp;
        temp=date;


        for(i=0;i<8;i++)
        {
        temp=temp<<1;
        scl=0;
        delay();
        sda=CY;//利用了CY這個移除來寫
        delay();
        scl=1;
        delay();
        scl=0;
        delay();
        }
        scl=0;
        delay();
        sda=1;
        delay();
        }

        uchar read_byte()//讀一個字節(jié)
        {
        uchar i,k;
        scl=0;
        delay();
        sda=1;//釋放sda
        delay();
        for(i=0;i<8;i++)
        {
        scl=1;
        delay();
        k=(k<<1)|sda;//讀出來的字節(jié)存在k中
        scl=0;
        delay();
        }
        return k;
        }

        void delay1(uchar x)
        {
        uchar a,b;
        for(a=x;a>0;a--)
        for(b=110;b>0;b--);
        }

        void write_add(uchar address,uchar date)//寫數(shù)據(jù)的整個過程

        {
        start();
        write_byte(0xa0);//a0為從機器件地址,最后位為0表示寫
        respons();
        write_byte(address);//要寫的地址
        respons();
        write_byte(date);//要寫的數(shù)據(jù)
        respons();
        stop();
        }

        uchar read_add(uchar address))//讀數(shù)據(jù)的整個過程
        {
        uchar date;
        start();
        write_byte(0xa0);
        respons();
        write_byte(address);//待讀數(shù)據(jù)的地址
        respons();
        start();//由寫變?yōu)樽x的過程需要重新執(zhí)行start的過程
        write_byte(0xa1);//最后位為一表示讀
        respons();
        date=read_byte();//讀出數(shù)據(jù)
        stop();
        return date;
        }

        void main()
        {

        uchar shi,ge;
        init();

        if(read_add(20))
        {
        tem=read_add(20);
        }
        else
        {
        tem=0;
        }
        while(1)
        {

        if(tem>99)
        {
        tem=0;
        }

        shi=tem/10;
        ge=tem;
        p1_1=0;
        P3=table[shi];
        delay1(14);
        p1_1=1;
        p1_0=0;
        P3=table[ge];
        delay1(14);
        p1_0=1;
        }

        }
        void zhongd() interrupt 1

        {
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%6;
        tt++;
        if(tt==20)
        {
        tt=0;
        tem++;
        write_add(20,tem);
        }
        }



        評論


        技術專區(qū)

        關閉
        主站蜘蛛池模板: 马公市| 额济纳旗| 霍林郭勒市| 萨迦县| 东丽区| 迭部县| 广汉市| 襄垣县| 桐城市| 增城市| 墨玉县| 农安县| 伊春市| 明光市| 天镇县| 林口县| 涿鹿县| 武乡县| 宁晋县| 共和县| 合山市| 阜南县| 阜新市| 鸡泽县| 边坝县| 夏邑县| 芮城县| 都江堰市| 米易县| 富阳市| 泾阳县| 临猗县| 合川市| 罗城| 曲阜市| 石渠县| 澎湖县| 五河县| 夏津县| 汝州市| 开封县|