OD,加上拉

Flash都用于存放运行代码,在运行过程中不能改;EEPROM是用来保存用户数据,运行过程中可以改变 FLASH按扇区操作,EEPROM则按字节操作,二者寻址方法不同,存储单元的结构也不同,FLASH的电路结构较简单,同样容量占芯片面积较小,成本自然比EEPROM低,因而适合用作程序存储器,EEPROM则更多的用作非易失的数据存储器。当然用FLASH做数据存储器也行,但操作比EEPROM麻烦的多,所以更“人性化”的MCU设计会集成FLASH和EEPROM两种非易失性存储器。有些单片机硬件上没有EEPROM,但是会提供软件模拟的EEPROM,可以让用户以EEPROM的方式直接对flash的某个特定扇区进行操作。这样硬件成本低,用户使用上也感觉不到麻烦,不过寿命和速度肯定不如硬件直接用EEPROM好

I2C总线死锁

在正常情况下,I2C总线协议能够保证总线正常的读写操作。但是,当I2C主设备异常复位时(看门狗动作,板上电源异常导致复位芯片动作,手动按钮复位等等)有可能导致I2C总线死锁产生。下面详细说明一下总线死锁产生的原因。

在I2C主设备进行读写操作的过程中.主设备在开始信号后控制SCL产生8个时钟脉冲,然后拉低SCL信号为低电平,在这个时候,从设备输出应答信号,将SDA信号拉为低电平。如果这个时候主设备异常复位,SCL就会被释放为高电平。此时,如果从设备没有复位,就会继续I2C的应答,将SDA一直拉为低电平,直到SCL变为低电平,才会结束应答信号。 Q:写数据时在SDA为0时复位会死锁吗?不会,从M向S发。

而对于I2C主设备来说.复位后检测SCL和SDA信号,如果发现SDA信号为低电平,则会认为I2C总线被占用,会一直等待SCL和SDA信号变为高电平。所以SDA不为0就能继续读 这样,I2C主设备等待从设备释放SDA信号,而同时I2C从设备又在等待主设备将SCL信号拉低以释放应答信号,两者相互等待,I2C总线进人一种死锁状态。 同样,当I2C进行读操作,I2C从设备应答后输出数据,如果在这个时刻I2C主设备异常复位而此时I2C从设备输出的数据位正好为0,也会导致I2C总线进入死锁状态。

方法

1)尽量选用带复位输人的I2C从器件。

(2)将所有的从I2C设备的电源连接在一起,通过MOS管连接到主电源,而MOS管的导通关断由I2C主设备来实现。

(3)在I2C从设备设计看门狗的功能。

(4)在I2C主设备中增加I2C总线恢复程序

每次I2C主设备复位后,如果检测到SDA数据线被拉低,则控制I2C中的SCL时钟线产生9个时钟脉冲(针对8位数据的情况,“9个clk可以激活”的方法来自NXP的文档,NXP(Philips)作为I2C总线的鼻祖,这样的说法是可信的),这样I2C从设备就可以完成被挂起的读操作,从死锁状态中恢复过来。

Q:为啥是9个clock GPT:在I2C规范中,一个完整的数据字节由8位数据加上一个确认位组成,共有9位。如果从设备在传输这9位中的任何一位时失去响应并锁住了数据线,那么通过再发送9个额外的时钟脉冲,主设备就能够给从设备一个完成当前字节发送的机会,包括最后的确认位。这样做提供了最大的机会来清除潜在的死锁,因为无论从设备停在了数据字节的哪一位,这9个额外的时钟脉冲都应该允许它完成当前字节的传输。 Q:如果真的有设备正确占用了是啥样子的

这种方法有很大的局限性,因为大部分主设备的I2C模块由内置的硬件电路来实现,软件并不能够直接控制SCL信号模拟产生需要时钟脉冲。 或者,发送I2C_Stop条件也能让从设备释放总线。 如果是GPIO模拟I2C总线实现,那么在I2C操作之前,加入I2C总线状态检测 I2C_Probe ,如果总线被占用,则可尝试恢复总线,待总线释放后,再进行操作。要保证I2C操作最小单元的完整性,不被其他事件(中断、高优先级线程,等)打断。

(5)在I2C总线上增加一个额外的总线恢复设备。这个设备监视I2C总线。当设备检测到SDA信号被拉低超过指定时间时,就在SCL总线上产生9个时钟脉冲,使I2C从设备完成读操作,从死锁状态上恢复出来。总线恢复设备需要有具有编程功能,一般可以用单片机或CPLD实现这一功能。

(6)在I2C上串人一个具有死锁恢复的I2C缓冲器,如Linear公司的LTC4307是一个双向的I2C总线缓冲器,并且具有I2C总线死锁恢复的功能。LTC4307总线输入侧连接主设备,总线输出侧连接所有从设备。当LTC4307检测到输出侧SDA或SCL信号被拉低30ms时,就自动断开I2C总线输入侧与输出侧的连接.并且在输出侧SCL信号上产生16个时钟脉冲来释放总线。当总线成功恢复后,LTC4307会再次连接输入输出侧,使总线能够正常工作。

results matching ""

    No results matching ""