在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 51單片機(jī) 普通IO口模擬IIC(I2C)接口通訊的程序代碼

            51單片機(jī) 普通IO口模擬IIC(I2C)接口通訊的程序代碼

            作者: 時(shí)間:2018-08-06 來(lái)源:網(wǎng)絡(luò) 收藏

            I2C總線是Philips公司提出的一種集成電路IC器件之間相連接的總線協(xié)議,其目的是使電子系統(tǒng)(不只 限于單片機(jī)系統(tǒng))各個(gè)IC器件之間的連線變得容易。因?yàn)槭褂脗鹘y(tǒng)的并行總線在IC器件之間連接,往往會(huì)使得IC之間連線較多,顯得非常復(fù)雜。而I2C總線 則使IC器件之間只需SDA、SCL兩條連線就可以傳送數(shù)據(jù),因而十分方便。由于I2C在印刷體中不容易書(shū)寫(xiě)(需要上標(biāo)),所以實(shí)際書(shū)寫(xiě)時(shí),還常見(jiàn)到 IIC、I2C等書(shū)寫(xiě)方法,本文采用IIC的寫(xiě)法,敬請(qǐng)注意。關(guān)于IIC總線的知識(shí),請(qǐng)參閱相關(guān)書(shū)籍,此處不再做進(jìn)一步介紹。

            本文引用地址:http://www.biyoush.com/article/201808/385451.htm

            下面我們用一個(gè)使用IIC總線連接器件的例子來(lái)簡(jiǎn)單說(shuō)明IIC總線的仿真。

            例.EEPROM24C02是采用IIC接口的一種常用2Kbit(256×8bit)的存儲(chǔ)器。編寫(xiě)程序使用AT89C51的IO口模擬實(shí)現(xiàn)IIC總線協(xié)議進(jìn)行通信,并向24C02存儲(chǔ)器內(nèi)從字節(jié)0到字節(jié)FF寫(xiě)入數(shù)字0到FF。

            51系列單片機(jī)本身沒(méi)有IIC接口,但一些本身具有IIC接口的單片機(jī)往往是高端產(chǎn)品,一方面價(jià)格不菲,另一方面我們的系統(tǒng)也沒(méi)有必要使用之。通常我們就使用軟件通過(guò)51系列單片機(jī)的IO口來(lái)模擬實(shí)現(xiàn)IIC總線通信。

            本例事實(shí)上比較簡(jiǎn)單,但需要對(duì)IIC總線時(shí)序有較好的理解。源文件如下圖所示(采用C51語(yǔ)言編寫(xiě)):




            在Keil中編輯好源文件以后,接下來(lái)就可以建立工程文件并生成相應(yīng)的源代碼了,然后我們來(lái)繪制電路圖。

            此例的電路圖極其簡(jiǎn)單。只需兩個(gè)IC,即AT89C51和24C02C,和兩個(gè)上拉電阻,而且上拉電阻還可以省略。至于連接,就更為簡(jiǎn)單了。最后得到繪制好的電路圖如下圖所示:


            繪制好電路圖,我們就可以將前面剛剛生成的程序源代碼裝入單片機(jī)了,裝入以后,下面我們就可以來(lái)進(jìn)行仿真了。

            首先點(diǎn)擊仿真按鈕,系統(tǒng)沒(méi)有什么反映,只有高低電平變化的顏色。我們要想查看結(jié)果,還要用前文中仿真擴(kuò)展 RAM存儲(chǔ)器的方法,先點(diǎn)擊暫停,然后點(diǎn)擊“Debug”菜單下的“I2C Memory Internal Memory – U2”子菜單來(lái)打開(kāi)U2即EEPROM存儲(chǔ)器24C02C的內(nèi)容窗口“I2C Memory Internal Memory – U2”,然后我們就看到了其中的內(nèi)容,也就是我們仿真程序的結(jié)果。如下圖所示:


            從圖中我們能清楚地看到我們的仿真結(jié)果,程序完全正確地執(zhí)行了我們的命令。

            當(dāng)然,如果你過(guò)早地點(diǎn)擊了暫停按鈕,那么你得到的結(jié)果可能和上圖略有不同,那可能是因?yàn)槌绦蛏形磮?zhí)行完畢。此時(shí)你可以繼續(xù)點(diǎn)擊運(yùn)行按鈕,或者點(diǎn)擊單步按鈕來(lái)仔細(xì)查看程序執(zhí)行過(guò)程中24C02C存儲(chǔ)器內(nèi)容的改變情況。

            完整代碼如下:

            /*----------------------------------------------------------------

            Acess the eeprom--24c04

            ----------------------------------------------------------------*/

            #include

            #ifndef INT8U

            #define INT8U unsigned char

            #endif

            #ifndef INT8S

            #define INT8S signed char

            #endif

            #ifndef INT16U

            #define INT16U unsigned int

            #endif

            #define I2C_DELAY; _nop_();_nop_();_nop_();_nop_();_nop_(); // >=4.7uS

            //----------------------------------------------------------------

            // delay 100us

            //----------------------------------------------------------------

            void mDelay(INT8U k)

            {

            INT16U i ;

            for(; k>0; k--)

            {

            for(i=0; i93; i++)

            ;

            }

            }

            //----------------------------------------------------------------

            //OK

            //----------------------------------------------------------------

            void I2C_Start(void)

            {

            SDA = 1;

            I2C_DELAY;

            SCL = 1;

            I2C_DELAY;

            SDA = 0;

            I2C_DELAY;

            I2C_DELAY;

            }

            //----------------------------------------------------------------

            //OK

            //----------------------------------------------------------------

            void I2C_Stop(void)

            {

            SDA = 0 ;

            I2C_DELAY;

            SCL = 1 ;

            I2C_DELAY;

            SDA = 1 ;

            I2C_DELAY;

            I2C_DELAY;

            }

            //----------------------------------------------------------------

            //

            //----------------------------------------------------------------

            void sendAck(void)

            {

            SCL = 0;

            I2C_DELAY;

            SDA = 0;

            I2C_DELAY;

            SCL = 1;

            I2C_DELAY;

            }

            //----------------------------------------------------------------

            //

            //----------------------------------------------------------------

            void sendNoAck(void)

            {

            SCL = 0;

            I2C_DELAY;

            SDA = 1;

            I2C_DELAY;

            SCL = 1;

            I2C_DELAY;

            }

            //----------------------------------------------------------------

            // 0 = noACK; 1 = ACK ;

            //----------------------------------------------------------------

            bit checkAck()

            {

            bit tempbit;

            /*發(fā)送完一個(gè)字節(jié)后檢驗(yàn)設(shè)備的應(yīng)答信號(hào)*/

            SDA = 1;

            I2C_DELAY;

            SCL = 0;

            I2C_DELAY;

            tempbit = SDA;

            SCL = 1;

            I2C_DELAY;

            if(tempbit==1)

            {

            return 0; //noACK

            }

            else

            {

            return 1; //ACK

            }

            }

            //----------------------------------------------------------------

            //OK

            // a positive clock edge clock a bit into the ROM

            //----------------------------------------------------------------

            void writeByte(INT8U datum)

            {

            INT8U bitCnt = 0 ;

            for(bitCnt=0; bitCnt8; bitCnt++)

            {

            SCL = 0 ;

            I2C_DELAY;

            if ((datum0x80) == 0x80) //if the MSb is 1

            SDA = 1 ;

            else

            SDA = 0 ;

            I2C_DELAY;

            SCL = 1 ;

            I2C_DELAY;

            datum=1 ;

            }

            }

            //----------------------------------------------------------------

            //OK

            //----------------------------------------------------------------

            INT8U readByte(void)

            {

            bit tempbit = 1 ;

            INT8U temp = 0 ;

            INT8U bitCnt ;

            SDA = 1 ; // release the bus,ready to receive byte??????????????

            I2C_DELAY;

            for(bitCnt=0; bitCnt8; bitCnt++)

            {

            SCL = 0; //?????????????????????????huan???????????????

            I2C_DELAY;

            tempbit = SDA ;

            if (tempbit)

            temp |= 0x01 ;

            else

            temp = 0xfe ;

            SCL = 1 ;

            I2C_DELAY;

            if(bitCnt7)

            temp = 1 ;

            }

            return(temp) ;

            }

            /*~~~~~~~~~~~~~~~~~~~~~~~ API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

            /*-----------------------------------------------------------------

            write some bytes to sequential address

            -----------------------------------------------------------------*/

            void writeToROM(INT8U datum[], INT8U address, INT8U num)

            {

            bit tempbit ;

            INT8U i ;

            INT8U *datum_P ;

            datum_P = datum ;

            I2C_Start() ;

            writeByte(0xa0) ;

            tempbit = checkAck();

            writeByte(address) ;

            tempbit = checkAck();

            for(i=0; i

            {

            writeByte(*(datum_P+i)) ;

            if(!checkAck())

            {

            I2C_Stop() ;

            mDelay(100) ;

            }

            }

            I2C_Stop() ;

            }

            /*-----------------------------------------------------------------

            read some bytes from ROM`s sequential address

            -----------------------------------------------------------------*/

            void readFromROM(INT8U datum[], INT8U address, INT8U num)

            {

            bit tempbit ;

            INT8U i ;

            INT8U *datum_P ;

            datum_P = datum;

            I2C_Start() ;

            writeByte(0xa0) ;

            tempbit = checkAck();

            writeByte(address) ;

            tempbit = checkAck();

            I2C_Start() ;

            writeByte(0xa1) ;

            tempbit = checkAck();

            for(i=0; i

            {

            *(datum_P+i) = readByte() ;

            if(i!=num-1)

            {

            sendAck() ;

            }

            else

            {

            sendNoAck() ;

            }

            }

            I2C_Stop() ;

            }

            /*-----------------------------------------------------------------

            wirte one byte to ROM --random write

            -----------------------------------------------------------------*/

            void writeOneByte(INT8U addr, INT8U datum)

            {

            bit tempbit ;

            /*write a byte to mem*/

            I2C_Start();

            writeByte(0xa0);

            tempbit = checkAck();

            writeByte(addr); /*address*/

            tempbit = checkAck();

            writeByte(datum); /*the data*/

            tempbit = checkAck();

            I2C_Stop();

            mDelay(100) ;

            }

            /*-----------------------------------------------------------------

            read one byte from rom --random read

            -----------------------------------------------------------------*/

            INT8U readOneByte(INT8U addr)

            {

            bit tempbit = 1;

            INT8U mydata;

            /*read a byte from mem*/

            I2C_Start();

            writeByte(0xa0);

            tempbit = checkAck();

            writeByte(addr); /*address*/

            tempbit = checkAck();

            I2C_Start();

            writeByte(0xa1);

            tempbit = checkAck();

            mydata = readByte();

            tempbit = checkAck();

            return (mydata) ;

            I2C_Stop();

            }

            『本文轉(zhuǎn)載自網(wǎng)絡(luò),版權(quán)歸原作者所有,如有侵權(quán)請(qǐng)聯(lián)系刪除』



            關(guān)鍵詞: 51單片機(jī) I/O口 程序代碼

            評(píng)論


            相關(guān)推薦

            技術(shù)專區(qū)

            關(guān)閉