久久人妻精品人妻视频五月天一区二区三区,,自慰午夜喷水久久久av国产成人a视频高在线,,欧美日韩免费专区在线97精品国产手机

  • <cite id="cwywg"></cite>
    <button id="cwywg"></button>
  • <button id="cwywg"><source id="cwywg"></source></button>
    <button id="cwywg"><tbody id="cwywg"></tbody></button>
  • <button id="cwywg"></button>
  • 
    
  • logo logo
    • BANNER
    • BANNER
    • BANNER
    您的位置 : 首頁 > 新聞資訊 > 技術(shù)支持
    STM32模擬I2C程序
    發(fā)布者:江蘇瑞易通電子科技有限公司 人氣:1891 發(fā)布日期:2021-04-23 10:10:40

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

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

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

    static void i2cDelay()

    {

        volatile int i = 7;

        while (i)

        i--;

    }


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

    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)上升沿為停止信號(hào)

    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í)鐘信號(hào)為低電平期間,允許數(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;

    }


    返回新聞列表