我们知道OD(对象字典)是CANopen的核心,所有功能都是围绕它开展的,是协议栈的数据中心,良好的OD实现是协议栈高效稳定运行的基础,而OD的实现最基本的一点就是怎么去保存它。因为OD的内容比较杂,读写属性上,有只读数据、只写数据、可读写数据;保存要求上有非易失和掉电丢失两种类型;数据类型上有字符型、整型、长整型等等;存储格式上有8位、16位、32位等。其它的不管,本文现只讨论怎么利用单片机的资源去尽量满足OD的存储需求。
有人会以为这还要讨论么?只读的就放在只读存储器中,可写的就放在RAM中,需要掉电保存的就放在非易失可读写存储器中。话是这么说,但实际上问题很多,罗列如下:
1. 对协议栈只读并不表示对应用程序只读。
2. 可读写而又掉电保存的数据不能放在RAM里。
3. 频繁读写的数据不能放在非易失存储器中,因为非易失存储器往往速度慢,有写次数限制。
4. 单片机资源有限,存取方式和读写速度有限值,因此得合理利用。
既然有这些问题,我们先对OD的数据进行分析分类:
1. 系统只读参数。自节点出厂就无需更改,例如,节点硬件序列号、软硬件版本等。
2. 过程数据对象。频繁读写,掉电无需保存。例如,采集的模拟量、待输出的开关量。
3. 系统配置参数。可读写,偶尔配置,大部分时间只读。
基本上所有的OD对象都可以归到这三类中去。下面再以AVR单片机为例说说单片机的几类存储资源以及其特点:
| 类型 | 运行中读写属性 | 访问速度 | 容量 | 特点 |
FLASH | 程序存储器 | 只读 | 一般 | 较大 | 操作方便但只能放程序和初始化只读数据,掉电不丢失 |
SRAM | 数据存储器 | 读写 | 最快 | 小 | 操作方便,速度快,掉电数据丢失 |
EEPROM | 数据存储器 | 读写 | 读一般,写很慢 | 小 | 操作复杂,写速度极慢 |
看到上面这个表,你会马上把OD的三类数据存放位置定下来吧,系统只读参数放在FLASH中;过程数据对象放在SRAM中;系统配置参数放在EEPROM中。
实际上确实该如此安排,但是所有问题的解决了?NO,NO,NO!OD中的数据对象是怎么安排进存储器的?系统启动怎么初始化?怎么去访问?下面提供一种方案:
出厂设置随程序一起写入FLASH,然后系统重器开始运行,在软件初始化过程中,程序将出厂默认的整个OD对象从FLASH 载入到RAM中去,不论是OD的那种分类的数据;之后如果判断是第一次运行,将用RAM中属于的统配置参数的那一类数据去初始化EEPROM,否则用EEPROM中的系统配置参数去重新覆盖对应的RAM映像。好了初始化完成,开始运行,因为所有OD数据都load到RAM中,因此OD对外可以提供统一快速的数据服务接口,外部的读操作就是直接读RAM,写则是先写RAM映像,然后再判断如果是OD的系统配置参数那一类则同时更新EEPROM。最后要注意一点就是OD的对象属性等信息一定要放在FLASH中,否则将是一个极大的RAM开销。
上面方案优点是在满足OD需求的前提下能够提供统一快速的OD访问接口;能够及时存储非易失性数据;并能在软件上实现恢复出厂设置的操作而不增加额外的出厂设置备份空间(在EEPROM中置一标志就行了,自己去想)。明显的优点也意味着明显的缺点,就是占用较多RAM空间,只读数据和非易失性数据都要映射到RAM中,浪费了一部分RAM,这将使得本来就紧张的RAM资源更加紧张,好在一般节点上的OD内容一般不多,而且现在RAM非常便宜。
上面的方案同样适用于其他单片机,基本上现在的单片机上都有FLASH和RAM,而即使有的单片机没有EEPROM,但是本身FLASH区是可以运行中在线写入的,也可以当EEPROM用(但此时最好就不要来一个写一个了,因为FLASH是页擦除的,比较耗时间,因此建议做成批量写入方式,OD的0x1010和0x1011对象有涉及),实在不行还可以外扩。
关键字:单片机 存储器资源 存储与访问
引用地址:
怎样利用好单片机上的存储器资源来实现OD的存储与访问
推荐阅读最新更新时间:2024-03-16 15:31
51单片机入门——矩阵建盘的基本操作
矩阵键盘的原理图和基本原理 原理图 基本原理 首先我们要进行扫描,扫描矩阵键盘中每个按键的状态,对与矩阵键盘,我们只能逐行扫描,然后读取列的状态信号。如果R3行输出低电平,那么黄色按键如果有按下动作的话,那读取C2列信号也应该为低电平,而该行上其他没有按下动作的按键的列信号则为高电平。 每个按键内部的结构 独立按键 - 矩阵键盘 检测 每次输入检测是都只保证一个为低电平,其余为高电平,只要某一行输入0,在某一列也输出0,则检测成功(成功按下) 例题 代码如下 #include reg52.h sfr P4 = 0xC0; sbit HC138_A = P2^5; sbit HC1
[单片机]
51单片机 驱动蜂鸣器、继电器实验
//==声明区======================================== #include // 定义8051暂存器之标头档, P2-17~19 sbit buzzer = P3^7; // 声明蜂鸣器的位置 sbit relay = P3^6; // 声明继电器的位置 void delay(int); // 声明延迟函数 void pulse_BZ(int,int,int); // 声明蜂鸣器发声函数 void pulse_RL(int,int,int); // 声明继电器控制函数 //==主程序==========
[单片机]
单片机电流的一些经验理解
1、按理说,一个东西的负载电流,应该是它供给外部的电流,这时候也就是流出时,应该为正。 2、外接电阻一般是上拉,通常情况这种接法输出高电平时,内部输出开关管是截止状态,如果该引脚上有负载的话,负载电流经上拉电阻提供,引脚内部基本上不存在电流出入,(所以低功耗) 3、这么讲下去,当该脚输出低电平时(内部开关管导通,电压接近地),电流经电阻流入内部,这时候应该在单片机的相关技术文档中会详细说明单片机的工作电流,但总的来说,每个端口电流不要超过20毫安,否则容易使得器件损坏。描述为负。IO口的灌电流最大30ma左右,拉电流更小了 一般来说上拉或下拉电阻的作用是增大电流,加强电路的驱动能力 比如说51的 还有,p0口必须接上拉电
[单片机]
由单片机和多片DS1820组成的多点温度测控系统
摘要: DS1820是DALLAS公司生产的单线数字温度传感器,它可以在单片机的控制下组成多点温度测量系统。文章介绍了单线数字式温度传感器DS1820的工作原理,给出了用DS1820和89C51单片机构成的单线多点温度测控系统的应用电路及软件框图。
关键词: 数字温度计 单线制 多路温控仪 单片机系统 DS1820
1 概述
DS1820是美国DALLAS公司生产的单线数字温度传感器,它具有微型化、低功耗、高性能、抗干扰能力强、易配微处理器等优点,特别适合于构成多点温度测控系统,可直接将温度转化成串行数字信号供微机处理,而且每片DS1820都有唯一的产品号并可存入其ROM中,以使在构
[传感技术]
HPI在MCU和DSP接口中的应用
描述HPI接口的工作原理及C8051F060和TMS320VC5409(简称C5409)之间的接口电路设计,给出了HPI接口的软件设计。该系统具有设计灵活、数据传输速度快、适用于其他含有HPI接口的DSP应用系统,为开发人员提供了一种便捷稳定的数据共享、传输方式。 1TMS320VC5409的HPI-8接口 C5409的HPI-8是一个增强型8位HPI8接口,主要用来与主处理器接口。C5409内部有32K的RAM空间,除了DSP本身可以访问该RAM区域外,主机也可以通过HPI口实现对整个RAM的访问,从而实现主机与DSP的通信。HPI-8接口通过HPI控制寄存器HPIC、地址寄存器HPIA、数据寄存器HPID等3个
[单片机]
单片机2——动态数码管的一些实例
1.8只数码管滚动显示单个数字 #include reg52.h #include intrins.h unsigned char code duanma ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};// 显示段码值0~9 unsigned char code weima ={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//分别对应相应的数码管点亮,即位码 unsigned char tempdata ; void delay(int ms) { unsigned char j; for(;ms 0;ms--)
[单片机]
基于AVR单片机Megal6的电子时钟设计
1 引言 数 7 钟能长期、连续、可靠、稳定地工作;同时还具有体积小,功耗低等特点,便于携带,使用方便。数字钟是采用数字电路实现对 “ 时、分、秒 ” 数字显示的计时装置,广泛应用于个人家庭、车站、码头、办公室等公共场所,已成为人们日常生活中不可缺少的必需品。由于数字集成电路的发展和石英晶体振荡器的广泛应用,使得数字钟的精度远远超过老式钟表,钟表的数字化给人们生产生活带来了极大的方便,而且大大地扩展了钟表原先的报时功能。传统 MCS51 系列单片机的所有数据处理都基于一个累加器,因此累加器与程序存储器、数据存储器之间的数据转换就成了单片机的瓶颈;在 AVR 单片机中,寄存器由 32 个通用工作寄存器组成,并且任何一个
[单片机]
单片机编程经验总汇
经验之一:用“软件陷阱+程序口令”对付PC指针的弹飞 当CPU受到外界干扰,有时PC指针会飞到另一段程序中,或跳到空白段去。其实,如果PC指针飞到空白段去,倒也好处理。只要在空白段设立软件陷阱(拦截指令),将程序拦截到初始化段或程序错误处理段。但是,如果PC指针飞到另一段程序中去了,系统如何办?小匠在这里推荐一种方法——程序口令,思路如下: 1、首先,程序必须模块化。每个模块(子程序)执行一个功能。每个模块只有一个出口(RET)。 2、设立一个模块(子程序)ID寄存器。 3、为每个子程序配置一个唯一的ID号码。 4、每当子程序执行完毕,要返回(RET)之前, 先将本子程序的ID号
[工业控制]