其实论坛中这样的驱动程序已经很多,如 EEPROM 驱动函数等,而且都做的很好,这里毕竟高手如云!!!但是我大概看了一下,似乎用AVR IO口做软件模拟I2C 的程序, 没有完全符合I2C规范的...憋了半天,觉得不吐不快,于是也动笔一叙,也管不得是否文采不好,术语不专业,鸡蛋满天飞了.
首先说明,对于I2C,AVR能用TWI就使用TWI,它相当于AVR内置硬件I2C接口,可靠性更高,节省软件运行开销.
I2C用IO模拟程序网上范例最多的就是51的程序了,这些范例的正确性无需怀疑.但是如果直接以它为蓝本将它"AVR化",一不留神,就会有点问题了.
这要从I2C的硬件规范和AVR及51单片机的IO口说起.I2C要求SCL,SDA二线都有 线与 功能,即I2C驱动口应该是 漏极开路 电路,其高电平的维持是靠上拉电阻来实现的, 而低电平则需要驱动口的 强下拉 能力.
51单片机IO口正好完全符合这个特性. 写起I2C驱动颇为得心应手.但是AVR的IO口强大了,它输出的高电平是实实在在的高电平,而不是靠什么上拉电阻来提供,只有10mA都不到的电流!于是如果直接使用 PORTB_Bit0 = 1这样的操作,就不能满足I2C的线与功能了,如果此时有别的设备要将SCL或者SDA拉低,那么结果就是二个IO口打架,谁赢谁输不得而知,时间长了,多半是两败俱伤,芯片发热吧.
当然AVR的IO口自然有办法满足I2C的电气特性要求,不就是不能输出1么,那么用它的高阻状态即可(DDRB_Bit0=0,PORTB_Bit0=0即可),要输出0么(DDRB_Bit0=1,PORTB_Bit0=0).
我网上看到的AVR软件模拟I2C的程序问题比较多的就是SCL的驱动,一般都直接用输出1和输出0来产生波形,这在一般应用中没问题,不过如果要用到主机仲裁,I2C芯片间肯定是要打架的!
I2C的上层建筑函数很丰富,我就给个最基本的I2C软件模拟函数,完全符合I2C规范.
补充以下,下面的程序用的是IAR.它控制单IO口比较方便.CVAVR也有这样的功能如 PORTB.0 = 1. 其它的编译器就只能用位操作了... |