亚洲中文字幕网站-亚洲中文字幕婷婷在线-亚洲中文字幕丝祙制服片-亚洲中文字幕三区二区-亚洲中文字幕三级电影-亚洲中文字幕日韩欧美

您好,歡迎訪問上海現易電子元器件有限公司網站!

021-51870898
021-51870898   18019251567
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 m.mpniao.cn All rights reserved   滬ICP備2020031792號

友情鏈接:

電話

易經理

18019251567

微信

易經理

易經理

頂部

咨詢
主站蜘蛛池模板: 国产丝袜一区二区在线播放 | 成人区精品一区 | 久久国产欧美另类久久久 | 国产精品免费视频一区一 | 精品无码国产AV一区二区三区 | 日本最新免费的一区二区 | 久久久久久无码大片a片 | 老熟女强人国产在线播放一区 | 韩国精品一区二区三区在线观看 | free性欧美hd另类 | 天天综合网人人网在线 | 欧美成人免费在线观看 | 国产丝袜拍偷超清在线 | 91精品啪在线观看国产九色 | 无码的黄a在线观看 | 精品久久久久免费极品 | 2024中文字幕在线动漫在线观看 | 国产网站黄 | 国产激情一区二区三区成人 | 欧美日韩国产激情在线视频 | 国产无码一区二区三区不卡视频 | 久久午夜国产片 | 亚洲老熟女AV一区二区在线播放 | 日产学生妹在线观看 | 欧美日本东京热一区二区三区 | 日本三级黄色网址 | 日韩人妻无码一区二区三区久久99 | 国产精品无码电 | 99无码人妻一区二区三区免费 | a级毛片毛片免 | 日韩大片在线永久免费观看网站 | 国产抖音亚洲综合旡码 | 丰满人妻无码AV一区二区免费 | 国产精品啪啪视频 | 亚洲AV永久无码精品网址 | 精品无码人妻一区二区三区国产 | 久久久午夜精品 | 国产精品萌白酱在线观看 | a片疯狂做爰全过的视频 | āV第三区亚洲狠狠婷婷综合久久 | 国产成人av在线免播放观看 |