单片机的存储器结构存储的问题

51单片机存储器内存详解
查看: 791|
摘要: 51单片机当中的存储器从功能性上来划分可以分为程序存储器与数据存储器。一般来说单片机存储器的存储空间是能够进行存储空间拓展的,但是如何进行拓展则需要根据不同的存储器类型进行选择,本文就将为大家针对这个问题进行讲解。 访 ...
&&& 51当中的存储器从功能性上来划分可以分为程序存储器与数据存储器。一般来说单片机存储器的存储空间是能够进行存储空间拓展的,但是如何进行拓展则需要根据不同的存储器类型进行选择,本文就将为大家针对这个问题进行讲解。&&& 访问存储空间时,需要用到两个指针变量,为DPTR和PC。其中pc为程序计数器,指向下一条需要执行的指令的地址,DPTR为数据指针寄存器,这两个变量的长度都为16位,这是51单片机内部结构决定的,无法改变。所以这两个指针的寻址能力都为64K。这样看来,两类存储器的扩展能力都为64K。但是,如果实际扩展过存储器,就可以发现程序存储器的扩展能力并没有64K。&&& 为什麽会这个样子呢?这得从51单片机的存储空间的编址说起。这里仅作简单说明,具体可以看教科书。简单地说,内部程序存储器和外部程序存储器是一起编址的,它们分别占用64K地址的一部分,所以外部扩展时要减去内部的地址空间,当然要小于64K。而数据存储器是内外部分别编址,内外部数据存储器用不同的指令进行访问,所以不用担心单片机会混淆内外部数据存储器,所以外部数据存储器扩展能力有64K。
上一篇:下一篇:
Powered by &
这里是—这里可以学习 —这里是。
栏目导航:单片机的RAM\ROM\FLASH等存储空间到底怎么区别? - 知乎12被浏览2120分享邀请回答43 条评论分享收藏感谢收起0添加评论分享收藏感谢收起51单片机 关于快速的ADC和保存数据的问题
来源:csdn
【传感器检测到震动后给出脉冲,要求将其波形模拟出来。
我用STC12C5160S2单片机,将未知的电压波形连续ADC后,UART发至电脑。
电压波形我用AD扫描后后发送。
有以下问题:
1,ADC时间为90个时钟周期,这90个时钟周期用来保存ADC的数据,足够。但是若还要UART发送,不行。
2,若在有波形时保存ADC的数据,没有波形时UART发送,我尝试编了程序,数据会乱。
有什么解决方法请给出,若全盘推翻我的方案也可给出。谢谢。
程序中,一直在进行ADC,并且使能其中断。
int j1,j2;
uchar dat[];
void adc_isr() interrupt 5 using 1
//AD中断服务函数
ADC_CONTR &= !ADC_FLAG;
//Clear ADC interrupt flag
if(ADC_RES>0)//AD转换的结果在ADC_RES中 >0表示有电压
我也尝试了将此处的0提高了一些
dat[i]=ADC_RES;
ADC_CONTR = ADC_START;
for(;j2<j1;j2++)
UART_send(dat[j2]);
1. 只要UART通信波特率能够保证每次采样的数据及时发送出去就不会有问题。
2. 你这个程序也太不严谨,dat[]就不考虑溢出的可能性吗?数组下标应当添加溢出后的复位处理,否则数据必然乱。
1)如果出现j2<j1,那么程序就停止运行了?
2)当你连续发送字节前,需要根据TX标志,判断字节是否已经从串口移位出去了
3)根据你的波特率,计算一下你发送每帧数据所要的时间,如果时间够,可以将UART_send(dat[j2])
直接放在dat[i]=ADC_RES语句后,加快速度;
4)一般情况下,串口速度比较慢,所以应该加长采样间隔,定时进行A/D转换,每次都发送出去;
5)不想丢失A/D数据,就要加入判断,无用的数据不保存,有用的数据保存到一个大数组中(加上上限限制);发送时,判断TX标志,并顺序发送数组数据;
schlafenhamster:
必须保证采样的数据与发送的数据不同时进行
你可以不使用中断,读一个数据发送一个,都在main中进行。
如果对实时性要求不是很高,可以读1024个数据存起来,再发送。
baimeixiaoxia1:
多谢各位 我有了一想法,试出来后给各位看结果。
还会有后续的问题...
该回复于 10:22:41被版主删除
UART口很慢的。。。
你传输速度跟不上采样速度那能有什么办法,降低采样频率是最直接的办法
adc的值超过8位的话,可以拼起来发送,能稍微节省点传输时间
还有就是楼主的代码实在……就算方法对了,也会出其他问题的
baimeixiaoxia1:
1 STC的快速ADC的时间为70-470个时钟周期,可调。470个时钟周期为50us左右;而UART发送数据时间约为1ms;应注意:STC12C5A的ADC时钟为内部RC时钟。只能在ADC采样完成后就对数据进行发送,只能对数据进行保存。在所有数据采集完后再发送。
2 我采用的方法是:
2.1 连续进行ADC;
2.2 当ADC结果:ADC_RES&1后对数据保存;仍然进行ADC。
2.3 当ADC_RES&1,停止ADC,UART发送数据。
2 此种方法下,若用ADC中断来进行数据处理会很麻烦。所以就用轮询方式进行ADC。
3 我进行了计算:一个信号周期的时间&10ms。最多可以采200个数据。
以下是我的程序:
任何问题/疑问/对数据处理有更好办法/... 都可提出,谢谢!
#include "reg51.h"
#include "intrins.h"
typedef unsigned char BYTE;
typedef unsigned int WORD;
sfr ADC_CONTR
//ADC control register
sfr ADC_RES
//ADC high 8-bit result register
sfr ADC_LOW2
//ADC low 2-bit result register
//P1 secondary function control register
#define ADC_POWER
//ADC power control bit
#define ADC_FLAG
//ADC complete flag
#define ADC_START
//ADC start control bit
#define ADC_SPEEDLL 0x00
//420 clocks
#define ADC_SPEEDL
//280 clocks
#define ADC_SPEEDH
//140 clocks
#define ADC_SPEEDHH 0x60
//70 clocks
void InitUart();
void InitADC();
void SendData(BYTE dat);
void Delay(WORD n);
void ADC();
void SaveResult(WORD i);
void Sendwei(WORD dat);
WORD GetResult();
BYTE shuju[502][2];
//任何问题/疑问/对数据处理有更好办法/... 都可提出,谢谢!
void main()
InitUart();
InitADC();
if(ADC_RES & 0x00)
// ADC值第一次
& 0 0100 =4
SaveResult(i);
//保存第一次ADC&4的值
if(ADC_RES & 0x01)
SaveResult(i);
if(i&=300)//
SendData('E');
SendData('x');
SendData('c');
SendData('e');
SendData('e');
SendData('d');
SendData('!');
SendData('R');
SendData(':');
SendData('i');
SendData('=');
Sendwei(i);
SendData(' ');
for(j=0;j&i;j++)
dat = shuju[j][0];
dat = (dat&&2) + ( (shuju[j][1]) & 0x03) ;
Sendwei(dat);
SendData(' ');
SendData('!');
SendData(' ');
void Sendwei(WORD i)
BYTE qian,bai,shi,
qian = i/1000;
ge = i%10;
if(qian&0)
SendData(qian+0x30);
SendData(bai+0x30);
SendData(shi+0x30);
SendData(ge+0x30);
else if(bai&0)
SendData(bai+0x30);
SendData(shi+0x30);
SendData(ge+0x30);
else if(shi&0)
SendData(shi+0x30);
SendData(ge+0x30);
SendData(ge+0x30);
void SaveResult(WORD i)
shuju[i][0] = ADC_RES;
shuju[i][1] = ADC_LOW2;
WORD GetResult()
dat = ADC_RES;
dat = (dat&&2) +
(ADC_LOW2 & 0x03);
void ADC()
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START;
//Must wait before inquiry
while (!(ADC_CONTR & ADC_FLAG));//Wait complete flag
ADC_CONTR &= ~ADC_FLAG;
//Close ADC
void InitUart()
SCON = 0x50;
//8 bit data ,no parity bit
TMOD = 0x20;
//T1 as 8-bit auto reload
TH1 = TL1 = 0
//Set Uart baudrate
//T1 start running
void InitADC()
//Open 8 channels ADC function
ADC_RES = 0;
//Clear previous result
ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
//ADC power-on and delay
void SendData(BYTE dat)
while (!TI);
//Wait for the previous data is sent
//Clear TI flag
//Send current data
void Delay(WORD n)
while (n--)
while (x--);
任何问题/疑问/对数据处理有更好办法/... 都可提出,谢谢!
baimeixiaoxia1:
第一次发帖。请各位给出一件。3天后结贴。
免责声明:本站部分内容、图片、文字、视频等来自于互联网,仅供大家学习与交流。相关内容如涉嫌侵犯您的知识产权或其他合法权益,请向本站发送有效通知,我们会及时处理。反馈邮箱&&&&。
学生服务号
在线咨询,奖学金返现,名师点评,等你来互动大学堂最新课程
汇总了TI汽车信息娱乐系统方案、优质音频解决方案、汽车娱乐系统和仪表盘参考设计相关的文档、视频等资源
热门资源推荐
频道白皮书
何立民专栏
北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。导读:单片机程序程序存储空间(ROM)和数据,存储空间(RAM)详解,问题:STC89C52RC单片机:8K字节程序存储空间,512字节数据存储空间,,8K的程序存储空间是存储代码,也就是你写的程序生成的HEX文件的,存储空间存储变量,像u8x,y,z,u32a之类的临时变量掉电后数据丢失,数据写入后掉电不丢失,主要是单片机在运行的过程中写入数据或者读取数据,保存在单片机里面,设置的数据也不会丢失,
单片机程序程序存储空间(ROM)和数据
存储空间(RAM)详解
问题:STC89C52RC单片机:8K字节程序存储空间,512字节数据存储空间,内带2K字节EEPROM存储空间;它们分别存的是什么?
8K的程序存储空间是存储代码,也就是你写的程序生成的HEX文件的,相当于电脑系统的C
512字节相当于内存,存储空间存储变量,像u8 x,y,z,u32 a之类的临时变量掉电后数据丢失。
2K eeprom相当于电脑系统的硬盘,数据写入后掉电不丢失。主要是单片机在运行的过程中写入数据或者读取数据。像设置的闹铃值,设置好了就不用每次都去设置了,保存在单片机里面,即使掉电了,设置的数据也不会丢失,只需单片机上电再读取就好了。 单片机原理及系统结构
在此先详细分析51单片的存储器结构和寻址方法,再分析片外存储器的扩展,最后给出设计原理并分析系统结构。
图一:存储空间分布
51单片机存储器结构分析
8051单片机的存储器在物理结构上分为程序存储器空间和数据存储器空间,共有4个存储空间: 片内程序存储器、片外程序存储器以及片内数据存储器、片外数据存储器空间。
这种程序存储和数据存储分开的结构形式被称为哈佛结构。MCS-51使用哈弗结构,它的程序空间和数据空间是分开编址的,即各自有各自的地址空间,互不重叠。所以即使地址一样,但因为分开编址,所以依然要说哪一个空间内的某地址。而ARM(甚至是x86)这种冯诺依曼结构的MCU/CPU,它的地址空间是统一并且连续的,代码存储器/RAM/CPU寄存器,甚至PC机的显存,都是统一编址的,只是不同功能的存储器占据不同的地址块,各自为政。
MCS-51单片机存储器的配置特点
① 内部集成了4K的程序存储器ROM;
② 内部具有256B的数据存储器RAM(用户空间+SFR空间);
③ 可以外接64K的程序存储器ROM和 数据存储器RAM。
从物理结构的角度讲,51单片机的存储系统可以分为四个存储空间:既片内ROM,RAM和片外ROM、RAM。
从逻辑结构上看(既编程的角度),可以分为三个不同的空间:
片内、片外统一编址的64KB的程序存储器地址空间:0000H~FFFFH(用16位地址);,其中0000H~0FFFH为片内4KB的ROM地址空间,1000H~FFFFH为外部ROM地址空间;
256B的内部数据存储器地址空间(用8位地址),00H~FFH,分为两大部分,其中00H~7FH(共128B单元)为内部静态RAM的地址空间,80H~FFH为特殊功能寄存器的地址空间,21个特殊功能寄存器离散地分布在这个区域;
64KB的外部数据存储器地址空间(用16位地址):0000H~FFFFH,包括扩展I/O地址空间。
上述4个存储空间地址是重叠的,如图1所示。8051的指令系统设计了不同的数据传送指令以区别这4个不同的逻辑空间:CPU访问片内、片外ROM指令用MOVC,访问片外RAM指令用MOVX,访问片内RAM指令用MOV。
程序存储器用于存放编好的程序和表格常数。程序通过16位程序计数器寻址,寻址能力为64KB。这使得指令能在64KB的地址空间内任意跳转,但不能使程序从程序存储器空间转移到数据存储器空间。
程序存储器ROM
的片内和片外寻址
1.程序存储器ROM用于存放程序、常数或表格。
2.在51单片机中,由引脚 /EA 上的电平选择内、外ROM: EA=1时,CPU执行片内的4KROM中的程序; EA=0时,CPU选择片外ROM中的程序。
3.无论是使用片内还是使用片外ROM,程序的起始地址都是从ROM的0000H单元开始。
4.尽管系统可以同时具备片内ROM和外部ROM,但是在一般正常使用情况下,通过/EA的设定来选择其一(或者使用内部ROM,或者使用外部ROM)。
5.如果EA=1(执行片内程序存储器中程序时):如果程序计数器的指针PC值超过0FFFH(4K)时,单片机就要自动的转向片外的ROM存储器且从1000H单元开始执行程序(无法使用片外ROM的低4K空间)。
6.当程序超过4K时,有两种使用程序存储器ROM的方法:
①设置EA=0,使用外部ROM。从地址=0000H开始;
②设置EA=1,使用内部的4KROM和外部ROM(地址从1000H开始的单元)。
8051从片内程序存储器和片外程序存储器取指时的执行速度相同。
程序存储器六个特殊的单元:
在ROM中有六个单元具有特定功能。
0000H单元:复位时程序计数器PC所指向的单元,因此用来
存放程序中的第一条指令; 0003H单元:外部中断/INT0的矢量入口地址;
000BH单元:定时器T0溢出中断的矢量入口地址;
0013H单元:外部中断/INT1的矢量入口地址;
001BH单元:定时器T1的溢出中断矢量入口地址;
0023H单元:串行口接收、传送的中断矢量入口地址。
矢量入口单元:在编写中断程序时,写入对应的“跳板指令”
单片机第一条指令的两个特征:
①存放在ROM的0000H单元;
②必须是“跳转指令”以跳过下面的5个中断矢量,转到后面的真正的主程序入口0100H单元。
包含总结汇报、办公文档、专业文献、文档下载、教程攻略、资格考试、外语学习、旅游景点以及单片机程序存储空间和数据存储空间详解等内容。本文共3页
相关内容搜索
(window.slotbydup=window.slotbydup || []).push({
id: '4581014',
container: s,
size: '0,0',
display: 'inlay-fix'

我要回帖

更多关于 单片机程序存储器 的文章

 

随机推荐