来源:公众号【鱼鹰谈单片机】,作者:鱼鹰Osprey,ID :emOsprey
有些 IO 可能作为双向输出,比如 I2C 的 SDA 引脚,如果配置成推挽输出(push-pull),那么当要读取 应答信号或者读取 i2c 数据时,需要重新配置 IO。
因此,很多教程会建议配置成开漏输出(open-drain),这样就不需要来回配置输出方向。
这里需要注意的一点是,不管是开漏还是推挽输出,作为输入时,都需要设置 ODR 寄存器。
一直以为设置为开漏后,不管 ODR 设置 0 或 1,引脚电平应该都是一样的低电平,实际上,还是会有差异:
开漏 ODR 设置为 1:0.15~0.6V(波动比较大)
开漏 ODR 设置为 0:0.002V
按理说,即使 0.6V 电压,IDR 读出的值应该都是 0 才对,实际上,不管是代码,还是调试窗口,偶尔还是可以读出 1 的情况。
刚开始以为是调试窗口有问题,但通过代码发现,开漏模式下,即使未接外部上拉电阻,电平确实被识别成高电平.
并且使用逻辑分析仪也是被莫名其妙的识别成高电平。
1V 不到的电平怎么就是高电平了(VDD 3.3V)?
按这个数据手册来说,VDD 3.3V 情况下,最少也需要 1.5V 以上才会被识别为高电平,百思不得其解。如果有道友懂的可以留言区讨论,没找到理论依据。
并且当设置为开漏时,当准备作输入时,如果 ODR 不设置为 1,虽然应答信号可以读取,读取的数据却是错误的(测试 AT24C256)
(STM32F103 参考手册)