找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1418|回复: 15
打印 上一主题 下一主题
收起左侧

MCU如何检测I2C设备是否存在?

  [复制链接]
跳转到指定楼层
楼主
1.部分代码:(软件模拟I2C连接BH1750模块,来自正点原子代码示例)


/*
*********************************************************************************************************
*        函 数 名: i2c_Stop
*        功能说明: CPU发起I2C总线停止信号
*        形    参:无
*        返 回 值: 无
*********************************************************************************************************
*/
void i2c_Stop(void)
{
        /* 当SCL高电平时,SDA出现一个上跳沿表示I2C总线停止信号 */
        BH1750_I2C_SDA_0();
        BH1750_I2C_SCL_1();
        i2c_Delay();
        BH1750_I2C_SDA_1();
}

/*
*********************************************************************************************************
*        函 数 名: i2c_WaitAck
*        功能说明: CPU产生一个时钟,并读取器件的ACK应答信号
*        形    参:无
*        返 回 值: 返回0表示正确应答,1表示无器件响应
*********************************************************************************************************
*/
uint8_t i2c_WaitAck(void)
{
        uint8_t re;


        BH1750_I2C_SDA_1();        /* CPU释放SDA总线 */
        i2c_Delay();
        BH1750_I2C_SCL_1();        /* CPU驱动SCL = 1, 此时器件会返回ACK应答 */
        i2c_Delay();
        if (BH1750_I2C_SDA_READ())        /* CPU读取SDA口线状态 */
                re = 1;
        else
                re = 0;
        BH1750_I2C_SCL_0();
        i2c_Delay();
        return re;
}



/*
*********************************************************************************************************
*        函 数 名: i2c_CheckDevice
*        功能说明: 检测I2C总线设备,CPU向发送设备地址,然后读取设备应答来判断该设备是否存在
*        形    参:_Address:设备的I2C总线地址
*        返 回 值: 返回值 0 表示正确, 返回1表示未探测到
*********************************************************************************************************
*/
uint8_t i2c_CheckDevice(uint8_t _Address)
{
        uint8_t ucAck;
        i2c_Start();                /* 发送启动信号 */
        /* 发送设备地址+读写控制bit(0 = w, 1 = r) bit7 先传 */
        i2c_SendByte(_Address | BH1750_I2C_WR);
        ucAck = i2c_WaitAck();        /* 检测设备的ACK应答 *

        i2c_Stop();                        /* 发送停止信号 */

        return ucAck;
}

2.现象:
(1)正常连接,时序正常(黄色为SCL,绿色为SDA),i2c_CheckDevice()函数返回0表示检测到


(2)换设备引脚改从机地址,SCL低电平,SDA高电平,i2c_CheckDevice(BH1750_Addr)函数返回1表示未检测


(3)不连接设备,SCL和SDA都为低电,i2c_CheckDevice(BH1750_Addr)函数返回0表示检测到?



3.问题:怎么让不连接设备的时候i2c_CheckDevice(BH1750_Addr)函数返回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);


        /* 给一个停止信号, 复位I2C总线上的所有设备到待机模式 */
        i2c_Stop();    //初始化的时候已经让SCL和SDA都输出高电平
}


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:94031 发表于 2023-6-11 05:50 | 只看该作者
采集来的数据在正常范围,说明设备存在。
回复

使用道具 举报

板凳
ID:1083310 发表于 2023-6-11 07:16 | 只看该作者
你IIC总线上有上拉电阻吗?
回复

使用道具 举报

地板
ID:401564 发表于 2023-6-11 10:53 | 只看该作者
iic是有应答机制的,有应答就是有设备,没有应答就是没有设备
回复

使用道具 举报

5#
ID:230500 发表于 2023-6-11 13:35 | 只看该作者
根据应答信号 检测从设备是否在线和损坏或者掉线;仔细看一下IIC的通讯协议,就清楚了; 硬件上面 我一般习惯IIC的总线额外添加3.3K-10K的上拉电阻; 5V设备一般用4K7就可以了;
回复

使用道具 举报

6#
ID:1083229 发表于 2023-6-11 22:06 | 只看该作者
已解决:BH1750模块内置上拉电阻,所以STM32直接连接就可以通信,但是当没有设备连接还想让SCL和SDA处于高电平就得额外接上拉电阻。
回复

使用道具 举报

7#
ID:1083229 发表于 2023-6-11 22:15 | 只看该作者
已解决:BH1750模块已经内置上拉电阻,所以直接连接就可以进行I2C通信,但是当没有外设连接的时候还想让SCL和SDA处于高电平需要额外接上拉电阻。
还有个疑问:在没有释放总线之前SCL和SDA都是主机控制,那没有设备连接时不应该也能检测到不完整的输出波形吗?为什么我用示波器没有检测到
回复

使用道具 举报

8#
ID:1034262 发表于 2023-6-12 11:00 | 只看该作者
读取器件信息即可知道
回复

使用道具 举报

9#
ID:883242 发表于 2023-6-12 12:16 | 只看该作者
_BEAR_ 发表于 2023-6-11 22:06
已解决:BH1750模块内置上拉电阻,所以STM32直接连接就可以通信,但是当没有设备连接还想让SCL和SDA处于高 ...

STM32可以设置内部上拉,你没有打开。
回复

使用道具 举报

10#
ID:1083229 发表于 2023-6-16 13:42 | 只看该作者
Hephaestus 发表于 2023-6-12 12:16
STM32可以设置内部上拉,你没有打开。

但是I2C通信要设置为开漏输出模式不是吗
回复

使用道具 举报

11#
ID:612392 发表于 2023-6-16 13:55 | 只看该作者
这IIC的波形质量好差
回复

使用道具 举报

12#
ID:77589 发表于 2023-6-16 15:25 | 只看该作者
Y_G_G 发表于 2023-6-11 10:53
iic是有应答机制的,有应答就是有设备,没有应答就是没有设备

正解,支持一下
回复

使用道具 举报

13#
ID:1109406 发表于 2024-1-16 15:53 | 只看该作者
请问是只有添加了上拉电阻才能解决吗
回复

使用道具 举报

14#
ID:43600 发表于 2024-1-17 01:22 | 只看该作者
device沒回應ack,就代表不存在。
回复

使用道具 举报

15#
ID:517951 发表于 2024-1-17 07:34 | 只看该作者
通过I2C读取从器件的ID值, 有ack就是有设备存在, 没有就是没有设备存在.
回复

使用道具 举报

16#
ID:1109406 发表于 2024-1-17 10:32 | 只看该作者
可以在传感器的采集时序函数里面设置返回值,调用时序函数时再检查一下有没ack返回。我也碰到跟你一样的问题,就这样解决了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表