您好,歡迎訪問上海意泓電子科技有限責任公司網站!
                                                4新聞資訊
                                                您的位置: 首頁 ->  新聞資訊 -> 單片機

                                                ?STM32模擬I2C程序

                                                文章出處:單片機 責任編輯:上海意泓電子科技有限責任公司 發表時間:
                                                2018
                                                05-20

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

                                                  測試平臺:STM32F103ZET6最小系統

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

                                                static void i2cDelay()

                                                {

                                                    volatile int i = 7;

                                                    while (i)

                                                    i--;

                                                }


                                                // SCL高電平期間,SDA出現下降沿為起始信號

                                                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出現上升沿為停止信號

                                                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電平被從設備拉低表示應答

                                                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;

                                                }


                                                // 發送數據,數據從高位到低位傳輸  

                                                static void i2cSendByte(uint8_t byte)  

                                                {

                                                    uint8_t i = 8;


                                                    SDA_OUT;

                                                    while (i--) {      

                                                        SCL_L;  // 時鐘信號為低電平期間,允許數據線電平變化

                                                        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總線寫一字節數據

                                                 * @param[in] dev:設備I2C地址

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

                                                 * @param[in] data:要寫入的數據

                                                 */

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

                                                {

                                                    if (!i2cStart())        

                                                        return false;

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

                                                    if (!i2cWaitAck()) {     

                                                        i2cStop();

                                                        return false;

                                                    }

                                                    i2cSendByte(reg);       

                                                    i2cWaitAck();

                                                    i2cSendByte(data);     

                                                    i2cWaitAck();

                                                    return true;

                                                }


                                                /**

                                                 *  

                                                 * @param[in] dev:設備I2C地址

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

                                                 * @param[in] len:字節數 

                                                 * @param[in] data:待寫入的數據 

                                                 */

                                                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設備中讀取數據

                                                 * @param[in] dev:設備I2C地址

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

                                                 * @param[in] len:數據字節數

                                                 * @param[out] data:讀出的數據

                                                 */

                                                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();  // 最后一個字節不應答

                                                        else

                                                            i2cAck();

                                                        data++;

                                                        len--;

                                                    }

                                                    i2cStop();

                                                    return true;

                                                }


                                                上海意泓電子科技有限責任公司 版權所有 未經授權禁止復制或鏡像

                                                CopyRight 2020-2025 www.your-backup-plan.com All rights reserved   滬ICP備2021005866號

                                                成人网站在线观看免费,97黄色网站,超碰最新网址,精品无码久久久久国产写真