由于AVR的EEPROM写周期比较长(一般为毫秒级),因此在编程使用过程中要特别注意.对于读EEPROM没什么好说的,读一个字节的数据要耗费4个时钟周期,可以忍受,写就比较麻烦了,虽然放在EEPROM的数据都不是频繁访问的;虽然可以用读-比较-写的机制降低EEPROM的写操作频度,但在写入过程中,过长的写入周期还是会造成一些问题,下面就分析一下几种方式的EEPROM写操作.

  1. 循环查询式

将地址和数据写入EEPROM相关的寄存器,置写标志后就循环不断查询写完成标志,直到写完成,退出循环,顺序执行其他程序.在置写入标志到写完成的这段时间,程序除了不断查询写完成标志和响应硬件中断之外什么也不干,这段时间就这么浪费了,如果是个实时性要求比较高的应用,浪费的就不仅是时间了,很可能在这段时间里I/O状态的变化不能得到及时的响应,如果一下子要进行多个字节的EEPROM的写入操作,那情况会更糟.针对这种情况,有种解决办法就是,这个写完成查询放在软件的死循环中(无操作系统的情况下,系统启动后都要进入一个死循环),每循环一次查询一次写完成标志,这样就不必一直等待写操作完成而可以干别的事情了,但是这样会带来两个问题.一是,如果死循环周期无法保证,则每一次的EEPROM写操作的完成标志查询也得不到保证,从而进行一次EEPROM写操作的周期也无法保证(最长延迟时间就是一个死循环周期的最长时间);二是,在执行一次EEPROM写入操作到写完成这段时间里死循环里其它的子程序不能进行EEPROM读写操作.第一个问题如果能保证最大循环周期在延迟允许范围内就不是问题了,否则就得采取下面讲到的方式二了;第二个问题的解决方法是每次EEPROM读写操作都要在其中加入对EEPROM写完成标志寄存器的判断,如果有数据正在写入,则等待或退出,但等待和退出又会造成等待延迟和写入操作不成功的问题,解决办法是先放入一个数据缓冲区,待上一次写入操作完成,再从缓冲区里拽出一个字节进行下一次写入周期,但这又会涉及到选择合适的缓冲区大小以及的问题,这个问题在下面中断式操作里继续讨论.

  1. 定时查询式

在写入EEPROM地址和数据寄存器置写标志后启动定时器,定时查询写完成标志,这种方法继承了方式1的大部分优缺点,唯一的进步就是能够确定写操作延迟时间为定时周期.

  1. 中断式

编写EEPROM写完成中断子程序,设置一个FIFO缓冲区,要写入的数据先放入这个FIFO,如果EEPROM操作空闲,则从FIFO中揪一字节数据出来写EEPROM,置完写完成标志就返回,然后去干别的事情,EEPROM写完成产生一个中断,在中断服务程序中再从FIFO中揪一个字节去写EEPROM,如此循环直到FIFO空,这种方式虽然能在第一时间完成一次写操作,但是还是有个和和方式1中提到一样的问题,怎么选择这个FIFO的大小.小了,待写入数据可能溢出丢失,大了,多大算大,1K够不够,10K够不够,硬件上有这么多RAM空间么,这就需要根据实际资源和系统需求来定了.如果EEPROM写操作频率很低,比一次EEPROM写操作间隔还要长得多,那么几个单位的FIFO就足够了;如果EEPROM写操作频率可能很高或一次大批量连续写入数据就要求很大的FIFO,达到能够保证数据不丢失,这就要根据批量数据大小和写频率来定了,另外还要考虑可用RAM空间的限制来找出最佳值,同时有FIFO溢出一定要制定相应的应对措施.

最后注意两点:

  1. 读写之前一定要检测是否已经有EEPROM写操作;在写完成之后一定要再读出写入的数据校验写入操作是否成功,不成功则EEPROM损坏,要做好应对措施.
  2. 如果要保存一个16位的数据,一定要保证在这16位数据分成的两字节都成功写入了EEPROM再去读该数据,否则在刚写完一个字节就去读该数据,得到的数据显然不是你想要的,如果该数据是一重要参数,后果可想而知.

    (2007.11.5)

旧文备份:AVR读写EEPROM分析的更多相关文章

  1. 旧文备份:简单CANOpen 协议说明

    (十年前的旧文,不舍等扔) 创建日期:2005-11-17 修改日期:2005-11-17 文件名称:简单CANOpen 协议说明.doc 作者:winshton 版本:V1.0 (注:本文以24in ...

  2. 旧文备份:怎样利用好单片机上的存储器资源来实现OD的存储与访问

    我们知道OD(对象字典)是CANopen的核心,所有功能都是围绕它开展的,是协议栈的数据中心,良好的OD实现是协议栈高效稳定运行的基础,而OD的实现最基本的一点就是怎么去保存它.因为OD的内容比较杂, ...

  3. 旧文备份:FFTW介绍

    1. FFTW介绍 FFTW由麻省理工学院计算机科学实验室超级计算技术组开发的一套离散傅立叶变换(DFT)的计算库,开源.高效和标准C语言编写的代码使其得到了非常广泛的应用,Intel的数学库和Sci ...

  4. 旧文备份:硬盘MBR引导记录损坏的一种修复方法

    硬盘MBR信息损坏原因:硬盘上安装了windows XP和linux双系统,在windows下安装一套软件,破解的时候修改了硬盘的序列号,结果导致引导系统的grub无法完成linux的引导,只能进到w ...

  5. 旧文备份:rtlinux安装手册

    前段时间接触了几天RTLinux,折腾了好几天才总算把它安装上,得益于Prof. Chang-Gun Lee的安装建议,觉得该文档可能会对准备尝试安装RTLinux的朋友们有帮助,本人英语很烂,也比较 ...

  6. 旧文备份: 怎样实现SDO服务

    SDO是CANopen协议中最复杂的一部分,带有应答机制,有多种传输方式,并且完整的SDO功能节点需提供1个SDO server和多个SDO client,因此SDO的实现异常困难,协议多种传输方式的 ...

  7. 旧文备份:在CANopen网络中通过LSS服务设置节点地址和网络波特率

    CANopen专有个子协议用来描述怎样去通过网络设置节点地址和波特率,就是CiA DSP-305,大伙都叫LSS协议,是Layer Setting Services的缩写,不太好翻译,可以叫底层设置服 ...

  8. 旧文备份:CANopen协议PDO的几种传输方式

    (于2007.1.22) 由于PDO所传输的数据内容是无协议的且分配的标识符范围较SDO靠前,因此,其效率和优先级都是较高的,通常用于实时过程数据的传输. PDO是生产/消费类型的通讯方式,数据只有一 ...

  9. 旧文备份:CANopen协议中SDO服务

    SDO是服务数据对象接口(Service Data Obiect)的缩写,顾名思义提供服务数据的访问接口,服务数据就是一些实时性要求不高的数据,一般是指节点配置参数,因此,SDO一般用来配置和获得节点 ...

随机推荐

  1. requirej入门(二)

    requirejs中的一些基本知识,包括API使用方式等. 基本API require会定义三个变量:define,require,requirejs,其中require === requirejs, ...

  2. volatile的作用和原理

    1.保持内存可见性内存可见性:所有线程都能看到共享内存的最新状态.每次读取前必须先从主内存刷新最新的值.每次写入后必须立即同步回主内存当中.Java通过几种原子操作完成工作内存和主内存的交互:lock ...

  3. pat1101. Quick Sort (25)

    1101. Quick Sort (25) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CAO, Peng There is a ...

  4. Postman+Newman+Jenkins APItest自动化集成测试

    postman做接口测试简单易用很容易上手,但是接口越来越多,每次手动点击runner进行测试不灵活,最近就研究了下newman,利用newman实现接口的自动化测试,但是每次需要命令行操作也不方便, ...

  5. h5:WebSocket

    实时 Web 应用的窘境 Web 应用的信息交互过程通常是客户端通过浏览器发出一个请求,服务器端接收和审核完请求后进行处理并返回结果给客户端,然后客户端浏览器将信息呈现出来,这种机制对于信息变化不是特 ...

  6. sass-基础

    导入: sass的导入(@import)规则和CSS的有所不同,编译时会将@import的scss文件合并进来只生成一个CSS文件. 但是如果你在sass文件中导入css文件如@import 'res ...

  7. TeeChart for .NET常用属性总结

    本文总结了图表控件Teechart for .NET常用的一些属性,对图表开发人员来说是一个很好的参考. 原文链接:http://blog.csdn.net/u010270772/article/de ...

  8. SpringBoot常用应用程序属性

    参考地址: https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.h ...

  9. Java —异常

    异常简介 有异于常态,和正常情况不一样,有错误出现,阻止当前方法或作用域,称为异常. Java中的异常类都继承Throwable类,它有两个子类:Error和Exception.Error很少接触,主 ...

  10. 数组模拟栈(C语言)

    用数组模拟栈的实现: #include <stdio.h> #include <stdlib.h> #define STACK_SIZE 100 typedef struct ...