找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3824|回復(fù): 15
收起左側(cè)

MCU如何檢測I2C設(shè)備是否存在?

  [復(fù)制鏈接]
ID:1083229 發(fā)表于 2023-6-10 18:32 | 顯示全部樓層 |閱讀模式
1.部分代碼:(軟件模擬I2C連接BH1750模塊,來自正點(diǎn)原子代碼示例)


/*
*********************************************************************************************************
*        函 數(shù) 名: i2c_Stop
*        功能說明: CPU發(fā)起I2C總線停止信號
*        形    參:無
*        返 回 值: 無
*********************************************************************************************************
*/
void i2c_Stop(void)
{
        /* 當(dāng)SCL高電平時,SDA出現(xiàn)一個上跳沿表示I2C總線停止信號 */
        BH1750_I2C_SDA_0();
        BH1750_I2C_SCL_1();
        i2c_Delay();
        BH1750_I2C_SDA_1();
}

/*
*********************************************************************************************************
*        函 數(shù) 名: i2c_WaitAck
*        功能說明: CPU產(chǎn)生一個時鐘,并讀取器件的ACK應(yīng)答信號
*        形    參:無
*        返 回 值: 返回0表示正確應(yīng)答,1表示無器件響應(yīng)
*********************************************************************************************************
*/
uint8_t i2c_WaitAck(void)
{
        uint8_t re;


        BH1750_I2C_SDA_1();        /* CPU釋放SDA總線 */
        i2c_Delay();
        BH1750_I2C_SCL_1();        /* CPU驅(qū)動SCL = 1, 此時器件會返回ACK應(yīng)答 */
        i2c_Delay();
        if (BH1750_I2C_SDA_READ())        /* CPU讀取SDA口線狀態(tài) */
                re = 1;
        else
                re = 0;
        BH1750_I2C_SCL_0();
        i2c_Delay();
        return re;
}



/*
*********************************************************************************************************
*        函 數(shù) 名: i2c_CheckDevice
*        功能說明: 檢測I2C總線設(shè)備,CPU向發(fā)送設(shè)備地址,然后讀取設(shè)備應(yīng)答來判斷該設(shè)備是否存在
*        形    參:_Address:設(shè)備的I2C總線地址
*        返 回 值: 返回值 0 表示正確, 返回1表示未探測到
*********************************************************************************************************
*/
uint8_t i2c_CheckDevice(uint8_t _Address)
{
        uint8_t ucAck;
        i2c_Start();                /* 發(fā)送啟動信號 */
        /* 發(fā)送設(shè)備地址+讀寫控制bit(0 = w, 1 = r) bit7 先傳 */
        i2c_SendByte(_Address | BH1750_I2C_WR);
        ucAck = i2c_WaitAck();        /* 檢測設(shè)備的ACK應(yīng)答 *

        i2c_Stop();                        /* 發(fā)送停止信號 */

        return ucAck;
}

2.現(xiàn)象:
(1)正常連接,時序正常(黃色為SCL,綠色為SDA),i2c_CheckDevice()函數(shù)返回0表示檢測到
51hei圖片20230610173002.jpg IMG_20230610_174048.jpg

(2)換設(shè)備引腳改從機(jī)地址,SCL低電平,SDA高電平,i2c_CheckDevice(BH1750_Addr)函數(shù)返回1表示未檢測
51hei圖片20230610173034.png 51hei圖片20230610172952.jpg

(3)不連接設(shè)備,SCL和SDA都為低電,i2c_CheckDevice(BH1750_Addr)函數(shù)返回0表示檢測到?
IMG_20230610_174029.jpg IMG_20230610_174059.jpg


3.問題:怎么讓不連接設(shè)備的時候i2c_CheckDevice(BH1750_Addr)函數(shù)返回1
static void I2C_BH1750_GPIOConfig(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;


        RCC_APB2PeriphClockCmd(BH1750_RCC_I2C_PORT, ENABLE);        /* 打開GPIO時鐘 */


        GPIO_InitStructure.GPIO_Pin = BH1750_I2C_SCL_PIN | BH1750_I2C_SDA_PIN;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;          /* 開漏輸出 */
        GPIO_Init(BH1750_GPIO_PORT_I2C, &GPIO_InitStructure);


        /* 給一個停止信號, 復(fù)位I2C總線上的所有設(shè)備到待機(jī)模式 */
        i2c_Stop();    //初始化的時候已經(jīng)讓SCL和SDA都輸出高電平
}


回復(fù)

使用道具 舉報

ID:94031 發(fā)表于 2023-6-11 05:50 | 顯示全部樓層
采集來的數(shù)據(jù)在正常范圍,說明設(shè)備存在。
回復(fù)

使用道具 舉報

ID:1083310 發(fā)表于 2023-6-11 07:16 | 顯示全部樓層
你IIC總線上有上拉電阻嗎?
回復(fù)

使用道具 舉報

ID:401564 發(fā)表于 2023-6-11 10:53 | 顯示全部樓層
iic是有應(yīng)答機(jī)制的,有應(yīng)答就是有設(shè)備,沒有應(yīng)答就是沒有設(shè)備
回復(fù)

使用道具 舉報

ID:230500 發(fā)表于 2023-6-11 13:35 | 顯示全部樓層
根據(jù)應(yīng)答信號 檢測從設(shè)備是否在線和損壞或者掉線;仔細(xì)看一下IIC的通訊協(xié)議,就清楚了; 硬件上面 我一般習(xí)慣IIC的總線額外添加3.3K-10K的上拉電阻; 5V設(shè)備一般用4K7就可以了;
回復(fù)

使用道具 舉報

ID:1083229 發(fā)表于 2023-6-11 22:06 | 顯示全部樓層
已解決:BH1750模塊內(nèi)置上拉電阻,所以STM32直接連接就可以通信,但是當(dāng)沒有設(shè)備連接還想讓SCL和SDA處于高電平就得額外接上拉電阻。
回復(fù)

使用道具 舉報

ID:1083229 發(fā)表于 2023-6-11 22:15 | 顯示全部樓層
已解決:BH1750模塊已經(jīng)內(nèi)置上拉電阻,所以直接連接就可以進(jìn)行I2C通信,但是當(dāng)沒有外設(shè)連接的時候還想讓SCL和SDA處于高電平需要額外接上拉電阻。
還有個疑問:在沒有釋放總線之前SCL和SDA都是主機(jī)控制,那沒有設(shè)備連接時不應(yīng)該也能檢測到不完整的輸出波形嗎?為什么我用示波器沒有檢測到
回復(fù)

使用道具 舉報

ID:1034262 發(fā)表于 2023-6-12 11:00 | 顯示全部樓層
讀取器件信息即可知道
回復(fù)

使用道具 舉報

ID:883242 發(fā)表于 2023-6-12 12:16 | 顯示全部樓層
_BEAR_ 發(fā)表于 2023-6-11 22:06
已解決:BH1750模塊內(nèi)置上拉電阻,所以STM32直接連接就可以通信,但是當(dāng)沒有設(shè)備連接還想讓SCL和SDA處于高 ...

STM32可以設(shè)置內(nèi)部上拉,你沒有打開。
回復(fù)

使用道具 舉報

ID:1083229 發(fā)表于 2023-6-16 13:42 | 顯示全部樓層
Hephaestus 發(fā)表于 2023-6-12 12:16
STM32可以設(shè)置內(nèi)部上拉,你沒有打開。

但是I2C通信要設(shè)置為開漏輸出模式不是嗎
回復(fù)

使用道具 舉報

ID:612392 發(fā)表于 2023-6-16 13:55 | 顯示全部樓層
這IIC的波形質(zhì)量好差
回復(fù)

使用道具 舉報

ID:77589 發(fā)表于 2023-6-16 15:25 | 顯示全部樓層
Y_G_G 發(fā)表于 2023-6-11 10:53
iic是有應(yīng)答機(jī)制的,有應(yīng)答就是有設(shè)備,沒有應(yīng)答就是沒有設(shè)備

正解,支持一下
回復(fù)

使用道具 舉報

ID:1109406 發(fā)表于 2024-1-16 15:53 | 顯示全部樓層
請問是只有添加了上拉電阻才能解決嗎
回復(fù)

使用道具 舉報

ID:43600 發(fā)表于 2024-1-17 01:22 | 顯示全部樓層
device沒回應(yīng)ack,就代表不存在。
回復(fù)

使用道具 舉報

ID:517951 發(fā)表于 2024-1-17 07:34 | 顯示全部樓層
通過I2C讀取從器件的ID值, 有ack就是有設(shè)備存在, 沒有就是沒有設(shè)備存在.
回復(fù)

使用道具 舉報

ID:1109406 發(fā)表于 2024-1-17 10:32 | 顯示全部樓層
可以在傳感器的采集時序函數(shù)里面設(shè)置返回值,調(diào)用時序函數(shù)時再檢查一下有沒ack返回。我也碰到跟你一樣的問題,就這樣解決了。
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表