现在的位置: 首页 > 综合 > 正文

嵌入式启动方式-从Nand启动cpu .中(学习整理笔记)

2013年02月13日 ⁄ 综合 ⁄ 共 4302字 ⁄ 字号 评论关闭

嵌入式启动方式-从Nand启动cpu .中(学习整理笔记)

《51单片机编程与原理》

我们在上篇讲到的是51单片机的程序存储器和启动方式

----数据存储器(内存)和程序存储器硬件结构差不多,但学起来更麻烦。

书比较难啃,建议看郭天明的《十天学会单片机》视频,不想往画电路板方面发展的可以只先看前面一部分,我就是这么做的,入了门再看书就容易了。

--------------------------------------------------------------------------------------------------------

首先回答大家的疑问

1既然前面已经讲过程序存储和单片机启动了,为什么还不讲嵌入式的启动呢?

答案:因为单片机的程序存储器和内存,在硬件和软件上被严格分开的,完全可以分开来讲。嵌入式却有所不同。

2没有内存,只靠程序存储器单片机能正常启动运行吗?

答案:不能,事实上我们看到有的单片机并没有外部扩展的数据存储器(内存),如果看书不仔细,这给人以误导,事实上出厂的cup内部固定有内部内存,只是容量很小,只有多少K。而扩展的可以达到M。

3那前面为什么没讲内存工作就把单片机启动起来了?

答案:那是在假设有内存工作的情况下来讲的,放在一起讲容易混淆和不理解。而且所有写的演示代码都是c语言的,这并不严格,只是为了更直观。(毕竟学c的人多)

------------------------------------------------------------------------------------------------------

先理解程序和数据(内存)存储器怎么严格分开的:

     程序和数据没有共用一个存储器,而是两个存储器,各自有自己的数据,地址,控制线和cpu相连。(单片机就是一种微型简单的cpu,除自身自带的以外,外部可扩展内存硬件等)

   单词move:移动   jump:跳

  

       就拿汇编语言来说:取指令,cpu先找pc指针所指向的程序存储器中的地址,然后从这个地址中拿取数据(指令),拿回cpu后编译执行。(启动时从00000地址拿指令)

                                     movx指令,cpu根据指令中的信息提取出要取数据的地址addr,这里是对数据存储器(内存)操作,也是拿对应地址上的数据。

       两者都是通过向存储器发送地址来实现存/取数据(数据的含义很广,可以是内存中的数据也可以是程序存储器中的指令数据,不要只想到内存)

---------------------------------------------------------------------

     
存/取数据的方式都很简单,把数据从一个地址移动到另一个地址。
关键是按什么样的方式和规律出来存取,以使程序能正常运行。

我们先理解两点:      

        
取指令cpu是通过pc来找地址,取数据(指令)。
       

         movxcpu是提取指令中的地址信息来取/存数据
       

         这两者有很多不同,关系到以后对程序中代码区,数据区,常量等术语的理解。

         注意观察:         取指令中只有读取出数据,禁止有写入或做修改。(这就是c语言中的数据只读和保护概念)    

         为什么程序存储器要保护起来?

假如你写的程序中有n=10;然后用n--n>0判断语句,这个计数功能让单片机的led灯泡闪烁十次。如果程序运行起来以后程序存储器是可写的,而你编写的程序指针有错误,正好不小心把里面的10修改成了0或其他,那下次启动单片机还会照你所设计的去闪烁吗?(如果修改的是其他地址都可能崩溃)   

        你已经写好并存入存储器的程序,你也不会希望别人插上一脚,把你的成果改的面目全非吧!

----------------------------------------------------------------------

      前面描述了将写好的程序存入程序存储器,又提到了单片机从程序存储器中提取到指令然后交给cpu执行。

分析:

      程序都已经存到程序存储器了为什么还要提取指令?

      什么是提取指令?

      提取指令之后接着做什么?

      内存一直在打酱油,它什么时候工作?

首先

            永远记住以下话:程序存储器也好,数据存储器也好,它们只是存储器,即不能做加减运算,也不能执行,只是用来存放数据的仓库。要做加工只能先把它们拿到工厂去(cpu),加工完了的成品再送回仓库(存储器)。

            很多人已经习惯了c语言中的int a=1;int b=2;int c;c=a+b;

                  导致的错误结论是:      a存放在存储器(内存)中,b,c也存放在存储器中,所以=>a+b也是在存储器中执行完成的。

                程序存储器不能将指令译码成可运行的信号,而内存也不是计算器,它不能对里面的数据做任何的运算,它们只有存储功能。

               真正能在做运算和译码的是cpu或其他协处理器,(数电中的电路组成的加法,乘法器等),看懂一个简单的汇编指令这些就很容易理解(简单的汇编其实比c还容易学)。

好了,一个简单的运行流程如下。

     假设单片机启动:

          cpu要运行指令就得先去拿指令,指令存储在程序寄存器中。

     先从哪拿?

          看pc指针,cpu取指令的地方就是pc所指向的地址(程序存储器地址),因为pc默认启动为0,所以先取地址0x0000中存放的指令。

         

     假设0x0000 中存放的是 int a =1;(这种说法有误,但只做演示)

         

  步骤:   cpu ->取指令->查看pc->pc=0x0000 ->拿到地址0x0000的数据指令->"int a=1";    (可以认为int a =1指令复制到了cpu中)

   接着:  “int a=1”的汇编指令在cpu中被译码->开始在硬件上执行 

------------------------------------------------------------------------------------------------------

从这里开始使用到内存了
     

              

                     光看 int a=1是无法了解怎么使用内存的。

   

得先分析这条指令

                     int:  说明a要存放的是int型的数据,它占4个字节,在内存中得用4个字节的空间来存储它。

                  

               a:  a代表的是变量名,但在硬件层它转化为了一个内存的存储地址,a地址名是以方便我们找到和使用它。

               a地址: 内存中并没有名字叫做a的地址,它只有地址0x0000~0fffff。 电脑中的编译工具 自动给c语言中的a分配了一个地址,可能是任何随机地址,我们先假设是0x00007;

                =1:   这是把a空间(也就是0x0007)赋值为1.

               

              注意了:在程序存储器的0x0000中有数据指令int a=1,也就是说除了对硬件操作的指令外,还有个数据1;这个程序存储区域是被保护的,就是代码区,所以这里的1是常量1。

                          而在内存的0x00007中也存放了一个数据1,但是这个内存数据区域的数据不被保护,可以被修改,所以是变量a=1;                 

                   到这里  整条指令基本执行完毕(但不包括栈的操作,如果扩展开来会涉及到全局,局部很多东西)

----------------------------------------------------------------------

        第一条指令执行完了,接着怎么执行第二条呢?

        很简单:pc自动+1, pc=0x00002;cpu执行步骤和之前一样。如果0x0002存的是跳转指令pc就不是+1了,上篇有例子实际情况实际分析。

----------------------------------------------------------------------       

前面强调过51单片机的程序存储器和内存(数据存储器)严格分开。

     程序存储器与内存的地址都是0x0000~0xfffff,当我们读取0x00007的数据然后送到显示屏幕打印出来时,必须先发送地址信号0x00007,但这个信号是发送到了程序存储器还是内存呢?

      答:事实上如果两个存储器共用一个地址线,它们都会收到cpu发出的0x0007信号。但通过硬件的方式cpu可以屏蔽掉程序存储器(先理解为使其停止工作),那么就只有内存在工作了,所以读取到的数据是内存中0x0007的数据。

      

     上面的做法会影响到程序正常运行吗?毕竟cpu还要从程序存储器中读取指令啊?

       答:不会影响,因为读取指令和读取内存数据并不是同时进行的,首先cpu先读指令时内存被屏蔽了,先让一条指令被复制到cpu中译码,然后屏蔽程序存储器让内存工作起来。

      1 指令传输:  程序存储器->cpu     内存被屏蔽    因为:(指令还在程序存储器中)程序存储器不能被屏蔽

        2 cpu译码指令:  程序存储器被屏蔽不影响运行   因为:(指令已复制到了cpu中)程序存储器可以被屏蔽

        3 执行译码后的指令 : 内存工作,程序屏蔽         因为:(cpu开始读取内存中的数据)程序存储器必须被屏蔽,防止冲突

        4执行完毕,pc+1,回到步骤1

扩展:阅读以上之后,是否注意cpu从程序存储器取指令是找pc指针得到地址信息。那cpu从内存中取数据,地址信息从哪来?

         答:就在我们的指令中提取出来。int a=1的指令中就已经包含了所要存取的内存地址是地址名a

强烈建议学习51单片机,能花时间学嵌入式,为什么不能花个十几天学习下单片机(视频中关于地址线,数据线,控制等都讲的很清楚了)

抱歉!评论已关闭.