引言
在嵌入式控制系统中,通常要用到非易失性存储器。无论是掉电时维持需要保存的设置,还是存储重要记录,可靠的非易失性存储器都是一种理想的选择。非易失性存储常常采用外部串行存储器来实现,其中I2C接口产品是最常用的一种类型。然而,这种产品和其他EEPROM存储器一样,在使用时也存在着一些条件会潜在地导致其产生某些非标准的甚至是错误的操作。因此在进行I2C串行EEPROM存储器的应用设计时,除了应考虑数据手册规范之外,还必须考虑更多的因素,这样才能实现更健壮的总体设计,确保系统具有优良的质量特性。
1 防意外写措施
器件在上电/掉电期间或者SDA/SCL线的噪声过大时都有可能导致意外写操作。为了解决这一问题,一方面需要使用去耦电容(容量通常为0.1 μF)来帮助滤除VCC上的纹波,另一方面则可以通过写保护措施来防止对器件的非法访问。
对于具有硬件写保护功能的器件,既可以将其WP引脚连接到VCC来保护整个阵列,也可以将其WP引脚连接到VSS来放弃写保护。通常用户可以将WP引脚连接到微控制器的一根I/O口线上,并在该引脚与VCC间连接一个上拉电阻,这样就可确保器件在平时处于写保护状态;但是要启动写周期,WP引脚必须首先被驱动为逻辑0。注意,WP引脚不能悬空,否则器件将无法正常工作。
对于无写保护功能的器件,则可以利用一个电子开关对其SDA引脚与微控制器之间的连接进行通断控制来实现写保护。平常不访问器件时,切断它们的连接;仅在需要对器件实施读/写操作时才接通。
2 数据完整性保护措施
在整个写周期内(对于大多数器件而言,通常最大为5 ms),必须将VCC维持在最小工作电压以上。如果此时VCC掉电或降到最小电压以下,则无论时间长短,均无法确保被写页面的数据完整性,可能导致编程数据的不正确。此外,由于无法对EEPROM单元进行完全编程,器件的数据保留时间会比数据手册中规定的时间短。对于写周期内电源故障所导致的这些问题,通常可以在软件上采取相应的保护措施来加以解决。基于事物的提交—回退机制[1]就是一种典型的解决方案。可以证明,当EEPROM存储器应用系统采用该机制后,无论电源何时掉电或微控制器何时被复位,EEPROM存储子系统都可保持数据的完整性。
(1) 提交—回退机制的建立
提交—回退机制的建立包括两方面的内容:一方面是定义EEPROM存储器的逻辑结构;另一方面是构造对存储子系统进行访问、检查和错误清理的接口函数。
该机制将EEPROM存储器划分为主存储区、校验存储区和缓存区3个部分。其中主存储区用于存放用户数据;校验存储区用于存放主存储区每个页面的CRC校验码,且该区中每一页的最后一个CRC用于校验本页数据;缓存区包括多个写缓存,每个写缓存包含4个域——数据域、地址域、状态域和16位CRC域。数据域用于临时存放写函数写入的数据页面,执行下一个提交命令时,该数据页面将从缓存区传送到主存储区。地址域表示缓存数据要写入的页面地址;状态域表示缓存的状态,包括可用(available)、占用(occupied)和终止(expired)状态;16位CRC域用来校验整个写缓存。
该机制提供了6个接口函数:读、写、提交、回退、检查和清理。
① 读函数。接收1个页面编号和1个用于存放待读出数据的暂存区指针。如果暂存区指针和页面编号处于有效范围内,程序就会将指定的页面数据读入暂存区,并校验数据的有效性。该函数会返回如下状态之一:有效读(valid read)、无效读(invalid read)、无效暂存区地址(invalid buffer address)、无效页面编号(invalid page number)或保护失败(protection failure)。
② 写函数。接收1个页面编号和1个指向填好数据的暂存区指针。如果暂存区指针和页面编号处于有效范围内,程序就会将数据写入非易失性缓存,并标记缓存状态以准备提交。
③ 提交和回退函数。提交和回退函数是可以在运行写函数之后执行的互补型操作。提交函数将最近被写入缓存的数据复制到存储区中的对应位置,并为下一个待写入的数据页面准备好缓存结构。回退函数实际上就是一个“取消”操作,它消除最近一次执行写函数产生的效果,并为下一个写操作准备好缓存子系统。
④ 检查函数。读取存储器件的每个数据页面,并检查存储数据的有效性。该函数还检查缓存子系统,以确保没有未执行的写操作。任何无效页面或未执行的写操作都会使检查函数返回一个错误状态。
⑤ 清理函数。修复一个数据损坏的EEPROM。实际上,它将试图找出发生的错误,并采取相应的解决措施。
(2) 提交—回退机制的应用
读操作:调用读函数来实现。
更新主存储区数据操作:先调用写函数再调用提交函数来完成。主存储区只有在完成一个提交操作后才更新数据,而不是在一个写操作之后更新的。
异常处理:在任何一个可能破坏EEPROM写周期的事件之后(例如上电之后),都将首先执行校验/清理函数。检查函数将检验存储系统的可用性,并报告任何发现的错误;清理函数将根据检查函数返回的错误代码解决EEPROM系统存在的任何问题。在清理操作退出时,无论EEPROM子系统先前是何种状态,都应该可以继续使用。
3 I2C通信的有效性保证措施
(1) 软件复位
有时EEPROM器件可能需要执行软件复位序列来确保其处于正确并且已知的状态。这在某些情况下会很有用。例如,在EEPROM上电时,若总线噪声过大,EEPROM上电后将会进入不正确的状态;又如,微控制器在通信期间若发生复位,将会使通信陷入不同步的状态。为了确保在出现这些情况之后,系统的微控制器与I2C串行EEPROM器件之间能够正确、有效地实现通信,可以先发送图1所示的软件复位序列,使I2C接口器件可靠复位,之后,再启动数据的传输过程。
图1 软件复位序列
第1个起始位会使器件从期望接收微控制器数据的状态复位。在该模式下,器件处于接收模式并监视数据总线,能够检测到强制其内部复位的起始位。9位“1”用于强制复位那些无法通过前面的起始位复位的器件。这只在以下情况下发生:器件处于在总线上驱动应答(低电平)的模式中;或处于输出模式中,正在总线上驱动输出数据位0。在这两种情况下,由于器件将总线保持在低电平,所以无法产生前面的起始位(定义为SCL为高电平时SDA被拉低)。通过发送9位“1”,可以确保器件检测到NACK(即微控制器不将总线驱动为低电平,从而不应答EEPROM发送的数据),这样也会强制进行内部复位。
发送第2个起始位是为了防止在以下情况中可能发生的罕见的错误写操作:微控制器在向EEPROM发送写命令时被复位,并且在发送第1个起始位时EEPROM正在总线上驱动ACK。在这种特殊情况下,如果没有发送第2个起始位,而是发送了停止位,器件将启动写周期。只有在微控制器向EEPROM发送写命令时被复位的情况下,才可能发生这种错误写操作。
最后的停止位将终止总线活动,并将EEPROM置于待机模式中。
(2) 检查应答位
I2C通信的众多优点之一就是在接收到每个字节后发送应答位ACK。除了正在进行写周期之外,I2C接口EEPROM在接收到每个字节后总会发送1位低电平,表明已收到有效的起始位和控制字节。因此,主器件可以在整个运行期间监视接收到的ACK位,以检测可能发生的任何错误。在发送期间检查接收到的ACK是否为逻辑1(表明EEPROM没有响应)始终是一种好的做法,若接收到ACK为逻辑1,则需要执行一个错误处理程序来确定器件为何没有响应,并根据需要执行软件复位序列。
(3) 应答查询
串行EEPROM上的写操作要求在启动写操作后遵守写周期时间,使器件有时间存储数据。在此期间,正常器件操作将被禁止,微控制器对器件的所有访问尝试都将被忽略。因此,微控制器应等待写周期结束后再尝试访问EEPROM,这一点很重要。每个器件在其数据手册中都给出了最长的写周期时间,该参数通常用TWC表示。确保遵守写周期时间的一种简单方法是:在再次访问EEPROM之前执行规定时长的延时。但是,器件在短于规定的最长时间内完成写周期是很寻常的事。因而,用这种延时方法会使EEPROM完成写操作后的一段时间内微控制器仍在等待。为了消除这段额外的时间,使运行更加高效,强烈建议利用应答查询功能。由于I2C接口EEPROM器件在写周期内不会应答,所以可在发送停止条件并启动器件的内部写周期后持续地向器件发送写命令控制字节并进行应答查询,直到接收到指示写操作已完成的ACK位为止。图2是应答查询流程。
图2 应答查询流程
4 延长EEPROM使用寿命的方法
(1) 避免对同一区域反复执行写操作
不要在同一个单元或同一个页面上反复执行写操作,尤其是不要将某个页面设置成写入任何其他页面时都要更新的“目录”。
(2) 尽可能降低供电电压
在满足器件最低供电电压的前提下,供电电压越低,器件的使用寿命越长。
(3) 选择适当的写操作模式
EEPROM存储器的写操作有3种模式: 字节模式、页写模式和块写模式。有些器件支持所有上述3种模式,而另一些器件则可能只支持上述3种模式中的一种或两种。选择适当的写操作模式,可使EEPROM存储器的使用寿命得以延长。在仅需要改变存储器中的一个字节时,应采用字节模式。而在需要改变存储器中的某块内容或全部内容时,写操作模式的选择原则是:首先应考虑块写模式,其次再考虑页写模式,最后才是字节模式。
(4) 存储块轮换使用
一般应用中,要存储的数据比较单一,EEPROM空间与要存储的数据相比会大得多。为此,可采用一种存储块轮换使用的方法来延长EEPROM的使用寿命。其原理如下:
根据要存储的数据量将EEPROM空间分块,从第1块开始存储数据,当数据被改写N次后转到第2块存放,等到第2块中的数据被改写N次后再转到第3块存放,依此类推,直到最后一个块存放的数据被改写N次后,又转到第1个块重新开始。在这种解决方案中,系统掉电后再上电时可用来确定数据存储块首地址的方法有[2]: 找最大数据法、用后还原法和地址指针法。
结语
健壮性设计是确保系统具有优良质量特性的基本措施。本文介绍的技术实用、可靠,在对I2C串行EEPROM存储器进行应用设计时应该尽可能地考虑这些技术。