对于51单片机相信很多电子信息或者相关专业的朋友应该都不会感觉陌生,很多专业在大学课程中开设的单片机课程就是使用的51单片机进行授课和学习的。51单片机的内容相较于其他高性能复杂的单片机来说,架构相对简单一些,寄存器也少很多,作为新手入门学习是很有好处的,不用一上来就啃很复杂的东西,有助于培养学习的兴趣和达到快速入门的作用。
以前学校学习常见的单片机:
也许很多朋友都有接触过不少的单片机,甚至从事相关开发工作的朋友使用单片机的频率还是相当的高的。但是如果要问你一个问题:什么是单片机?你能回答的出来吗?这点我估计很多就算是从事了很多年单片机开发工作的朋友也未必能说出一个完整的结论。
在我看来,对于什么是单片机的一种说法:单片机就是在一块集成电路芯片上集合了微处理器单元、存储器、I/O电路接口以及其他的多种外设功能电路模块的微型计算机。它可以进行逻辑运算处理,也可以接收外部信号和发送信号给外部设备,是一种集合运算逻辑功能和输入输出控制的集成电路芯片。
那单片机内部的架构又由什么组成呢?都包括些什么呢?
对于这个问题我打算还是以51单片机进行分析,方便了解。其他复杂的单片机内容就更加多了,对于新手和初学者也不友好,我们主要是先理解基本框架和一些通用性的东西,以后遇到其他的复杂单片机也能快速的理解。
下面是某芯片厂商设计的51单片机的架构框图:
从上图中可以看到,这个51单片机的架构中包含了几大组成部分:
1)程序计数器 —— Program counter
2)堆栈寄存器 —— stack Register
3)指令寄存器 —— Instruction Register
4)指令译码器 —— Instruction decoder
5)算术逻辑单元 —— ALU
6)工作寄存器 —— Work Register
7)状态寄存器 —— Status Register
8)程序存储器 —— Flash Program Memory
9)数据存储器 —— SRAM Data memory
上面提及的几大组成部分的作用如下:
程序计数器在cpu中是非常重要的,它记录着cpu要执行的指令的指针。简单的说就是程序计数器中存放的是下一条将要被执行的指令的地址。
当cpu复位的时候,程序计数器会回到指令最开始的位置(比如地址0的位置),然后会从程序存储器中取指令,将指令存取到指令寄存器中,然后程序存储器会自动加1指向下一条指令,不断地循环往复,从而让cpu井然有序的执行着指令。
注意:一般一条指令的执行都会分为几个阶段:取指、译码、执行。有些指令还会包括数据的读取、缓存等操作。
堆栈寄存器是用于记录程序返回的指令指针的。当程序中调用一个函数的时候,程序计数器会把指令指针推送到堆栈寄存器中(俗称入栈push),然后cpu会根据指令指针所指的指令进行执行。在函数被执行完之后,堆栈寄存器又会将指令指针再送回到程序计数器以继续原来的程序处理流程。
简单的来说,堆栈寄存器中记录着程序被调用的入口地址,在程序调用结束之后将指令指针再交还程序计数器,从而能够让cpu能够继续往下执行下一个指令。
指令寄存器中存放的是当前正在被执行的指令的指针。
当cpu要执行一条指令的时候,会先由程序计数器取出一条指令,再将这条指令的指针放到指令寄存器中,cpu便得到了需要去执行的指令的地址,从而开始指令的执行。
注意:除了指令寄存器之外还有一个指令寄存器IP,这个IP寄存器和指令寄存器可是不同的哦,指令寄存器存放的是被执行指令的地址,而指令寄存器IP存放的是下一个将要去获取的指令的内存地址。两者的关系是:cpu会从指令寄存器IP中获取需要执行的指令放置到指令寄存器中,然后指令寄存器IP自动会加1指向下一条指令。
cpu想要执行一条指令就必须知道这条指令想要干什么,要执行什么样的操作,要完成指令的解析就需要指令译码器。
一条指令是由操作码和地址码组成的,操作码表示指令的操作性质,决定指令执行什么样的操作;地址码是执行操作码时的操作对象的地址。
算术逻辑单元是cpu中的核心部分,它是中央处理的执行单元,是专门执行算术和逻辑运行的数字电路,cpu能进行各种各样的逻辑和运算操作依靠的就是ALU算术逻辑单元。
在cpu中大部分的指令都是由ALU执行的,ALU从寄存器中获取到数据,将经过处理的数据存入到ALU的输出寄存器中,再由其他的部件完成在寄存器与内存中数据交互,多个控制单元协作配合让ALU知道该执行什么的操作,最终达到期望的控制目的。
绝大多数的ALU都可以实现整数算术运算、位逻辑运算、移位操作等,在一些高级的cpu中还会包含很多的浮点运算单元,可以实现浮点数的快速处理运算,如FPU单元、DSP等。
工作寄存器用来缓存数据寄存器的数据和立即数。在cpu中一般都会设置工作寄存器组,运算中产生的结果直接放在寄存器中,而不是放回到内存中,可以极大地提高cpu的执行速度。
因为我们知道,在程序中定义的变量是放在内存中的,也可以把变量定义成寄存器类型的变量,寄存器的访问速度是比内存要快的。
如下,定义一个普通的变量和寄存器变量:
char var_1;
register char var_2;
状态寄存器在单片机中可以说是非常常见的了,它是cpu中非常重要不可或缺的一部分。
状态寄存器一般用于存放各种状态信息,一般包括:
1)暂存当前指令执行结果的状态信息,比如进位信息、位溢出、运算结果标志、奇偶标志等;
2)存放控制信息,常见的比如中断标志位、数据发送完成标志位、数据接收完成标志位等;
程序存储器在单片机中主要用于指令的存储。
我们编写好的代码通过编译器的编译之后,会通过烧录工具烧录到单片机中被执行。而保存这些我们编写好的程序代码就是通过程序存储器,一般而言烧录到程序存储器的代码都是只读的。
为什么我们的代码在烧录到单片机之后,即使断电再重启依然可以执行断电之前的代码逻辑,就是因为代码被保存在了程序存储器中,在下次重新上电启动的时候,cpu还是可以从程序存储器中将指令读回RAM中由指令译码器分析译码并执行。
目前常见的单片机的程序存储器主要有:
1)内部Flash:一般的单片机都会内置flash存储器,代码直接烧录到flash中;
2)外部存储器:有些单片机内有内置的flash,而是采用外部的存储器,比如EPROM、NAND_FLASH、emmc、SD卡等等的
单片机内部中的数据存储器一般指的是随机存储器,成为RAM,主要用于存储程序运行过程中的全局变量以及中间变量。它可以随时读写,访问速度也快,一般作为操作系统或者程序运行过程中的数据临时存储的媒介,而且可以和cpu直接交换数据。
但是RAM是掉电就会丢失的,不能作为数据长久保存的媒介,想要数据能被长久保存就必要写入到掉电能保存的存储器中。
联想一下我们使用的电脑便知,RAM指的是电脑的内存条中的存储空间,ROM指的是机械硬盘、固态硬盘、U盘之类的存储设备。