• <label id="gmp5l"></label>

    <li id="gmp5l"></li>
      • 您好,歡迎訪問上海意泓電子科技有限責(zé)任公司網(wǎng)站!
        4新聞資訊
        您的位置: 首頁 ->  新聞資訊 -> 單片機(jī)

        ?STM32模擬I2C程序

        文章出處:單片機(jī) 責(zé)任編輯:上海意泓電子科技有限責(zé)任公司 發(fā)表時(shí)間:
        2018
        05-20

        /*******************************************************************************

          測試平臺:STM32F103ZET6最小系統(tǒng)

        *******************************************************************************/

        static void i2cDelay()

        {

            volatile int i = 7;

            while (i)

            i--;

        }


        // SCL高電平期間,SDA出現(xiàn)下降沿為起始信號

        static bool i2cStart()

        {

            SDA_OUT;

            SCL_H;

            SDA_H;

            i2cDelay();

            if (!sdaRead)  // 如果SDA為低電平,則總線忙,退出

                return false;

            SDA_L;

            if (sdaRead)  // 如果SDA為高電平,則總線忙,退出

                return false;

            SDA_L;

            return true;

        }


        // SCL高電平期間,SDA出現(xiàn)上升沿為停止信號

        static void i2cStop(void)

        {

            SDA_OUT;

            SCL_L; 

            SDA_L;

            i2cDelay();  // STOP:when CLK is high DATA from low to high 

            SCL_H;

            SDA_H;  

            i2cDelay();

        }


        static void i2cAck(void)

        {

            SDA_OUT;

            SCL_L;

            i2cDelay();

            SDA_L;

            i2cDelay();

            SCL_H;

            i2cDelay();

            SCL_L;

        }


        static void i2cNoAck(void)

        {

            SDA_OUT;

            SCL_L;

            i2cDelay();

            SDA_H;

            i2cDelay();

            SCL_H;

            i2cDelay();

            SCL_L;

        }


        // SCL高電平期間,SDA電平被從設(shè)備拉低表示應(yīng)答

        static bool i2cWaitAck(void)

        {

            uint8_t errTimes = 0;


            SDA_IN;

            SDA_H;

            i2cDelay();

            SCL_H;

            i2cDelay();

            while (sdaRead) {

                if (errTimes++ > 20) {

                    SCL_L;

                    return false;

                }           

                i2cDelay();

            }

            SCL_L;

            return true;

        }


        // 發(fā)送數(shù)據(jù),數(shù)據(jù)從高位到低位傳輸  

        static void i2cSendByte(uint8_t byte)  

        {

            uint8_t i = 8;


            SDA_OUT;

            while (i--) {      

                SCL_L;  // 時(shí)鐘信號為低電平期間,允許數(shù)據(jù)線電平變化

                i2cDelay();

                if (byte & 0x80)

                    SDA_H;

                else

                    SDA_L; 

                byte <<= 1; 

                i2cDelay();

                SCL_H;

                i2cDelay();

            }

            SCL_L;

        }


        static uint8_t i2cReceiveByte()  

        {

            uint8_t i = 8;

            uint8_t byte = 0;


            SDA_IN;

            SDA_H;

            while (i--) {

                byte <<= 1;

                SCL_H;

                i2cDelay();

                if (sdaRead) {

                    byte |= 0x01;

                }

                SCL_L;

                i2cDelay();

            }

            SCL_L;

            return byte; 

        }



        void i2cInit()

        {

            GPIO_InitTypeDef GPIO_InitStructure;


            /* Enable GPIOB clock */

            RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);


            /* Configure GPIOB.6 & GPIOB.7 as open-drain output */

            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;

            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;


            GPIO_Init(GPIOB, &GPIO_InitStructure);

        }


        /**

         * 通過I2C總線寫一字節(jié)數(shù)據(jù)

         * @param[in] dev:設(shè)備I2C地址

         * @param[in] reg:寄存器地址

         * @param[in] data:要寫入的數(shù)據(jù)

         */

        bool i2cWriteOneByte(uint8_t dev, uint8_t reg, uint8_t data)

        {

            if (!i2cStart())        

                return false;

            i2cSendByte(dev << 1);  // 從機(jī)地址由高7位+讀寫位構(gòu)成   

            if (!i2cWaitAck()) {     

                i2cStop();

                return false;

            }

            i2cSendByte(reg);       

            i2cWaitAck();

            i2cSendByte(data);     

            i2cWaitAck();

            return true;

        }


        /**

         *  

         * @param[in] dev:設(shè)備I2C地址

         * @param[in] reg:寄存器地址

         * @param[in] len:字節(jié)數(shù) 

         * @param[in] data:待寫入的數(shù)據(jù) 

         */

        bool i2cWriteBytes(uint8_t dev, uint8_t reg, uint8_t len, uint8_t *data)

        {

            uint8_t i;


            if (!i2cStart())        

                return false;

            i2cSendByte(dev << 1);          

            if (!i2cWaitAck()) {     

                i2cStop();

                return false;

            }

            i2cSendByte(dev);   

            i2cWaitAck();

            for (i = 0; i < len; i++) {

                i2cSendByte(data[i]);

                if (!i2cWaitAck()) {

                    i2cStop();

                    return false;

                }

            }

            i2cStop();

            return true;

        }



        /**

         * 從I2C設(shè)備中讀取數(shù)據(jù)

         * @param[in] dev:設(shè)備I2C地址

         * @param[in] reg:寄存器地址

         * @param[in] len:數(shù)據(jù)字節(jié)數(shù)

         * @param[out] data:讀出的數(shù)據(jù)

         */

        bool i2cReadBytes(uint8_t dev, uint8_t reg, uint8_t len, uint8_t *data)

        {

            if (!i2cStart())        

                return false;

            i2cSendByte(dev << 1);      

            if (!i2cWaitAck()) {     

                i2cStop();

                return false;

            }

            i2cSendByte(reg);     

            i2cWaitAck();

            i2cStart();           

            i2cSendByte((dev << 1) | 0x01);  // 器件地址+讀命令    

            i2cWaitAck();

            while (len) {

                *data = i2cReceiveByte();

                if (len == 1)

                    i2cNoAck();  // 最后一個(gè)字節(jié)不應(yīng)答

                else

                    i2cAck();

                data++;

                len--;

            }

            i2cStop();

            return true;

        }


        上海意泓電子科技有限責(zé)任公司 版權(quán)所有 未經(jīng)授權(quán)禁止復(fù)制或鏡像

        CopyRight 2020-2025 www.jlodreman.com All rights reserved   滬ICP備2021005866號

        亚洲人成影院在线观看,91综合永久在线观看,欧洲亚洲日韩国产AV一级,中文字幕在线视频播放
      • <label id="gmp5l"></label>

        <li id="gmp5l"></li>