单片机数据存储方法_单片机eeprom存储数据为什么与plc存储数据相差那么大 - CSDN
  • 本文着重介绍了51单片机存储器寻址空间的分布,讲述了单片机是如何进行存储程序,数据的。

    初学51总是会有这样的疑问,从电脑下载程序到开发板后,程序去哪了? C51中,用户或应用程序,系统程序和数据都是存放在哪的?

    51单片机从物理结构上,可分为片内,片外程序存储器,片内片外数据存储器。

    51单片机从功能上,有程序存储器,片内数据存储器,特殊功能寄存器,位地址空间,片外数据存储器。

    程序存储器

    51单片机的程序存储器用于存储代码和一些固定表格常数。
    可寻址的程序存储器空间为64KB。

    51单片机的从物理角度上可分为:片内,片外程序存储器,作为编址空间,编址规律是:先片内,后片外,片内片外连续,不重叠。
    如图:为51单片机程序存储器编址图。

    单片机如何执行指令?
    如图:

    无论片内程序存储器,还是片外程序存储器,他们的地址是共享的。如果片内4K ROM的话,地址就是0x0000-0x0FFF,从0x1000-0xFFFF就是外部ROM的地址空间。可外部ROM的0x0000-0x0FFF的这一部分是否使用呢,这取决于单片机EA引脚的电平值。EA=1时就是使用内部ROM的这一部分,外部ROM的这一部分浪费不用;EA=0时就是使用外部ROM的这一部分,内部ROM浪费不用。从CODE段读取数据要使用汇编的MOVC指令,单片机会根据MOVC指令、EA状态、要读取的地址值,来自动地判断从什么存储器里取数据。

    程序地址空间一般可以根据用户需要任意安排使用,但是cpu执行特殊程序的入口地址,用户必须按照规定存放相应的程序。
    特殊程序入口地址如图:

    数据存储器

    51单片机内外数据存储器是两个独立的地址空间,应单独编址。
    片内数据存储器地址空间"00H-FFH",RAM地址空间“00H-7FH”
    特殊功能寄存器SFR地址空间“80H-FFH”
    片外数据存储器地址空间“0000H-FFFFH”
    如图:

    为了使片内数据存储器的存储空间合理运用,对低128字节的RAM划分了不同的功能区。
    如图:

    位寻址区,地址空间20H-2FH,16个单元,共128位。

    数据缓冲区,地址空间30H-7FH,共80个单元。

    特殊功能寄存器
    特殊功能寄存器(SFR,Special Function Registers)别称专用寄存器,主要用于管理,控制,片内逻辑部件,并行i/o口,串行i/O口,定时器/计数器,中断系统等功能模块的工作。

    总结:对于数据存储器,则分为内部数据存储器(IDATA/RAM)和外部数据存储器(XDATA)两个部分,但这两个存储器就不像code存储器那样共享地址空间的了。一般 的8051芯片,内部RAM只有128B,从0x00-0x7F,而从0x80-0xFF则是SFR(CPU工作寄存器和各种外设寄存器都在此)的区域。对于8052来说,内部RAM有256B,所 以0x80-0xFF是高128B的RAM在使用。可这部分不是SFR专用的吗?是SFR专用,但注意,SFR的访问只能使用“直接寻址方式”(使用特定的汇编指令来实现),区别就 在这里。只有通过直接寻址访问的地址才是SFR,否则就是普通的RAM。至于外扩的RAM(XDATA),地址也是从0x0000-0xFFFF的,而且这里的0x0000和内部RAM的 0x00是不同的,是完全独立的两个空间。他们的访问方法也是不同的。MCS-51使用MOVX指令,来读写XDATA区。而且,访问XDATA区,是需要DPTR寄存器来辅助 的。因为只有DPTR才能装得下十六位的XDATA地址。参考:http://blog.csdn.net/shanzhizi/article/details/8997881

    特殊功能寄存器

    特殊功能寄存器(SFR,Special Function Registers)别称专用寄存器,主要用于管理,控制,片内逻辑部件,并行i/o口,串行i/O口,定时器/计数器,中断系统等功能模块的工作。

    51单片机中,专用寄存器与片内RAM统一编址,且作为直接寻址使用。

    51单片机有18个专用寄存器,其中3个是双字节寄存器,占用21个字节。

    在SFR块的地址空间80H-FFH中,仅仅只有21个字节作为特殊功能寄存器离散分布在这128个字节范围中,其余字节无定义,但是用户不能对这些字节进行“读写操作”

    下图为特殊功能寄存器的名称,表示符,地址一览表。

    展开全文
  • 51 单片机数据存储

    2019-09-09 11:07:41
    数据存储类型来说,8051系列有片内、片外程序存储器,片内、片外数据存储器,片内程序存储器还分直接寻址区和间接寻址类型,分别对应code、data、xdata、idata以及根据51系列特点而设定的pdata类型,使用不同的...

    从数据存储类型来说,8051系列有片内、片外程序存储器,片内、片外数据存储器,片内程序存储器还分直接寻址区和间接寻址类型,分别对应code、data、xdata、idata以及根据51系列特点而设定的pdata类型,使用不同的存储器,将使程序执行效率不同,在编写C51程序时,最好指定变量的存储类型,这样将有利于提高程序执行效率(此问题将在后面专门讲述)。与ANSI-C稍有不同,它只分SAMLL、COMPACT、LARGE模式,各种不同的模式对应不同的实际硬件系统,也将有不同的编译结果。

    在51系列中data,idata,xdata,pdata的区别:

    data:  固定指前面0x00-0x7f的128个RAM,可以用acc直接读写的,速度最快,生成的代码也最小。

    idata:  固定指前面0x00-0xff的256个RAM,其中前128和data的128完全相同,只是因为访问的方式不同。idata是用类似C中的指针方式访问的。汇编中的语句为:    mox ACC,@Rx.(不重要的补充:c中idata做指针式的访问效果很好)。

    xdata:  外部扩展RAM,一般指外部0x0000-0xffff空间,用DPTR访问。

    pdata: 外部扩展RAM的低256个字节,地址出现在A0-A7的上时读写,用movx ACC,@Rx      读写。这个比较特殊,而且C51好象有对此BUG,建议少用。但也有他的优点,具体用法属于中级问题,这里不提。


    单片机C语言unsigned char code table[] code 是什么作用?

      code的作用是告诉单片机,我定义的数据要放在ROM(程序存储区)里面,写入后就不能再更改,其实是相当与汇编里面的寻址MOVX(好像是),因为C语言中没办法详细描述存入的是ROM还是RAM(寄存器),所以在软件中添加了这一个语句起到代替汇编指令的作用,对应的还有data是存入RAM的意思。

      程序可以简单的分为code(程序)区,和data (数据)区,code区在运行的时候是不可以更改的,data区放全局变量和临时变量,是要不断的改变的,cpu从code区读取指令,对data区的数据进行运算处理,因此code区存储在什么介质上并不重要,象以前的计算机程序存储在卡片上,code区也可以放在rom里面,也可以放在ram里面,也可以放在flash里面(但是运行速度要慢很多,主要读flash比读ram要费时间),因此一般的做法是要将程序放到flash里面,然后load到 ram里面运行的;DATA区就没有什么选择了,肯定要放在RAM里面,放到rom里面改动不了。

    bdata如何使用它呢?
    若程序需要8个或者更多的bit变量,如果你想一次性给8个变量赋值的话就不方便了,(举个例子说说它的方便之处,想更深入的了解请在应用中自己琢磨)又不可以定义bit数组,只有一个方法

    char bdata MODE;
    sbit MODE_7 = MODE^7;
    sbit MODE_6 = MODE^6;
    sbit MODE_5 = MODE^5;
    sbit MODE_4 = MODE^4;
    sbit MODE_3 = MODE^3;
    sbit MODE_2 = MODE^2;
    sbit MODE_1 = MODE^1;
    sbit MODE_0 = MODE^0;
    8个bit变量MODE_n 就定义好了,这是定义语句,Keilc 的特殊数据类型。记住一定要是sbit不能 bit MODE_0 = MODE^0;赋值语句要是这么些C语言就视为异或运算

    //-------------------------------------------------------------------------------------------------------------------------------------------

    空间名称

    地址范围

    说明

    DATA

    D:00H~7FH

    片内RAM直接寻址区

    BDATA

    D:20H~2FH

    片内RAM位寻址区

    IDATA

    I:00H~FFH

    片内RAM间接寻址区

    XDATA

    X:0000H~FFFFH

    64KB常规片外RAM数据区

    HDATA

    X:0000H~FFFFFFH

    16MB扩展片外RAM数据区

    CODE

    C:0000H~FFFFH

    64K常规片内外ROM代码区

    HCONST(ECODE)

    C:0000H~FFFFFFH

    16MB扩展片外ROM常数区(对Dallas390可用作代码区)

    BANK0~BANK31

    B0:0000H~FFFFH:

    B31:0000H~FFFFH;

     

    keil生成的文件:
    .plg:编译器编译结果
    .hex和.bin:可执行文件
    .map和.lst:链接文件
    .o:目标文件
    .crf、.lnp、.d和.axf:调试文件
    .opt:保存工程配置信息
    .bak:工程备份文件

    M51文件,startup文件。

     

    bit :是指0x20-0x2f的可位寻址区

     

    展开全文
  • 在软件角度来看,程序和数据存储分为以下几个部分 代码段和常量段都可以用于保存常量数据,其主要区别是,如果常量可以作为汇编指令的一个操作数,则该常量被编译进代码段。如果不能用一个汇编操作数表示,则...

    说明:文章来源

    EDN电子技术设计:嵌入式程序开发需要知道的存储器知识

    MCU 中常使用的存储器类型有:FLASH、RAM、ROM(包括EEPROM)
    在软件角度来看,程序和数据的存储分为以下几个部分
    这里写图片描述

    代码段和常量段都可以用于保存常量数据,其主要区别是,如果常量可以作为汇编指令的一个操作数,则该常量被编译进代码段。如果不能用一个汇编操作数表示,则存于常量段。如 “uchar a=0x05;” 中的 “0x05” 将被编译成代码 “mov #0x05, a”;如果是 “uchar a[]={0x05, 0x06}” 则 “0x05,0x06” 被放置于常量段, 在初始化 a[] 的时候会有一段汇编指令用于将常量段中的内容拷贝到 a[] 中。

    软件存储区与硬件存储器类型是怎么对应的呢?一般来讲如下:
    这里写图片描述

    1.MCU 中的 ROM 通常用于存储制造商信息、控制器型号等信息;
    2.对于 x86 体系结构的系统,因为没有 Flash 类型的存储器,所以,所有的软件存储区最终都加载到内存中,但是其内存是分段的,用户对不同内存段的访问权限不同,其代码段和常量段不可以被用户修改,如果意外修改则抛出段错误异常。

    知道了存储器类型和各存储区的划分之后,让我们来看以下三组程序:

    static void ProcStr(void)
    {
        uchar Str[] = {"12345"};
    }

    这段程序中,Str[] 是一个局部数组,其大小为 6,占用的堆栈空间是 2 个字符;”12345” 是常量,被存储在常量段;Str[] 的初始化过程,相当于从常量区拷贝 6 个字符的数据到栈中,这 6 个字符是”12345\0”。

    static void ProcStr(void)
    {
        uchar Str[] = "12345";
    }

    这段程序中,Str[] 是一个局部数组,其大小为 6,占用的堆栈空间是 2 个字符;”12345” 是常量,被存储在常量段;Str[] 的初始化过程,相当于从常量区拷贝 6 个字符的数据到栈中,这 6 个字符是 “12345\0”。

    static void ProcStr(void)
    {
        const uchar* Str = "12345";
    }

    这段程序中没有数组,唯一的 Str 是一个局部指针,其大小为 4(在 32 位系统中),因此这段程序只占用 4(在 32 位系统中) 个字符的堆栈空间;”12345”是常量,被存储在常量段;Str 的初始化过程,是将指针 Str 初始化为常量”12345”的地址,后续程序通过指针 Str 直接访问常量段,无需内存拷贝过程。


    从以上分析可以看出,前两种方法是一样的,都需要为局部数据分配存储空间,并将静态存储区的数据拷贝过来,而最后一种方法是通过指针直接访问静态数据而无需拷贝。如果字符串长度大于系统中指针的长度,第三种方法将在时间和空间上大大优于前两种方法(第三种方法极大的节省了堆栈空间,并减少了拷贝数据所用的时间)。

    但是,对于 MCU 来说,并不总是第三种方法好,原因在于第三种方法是直接访问常量段,由上面的表可知,对于将常量存储于 Flash 的 MCU 来说,访问常量段要比访问 RAM 慢得多。因此,如果接下来要频繁访问这个字符串,那么,采用前两种方法在速度上将会更优一些,理由是前两种方法只需要访问一次 Flash,而第三种方法则每次都需要访问 Flash。

    当然,如果在接下来的程序中,需要修改字符串 Str 中的内容,那就只能采用前两种方法,第三种方法将会提示错误。

    特殊说明:今天讲的一些内容跟编译器的特性相关,不同编译器,甚至相同编译器的不同版本间存在一定差异。

    展开全文
  • 单片机串口接收的几种常用的数据处理方法 一、为什么串口接收的数据需要处理 我们在做项目的时候经常会用到串口,当我们用串口和别的设备通讯的时候就需要严格遵循通讯协议,然而,仅仅是遵循通讯协议是不够的,因为...

    单片机串口接收的几种常用的数据处理方法

    一、为什么串口接收的数据需要处理
    我们在做项目的时候经常会用到串口,当我们用串口和别的设备通讯的时候就需要严格遵循通讯协议,然而,仅仅是遵循通讯协议是不够的,因为单片机串口受到别的信号干扰的时候,容易出现数据错误,特别是串口发送的第一个字节和最后一个字节。一旦出现这种情况,设备之间的通讯可能会受到影响,甚至会导致系统瘫痪。另外,串口收到数据的时候,我们也需要判断一帧数据的长度,特别是指令发送比较频繁的时候。因此,串口在接收到数据之后应该先进行数据处理,再执行命令,这样能够增强产品的稳定性。

    二、串口接收重点关注的几个标志
    为了保证通讯的稳定性,一般的通讯协议会加入帧头、帧尾、数据长度、校验这四个标志中的一个或多个。它们的作用如下:
    1、帧头:串口发送数据的第一个字节是最容易出错的,如果你把重要的指令放在第一个字节,一旦出现错误,可能会使从机执行错误的操作。而帧头能够有效规避这个问题。
    2、帧尾:和帧头类似,帧尾也能避免最后一个字节出错,同时,它也可以作为接收端接收完成的标志。
    3、数据长度:它可以作为接收端接收完成的标志。有时也能作为判断数据是否正确的标志。
    4、校验:能够有效避免校验以外的所有数据的错误,但是校验正确不代表数据一定没有出错,每种校验方式都有一定的缺陷。
    帧头、帧尾、数据长度和校验,这四种标志加起来之后能够大大的增强数据传输的稳定性,但不是每个通讯协议都会包含以上四个标志,可能只会用到其中的一两个。因为如果要发送的主要数据本身就比较长,加上这个几个标志之后会更长,这对于那种传输速度慢、传输数据时间长、传输指令频繁处理速度慢的设备来说,较长的指令可能会影响工作效率。具体我就不多说了,我今天主要讲的是接收数据的处理方法,大家根据自己的协议选择合适的处理方法就行了。

    三、常用的几种数据处理方法
    1、判断帧头:串口接收到第一个数据之后先判断是否是帧头,如果帧头正确就存起来继续收,反之则丢掉继续等帧头。示例代码片段如下:

    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断
    {
    	Res = USART_ReceiveData(USART1);//读取接收到的数据,同时也清除了中断标志位
    		   
    	USART_RX_BUF[USART_RX_STA ++] = Res;
    	if(USART_RX_BUF[0] != 0xA5 && USART_RX_STA == 1)
    	{//帧头错误
    	     USART_RX_STA = 0;//重新接收
    	}
    	if(USART_RX_STA >= USART_RX_Len)
    	{//接收完成
    	    USART_RX_STA = 0;
    	    USART_RXHANDLE_FLAG = 1;
    	}
    }
    

    这种处理方法能够有效避免第一个字节出错的问题,我就试过一次主设备那边传过来的数据帧头前面多了一个字节(可能是刚开始传输的时候电压不稳定产生的纹波),用这种方法就能够之间把第一个错误的数据丢掉,从正确的帧头开始接收。但是这种方法不能够检查帧头后面的数据是否正确。
    2、判断帧尾:可以把帧尾作为一帧数据接收完成的标志。另外,当接收缓存存了多个指令的时候,帧尾能够帮助我们在一堆数据中区分出哪些数据是同一个指令的。当然,如果仅仅是区分数据用帧头也可以。不过这种办法必须保证帧尾和其他数据不一样,不然就会出现错误的判断。所以有些人为了避免这个问题会用两个字节作为帧尾,不过这样一来,数据长度就更大了,影响通讯效率。
    3、根据数据长度判断是否完成接收:可以通过数据长度判断接收是否完成。如果协议里面的指令长度不是统一的,我们就不能根据固定的长度来接收数据。这个时候在一帧数据里面加入数据长度这个标志,就能够给单片机一个判断的准则,单片机接收到数据长度这个标志之后,根据这个长度来接收剩下的数据。示例代码片段如下:

    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断
    {
    	Res = USART_ReceiveData(USART1);//读取接收到的数据,同时也清除了中断标志位
    		   
    	USART_RX_BUF[USART_RX_STA ++] = Res;
    	if(USART_RX_BUF[0] != 0xA5 && USART_RX_STA == 1)
    	{//帧头错误
    	     USART_RX_STA = 0;//重新接收
    	}
    	If(USART_RX_STA == 4)
    	{
    	USART_RX_Len = USART_RX_BUF[3];//数据长度
    	}
    	if(USART_RX_STA >= (USART_RX_Len + 4))
    	{//接收完成
    	    USART_RX_STA = 0;
    	    USART_RXHANDLE_FLAG = 1;
    	}
    }
    

    4、根据接收时间判断一帧数据的长度。根据波特率计算出两个字节传输的时间间隔,接收到数据之后定时器开始计时,在定时器中断触发之前收到数据就清空,重新计时,超过两个字节的间隔时间,就认为是一帧数据接收完成。具体的程序我就不写了,这个网上能找到很多例程。这种方法适合接收长度不定的情况,在这个方法的基础上还可以加上帧头帧尾等标志,增强稳定性。
    5、校验处理:校验一般是在接收完成之后进行,校验是很必要的,因为它包含一帧数据的所有字节,通过校验能够大大的减少出错的概率。

    四、总结
    其实串口接收数据处理主要要注意两点,第一点是单片机如何确定一帧数据接收完成,第二点是单片机如果判断接收到的数据是正确的指令。第一点可以通过帧尾,数据长度等标志确定接收完成。第二点可以先通过帧头初步判断指令的正确性,再通过校验二次处理,判断指令是否正确接收。

    关于串口接收数据处理的相关内容就介绍到这里,如果还有什么问题,可以留言,如果文章有哪里写的不对,欢迎指正,谢谢!

    展开全文
  • 单片机测试系统的数据存储和管理 时间:2007-12-10 09:48:00 来源:单片机及嵌入式系统应用 作者:北京航空航天大学 赵成 袁海文 摘要 介绍一种应用于单片机洲试系统的链式存储结构,其特点在于采用数据...
  • STM32单片机数据在内存中的存储方式 设一个数为 uint16_t a = 0x1234 ,它在单片机内存中的存放地址为 0x20000002,测0x20000002中存放0x34(低位),在 0x20000003中存放0x12(高位数)。基地址存放低位数据的这种...
  • 尊重原创,转载请说明出处……   在工作中用单片机很久了,对通信数据的处理有一些小小的心得体会。分享出来供讨论和指正。 以下讨论基于C语言。...2、使用链表的方式进行数据存储。每个字节做成一个节...
  • 存储器分类如下:单片机变量存储如下:
  • 51单片机数据区详解

    2019-01-09 00:55:25
    51单片机数据区详解 从数据存储类型来说,8051系列有片内、片外程序存储器,片内程序存储器还分直接寻址区和间接寻址类型,以及根据51系列特点而设定的pdata类型。使用不同的存储器,将使程序的执行效率不同,在编写...
  • 51单片机每隔1s读取一次DS18B20温度传感器数据,将温度数据不断存储到SD存储卡中,同时有串口不断输出温度数据。带proteus仿真。
  • 单片机片内RAM存储区首地址设置为60H、片外存储器存储区首地址设置为4000H,存入片内存储区内容为04H-14H共17个字节 ,读取片内首地址为60H单元内容,将该内容传送到片外数据存储器存储区中保存(首地址4000H),将...
  • 51之51单片机RAM数据存储区学习笔记 转自:http://www.eeworld.com.cn/mcu/2014/0826/article_16044.html 1.RAM keil C语言编程 RAM是程序运行中存放随机变量的数据空间。在keil中编写...
  • 51单片机数据类型转换问题 这两天我试了试STC8A4K系列单片机开发一些小型仪表项目,单片机型号为STC8A4K60S2A12。封装是LQFP44,使用的是数码管显示的当前数据,在这显示函数中呢,有几句函数是将一整个数据拆分开...
  • 一个把WAV文件数据改为单片机数据的软件
  • 如果所有的变量超过单片机small模式下的128B大小,则必须对变量进行初始化,否则超过RAM大小变量的值是不确定的,在small模式下超过128B大小的变量也必须在编译器中重新设定存储器的存储模式。
  • 一、总线概述 计算机系统是以微处理器为核心的,各器件要与微...而数据总线用于传送数据,控制总线用于传送控制信号, 地址总线则用于选择存储单元或外设。 二、单片机的三总线结构 51系列单片机具有完善的总线接...
  • 单片机片内存储器存储区首地址设置为60H、片外存储器存储区首地址设置为4000H,存入片内存储区内容为04H-14H共17个字节 ,读取片内首地址为60H单元内容,将该内容传送到片外数据存储器存储区中保存(首地址4000H),...
  • 单片机数据传送类指令教程:http://www.51hei.com/mcuteach/242.html寄存器教程:http://www.51hei.com/mcuteach/245.html我看懂了单片机传送类指令的教程!我觉得我自己好厉害啊哈哈哈哈哈哈哈。一遍看不懂看两遍,...
  • 我用51单片机通过IIC向EEPROM存储数据,然后再把数据读出来,再通过串口发送出去, 再用串口调试工具(eaglecom)查看数据。。。最后发现一次只能发送或者读取12个 字节,大于12个字节之后的数据全是0xff。不知道...
  • 包含单片机常用数据结构+部分算法。顺序表丶链表、双向循环链表、队列链表存储、循环队列均有。算法包括,一个串口缓冲算法,可以解析帧头帧尾,固定数据长度的数据包。另一个是归排序,都已经验证通过。
1 2 3 4 5 ... 20
收藏数 23,322
精华内容 9,328
关键字:

单片机数据存储方法