51单片机的架构与原理(STC89C51)

article/2025/10/11 20:59:27

前言

        学习单片机,不管怎么学都是要走一些弯路的,有的人弯路走得多,有多人弯路走得少,有些人中途就放弃了,也有不少人成功上岸,掌握了各式各样的单片机、处理器。用51单片机来学习是最合适不过的,因为它的结构不复杂,该有的东西也都有,学会了它,再学习其他的单片机就简单多了。很多人会使用单片机来点亮LED、数码管,能使用单片机进行串口通讯,能用单片机进行各种传感器和驱动器,就觉得已经精通了。其实这还远远不够,换个单片机又要学习很久,换个处理器更是两眼一黑,真正学会单片机是要搞清楚单片机的内部构架和原理,这样你就可以一招鲜吃遍天了,因为不管是51构架的单片机、还是Cortex-M系列的单片机、或者手机上使用Cortex-A系列的处理器、以及PC上使用的处理器,基本原理没有太大差异。就像房子,有摩天大厦、也有厂房、有公寓、有仓库、有商品房、有安置房、有别墅、有厕所,他们都是钢筋,水泥构成,有门,有窗,有房间,有大房间,小房间,有精装修,有毛坯装修,基本的东西是一样的,只是使用的差异不同而已。

什么是单片机

单片机的英文全称Single-Chip Microcomputer,也叫单片微电脑,想想电脑的主要构成(CPU、内存、硬盘、主板),那单片机就是把CPU、内存、硬盘、主板集成在一个芯片上,CPU还是CPU、内存就是RAM、硬盘就是ROM(单片机的ROM也叫Flash)、主板就是单片机上各种总线连接。电脑还可以提供一些外部的接口,比如鼠标、键盘、显示器、各种USB接口,单片机也可以提供各种外部接口,就是那些GPIO,有些GPIO有特殊的功能,比如UART、SPI、IIC等。

所以单片机的结构可以是下面这样子。CPU通过总线与ROM、RAM、GPIO进行信息交互。

CPU:是单片机运行的核心部分,负责执行程序指令,数据处理,控制各个外设。                     

解码指令和执行指令:CPU从程序存储器(Flash)中读取指令,对指令进行解码,并执行;     

控制数据流:CPU负责控制数据在内部总线上的流动,以及将数据传递给内部寄存器和外设

管理中断:CPU能够检测到外部中断信号,并根据优先级处理中断请求;                                     

控制时序和时钟:CPU需要根据时钟信号来同步各个部件的操作,来确保系统的正常运行 

处理输入输出操作:CPU可以通过输入输出端口与外部设备进行通信,实现对外设的控制和数据交换。

ROM:51单片机的ROM是用来存储代码和常量数据,包括程序指令、常量、变量的初值、固定的数据表等。在51单片机中ROM是不可写的,只能烧录。单片机上电后,程序代码和常量数据会ROM中被加载到RAM中运行。

RAM:51单片机的RAM是用来存储程序和数据的临时存储器,RAM分内部RAM和外部RAM,内部RAM位于芯片内部,主要用于存储程序运行时所需的变量和数据、堆、栈等,内部RAM一般比较小,128字节、256字节等。外部RAM则需要通过外部接口连接到芯片上,可以扩展单片机的存储空间,外部RAM的大小一般在几K字节到几十K字节之间

GPIO:51单片机的GPIO(通用输入输出口),是最基本的IO口,可以通过编程实现对外部设备的控制和数据的输入输出。常见的应用包括LED灯的控制、蜂鸣器控制、按键检测、数码管显示、LCD显示等。

51单片机的CPU

51单片机的CPU主要由这几部分组成:ALU、特殊功能寄存器、指令寄存器、指令译码器、程序计数器(PC)、时钟电路。

ALU(算术逻辑单元):ALU是处理CPU中所有算术和逻辑运算的核心部件,它包括加法器、逻辑门、移位器等。

特殊功能寄存器:

程序计数器(PC):程序计数器是一个16位的寄存器,用于存储下一条指令的地址。当51单片机执行一条指令时,PC寄存器会根据指令的长度自动+1或者+2,以便指向下一条指令的地址当遇到跳转指令的时候PC寄存器的值会被直接修改为要跳转的地址。

指令寄存器(IR):指令寄存器是专门用来存储当前执行的指令的寄存器,当51单片机执行指令时,指令从程序存储器读取到指令缓冲区,在被传送到指令寄存器中。在指令寄存器中,指令被分解成操作码和操作数,然后被送到指令译码器中进行译码,最终执行相应的操作。

指令译码器(ID):用于将指令寄存器中的指令解码成相应的操作,并控制相应的执行大暖完成指令的执行。在51单片机中,指令译码器通常由微指令控制器和微程序存储器组成,主要工作时将操作码和操作数等信息解码成微指令,并将微指令送到执行单元,从而实现指令的执行。

时钟电路:给CPU提供时钟信号

51单片机的ROM

51单片机的ROM分位3个区域:代码区、数据区、扩展区

代码区:也称为程序区,用于存放代码,是程序的主要部分。代码区的大小由ROM的容量决定,一般有4KB、8KB、16KB;

数据区:用于存放常量

扩展区:用于存放可以被访问的区域

51单片机的RAM

STC89C52系列单片机的RAM分两部分,一部分是内部RAM(256字节),一部分是内部扩展RAM,大小要看手册。

内部的256字节RAM,地址范围是0x00--0xFF,

256字节的RAM又分低128字节内部RAM(0x00--0x7F)和高128字节内部RAM(0x80--0xFF);

这个低128字节的RAM既可以直接寻址,也可间接寻址;

高128字节RAM与特殊功能寄存器的地址范围是一样的,都是0x80--0xFF,看起来是一样的,实际上不一样,因为他们的寻址方式不一样高128字节的RAM只能间接寻址,特殊功能寄存器只能直接寻址,怎么理解,就拿高考来比喻吧,就像河南的高考成绩和北京的高考成绩,同样都是500分,北京的可以上985,河南的只能去上专科,因为他们的录取系统不一样,也就是寻址方式不一样。

低128字节RAM也称通用RAM区,是使用的最频繁的RAM区。

RAM区又可分为:

工作寄存器组区:地址从00H--1FH,工32个字节,分位4组,每组包含8个8位的工作寄存器,编号都是R0--R7,提供4个寄存器组是因为1个寄存器组可能还不够用,可通过程序状态字寄存器PSW中的RS1和RS0组合决定使用那个工作寄存器组

可位寻址区:地址20H--2FH,共16个字节,所谓可位寻址指的是可以一个BIT一个BIT的读写

用户RAM区和堆栈区:地址30--FF,一个8位的堆栈指针(SP),用于指向堆栈区,单片机复位后,堆栈指针SP为07H,指向了工作寄存器组0中的R7,因此用户初始化程序都应对SP设置初值,一般都是在在80H以后得单元,也就是设置在低128字节的RAM区,

51单片机的特殊功能寄存器(SFR)

51单片机的特殊功能寄存器包括以下几个,地址空间分布在0x80--0xFF:

1、P0、P1、P2、P3:端口寄存器,用于控制芯片的输入输出状态;

2、ACC:累加器寄存器,用于存储运算结果、或者数据传输;

3、B:B寄存器,用于存储运算的第二个操作数;

4、PSW:程序状态字寄存器,用于存储程序执行的状态信息,包括标志位、进位等;

5、SP:堆栈指针寄存器,用于存储堆栈的地址;

6、DPL、DPH:数据指针寄存器,用于存储数据的地址;

7、IE、IP中断使能和中断优先级寄存器,用于控制中断的使能和优先级;

8、TMOD、TCON、TH0、TL0、TH1、TL1:定时器/计数器模式寄存器,计数器寄存器,用于定时器和计数器的控制;

9、SCON、SBUF:串口控制寄存器和数据缓冲寄存器,用于串口通信的控制和数据传输;

10、其他系列的单片机也会根据功能扩展对应的寄存器,如ADC、 PCA

常规51单片机特殊功能寄存器的地址分配如下所示

STC89C52RC的特殊功能寄存器和地址分布可以从提供的头文件中查找


sfr  XICON = 0xc0;
sfr  WDT_CONTR = 0xe1;sfr ISP_DATA  = 0xe2;
sfr ISP_ADDRH = 0xe3;
sfr ISP_ADDRL = 0xe4;
sfr ISP_CMD   = 0xe5;
sfr ISP_TRIG  = 0xe6;
sfr ISP_CONTR = 0xe7;sfr P0   = 0x80;
sfr P1   = 0x90;
sfr P2   = 0xA0;
sfr P3   = 0xB0;
sfr P4   = 0xe8; //STC自己扩展了P4端口,标准的51单片机是只有P0,P1, P2, P3端口sfr PSW  = 0xD0;
sfr ACC  = 0xE0;
sfr B    = 0xF0;
sfr SP   = 0x81;
sfr DPL  = 0x82;
sfr DPH  = 0x83;
sfr PCON = 0x87;
sfr TCON = 0x88;
sfr TMOD = 0x89;
sfr TL0  = 0x8A;
sfr TL1  = 0x8B;
sfr TH0  = 0x8C;
sfr TH1  = 0x8D;
sfr IE   = 0xA8;
sfr IP   = 0xB8;
sfr SCON = 0x98;
sfr SBUF = 0x99;/*  STC自己扩展的寄存器 */
sfr AUXR   = 0x8E;
sfr AUXR1  = 0xA2;
sfr SADDR  = 0xA9;
sfr IPH    = 0xB7;
sfr SADEN  = 0xB9;
sfr T2CON  = 0xC8;
sfr T2MOD  = 0xC9;
sfr RCAP2L = 0xCA;
sfr RCAP2H = 0xCB;
sfr TL2    = 0xCC;
sfr TH2    = 0xCD;

51单片机的构架

下面的图是从STC的官方手册中截下来的STC89C51架构,该包含的模块都包含进去了

TMP1、TMP2与ACC的关系

TMP寄存器和ACC寄存器都是累加器寄存器,但是他们的用途不一样。

TMP寄存器是一个临时寄存器,用于存储计算过程中的临时结果,比如计算的中间结果、或者一些运算的临时存储。TMP寄存器不是一个通用的寄存器,所以它不能直接访问。

ACC寄存器是累加器寄存器,就不一样了,它是一个通用的寄存器,可以被程序直接访问,ACC是可以存储加减乘除,移位等运算的结果,也可以用于存储数据和地址。

地址生成器是什么

地址生成器指的是内部存储器地址的生成电路,这个电路由几个寄存器和逻辑门构成。地址生成电路通过以下几个步骤来生成内部存储器的地址:

1、程序计数器(PC)指向下一条要执行的指令的地址;

2、指令寄存器(IR)读取PC指向的指令;

3、根据指令的操作码,去顶指令的长度;

4、PC的值加上指令的长度,得到下一条指令的地址;

对于数据存储器,可以使用数据寄存器(DPTR)来生成地址,这个数据寄存器就是双数据指针。

51单片机如何取指令

51单片机的取指令步骤:

1、将程序计数器(PC)的值送到地址总线,使得程序计数器中存储的地址作为地址总线的地址;

2、将程序计数器中存储的地址送入程序存储器的地址端口,从而选中相应的存储单元;

3、从程序存储器中读取指令,并将指令送入数据总线;

4、将指令从数据总线送到指令寄存器;

5、将程序计数器+1,指向下一条指令;

6、重复上面的过程,直到程序执行结束

51单片机的程序是怎么运行的

51单片机的程序经过编译器编译成单片机可执行的文件,比如hex格式的文件或者bin格式的文件;

使用烧录器将可执行文件烧录(下载)到单片机的Flash中,也就是ROM中;

上电后,51单片机CPU从Flash的地址0开始读取指令;

根据指令对寄存器、内存进行读写操作;

51单片机在main函数之前的操作

其实单片机上电之后并不是直接进行main函数里面的各种操作指令,在进入main函数之前还有一些初始化的操作,包括:

1、清除所有的RAM变量,初始化所有的寄存器,设置所有的IO口为默认状态;

2、使能中断,初始化中断向量表,设置中断优先级;

3、配置系统的时钟;

4、初始化各种外设;

5、初始化堆栈指针;

这些初始化的操作一般是由编译器或者开发环境提供的启动代码完成的。

堆栈指针是什么,有什么用

在特殊功能寄存器中有一个堆栈指针寄存器(SP),它用于指向堆栈顶部的地址。当程序执行中遇到CALL指令、中断时,会将程序计数器(PC)的值压入堆栈中,并将SP寄存器的值-1,指向堆栈的下一个可用地址。返回时,会从堆栈中取出压入的PC值,并将SP寄存器的值+1,指向堆栈的顶部。

堆栈的作用

堆栈,英文stack,一般翻译成栈,因为堆和栈还是有一定区别的,在计算机中,堆和栈都是内存的一部分,栈一般是CPU自己分配,而堆需要程序员自己去申请,自己去释放。

在51单片机中,堆栈(stack)用来保存上下文。当中断发生时,会将当前的程序计数器(PC)、状态寄存器(PSW)、以及其他通用寄存器中的值都保存在堆栈中。当中断服务程序结束之后,又把堆栈中的内容读出来。

使用堆栈保存上下文,需要注意以下几点:

1、确保堆栈的大小足够保存所有的需要保存的寄存器的值;

2、在进入中断前,需要禁止其他中断的发生,以防止在中断服务程序执行的过程中发生其他的中断,从而破坏堆栈中保存的值;

3、在退出中断服务程序后,需要重新开启中断,以便能够响应其他的中断请求;

4、当使用多重嵌套中断时,需要使用多个堆栈来保存不同中断的上下文。

51单片机的中断向量是什么

51单片机的中断向量就是一组地址,这个地址就是单片机中存储程序指令的地址,

程序存储器就是Flash,他的地址从0x0000开始,按照代码量地址也逐渐增加,但是有一些特殊的地址位置,一般的程序指令是不能占用的,这些特殊的位置就是中断向量,一旦中断发生,程序计数器(PC)直接就跳转到对应的中断向量地址,开始执行中断服务。

常规的51单片机有以下几个中断向量

  1. 外部中断0(INT0):中断向量地址为0x0003H
  2. 外部中断1(INT1):中断向量地址为0x0013H
  3. 定时器/计数器0中断(Timer0):中断向量地址为0x000BH
  4. 定时器/计数器1中断(Timer1):中断向量地址为0x001BH
  5. 串口中断(UART):中断向量地址为0x0023H

STC单片机自己扩充了几个其他的中断,用到的时候自己可以去查一下手册。一般中断向量的地址是位于程序存储器的0x0000--0x003F这段地址范围内。
在程序开发过程中,我们可以通过特定的指令将中断服务子程序的入口地址写入中断向量地址中,当发生对应的中断事件时,CPU会根据中断向量中存储的入口地址跳转到对应的中断服务子程序。


http://chatgpt.dhexx.cn/article/Cx1ltfcn.shtml

相关文章

C51单片机利用HC-05蓝牙模块实现手机点灯

蓝牙通信,实现手机端远程(15米)控制单片机,这听起来对于初学者的我来说,是那么不可思议,经过不断地实验,阅读其他大佬的文章,终于实现了。 在有基础的通信原理知识的前提下,知,HC-05…

基于C51单片机的ESP8266Wifi模块(ESP-01s)编程(详细)

1、模块简介 ESP-01S 是由安信可科技开发的 Wi-Fi 模块,该模块核心处理器为ESP8266。ESP8266 拥有完整的且自成体系的 Wi-Fi 网络功能,既能够独立应用,也可以作为从机搭载于其他主机 MCU 运行。当 ESP8266 独立应用时,能够直接从外…

(可远程)开源手机app控制c51单片机,附微信小程序控制

开源手机app控制c51单片机 第一 、先上效果图第二、原理讲解第三、下载程序到c51第四 app inventor 开发第五、微信小程序开发第六 可能遇到的一些小问题 第一 、先上效果图 第二、原理讲解 原理简述:利用发布订阅模式。第一步,新建主题,第二…

java实例内部类

内部类:可以将一个类定义在另一个类或者一个方法的内部。描述一个事物的一个完整结构的描述。内部类包括:实例内部类(普通内部类),静态内部类,局部内部类(定义在方法里,几乎不用&…

Java内部类介绍 - 局部内部类和匿名内部类

文章目录 内部类局部内部类匿名内部类匿名内部类介绍常见的使用形式开发中使用场景 内部类 局部内部类 局部内部类 (鸡肋语法,了解即可) 局部内部类, 在方法、代码块、构造器等执行体中创建一个类, 称为为局部内部类(但是我们一般都不会这样…

夯实Java基础系列8:深入理解Java内部类及其实现原理

本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star、Fork、Watch三连哈,感谢你的支持。 文章首发于我的个人博客: www.how2playlife.c…

初识JAVA内部类

1 内部类概述 如果一个类存在的意义就是为指定的另一个类,可以把这个类放入另一个类的内部。 就是把类定义在类的内部的情况就可以形成内部类的形式。 A类中又定义了B类,B类就是内部类,B类可以当做A类的一个成员看待: 2 特点 1) 内部类可以直接访问外…

java 内部类怎么调用成员变量_JAVA内部类之成员内部类

JAVA有一个特殊的类形式——内部类(这个词有点为难普通话不好的南方朋友)。今天我们就来聊聊内部类的一种:成员内部类。 如何定义成员内部类 那要如何定义成员内部类呢。 既然叫成员内部类,说明和成员变量是有类似的地方。从代码的层次结构上来看他是和成…

Java内部类(匿名内部类)

Java内部类(匿名内部类) 一、内部类二、静态内部类三、成员内部类四、局部内部类(了解即可)五、匿名内部类(重要) 一、内部类 1、概述 内部类就是一个定义在一个类里面的类,里面的类可以理解为…

Java 内部类的四种实现方式

Java 内部类的四种实现方式 前言 今天的话我将为大家介绍Java的四种内部类,他们分别是普通内部类,静态内部类,局部内部类,匿名内部类。 提示:以下是本篇文章正文内容,下面案例可供参考 一、内部类是什么&…

Java内部类

Java内部类 内部类成员内部类局部内部类匿名内部类静态内部类常规面试案例内部类实例化对象重名变量的引用 内部类 是什么? 字面意思,在类的内部编写的类就叫内部类! 为了方便区分、学习、理解我们一般将内部类分为以下几种! 内部…

java内部类赋值_详解 Java 内部类

内部类在 Java 里面算是非常常见的一个功能了,在日常开发中我们肯定多多少少都用过,这里总结一下关于 Java 中内部类的相关知识点和一些使用内部类时需要注意的点。 从种类上说,内部类可以分为四类:普通内部类、静态内部类、匿名内部类、局部内部类。我们来一个个看: 普通…

java new 一个内部类_java内部类

java内部类的几种类型:成员内部类,静态内部类,方法内部类,匿名内部类。 成员内部类:成员内部类是类内部的非静态类。成员内部类不能定义静态方法和变量(final修饰的除外)。这是因为成员内部类是非静态的,类初始化的时候先初始化静态成员,如果允许成员内部类定义静态变量…

java中的内部类

java中的内部类主要分为两类四种: 第一类:定义在外部类局部位置上,分为局部内部类( 有 类名)、匿名内部类(没有类名)。 第二类:定义在外部类的成员位置上,分为成员内部类(没有static修饰)、静态内部类(使用static修饰…

java内部类最全详解

1、成员内部类 内部类与外部类的关系 a.成员内部类的创建需要依赖于外部类对象-(成员方法必须通过对象调用),在没有外部类实例之前无法创建成员内部类对象 b.内部类与外部类相对独立,不是is a 的关系(发动机-汽车&am…

Java内部类详解(含:成员内部类、局部内部类、匿名内部类、静态内部类)

内部类是什么? 字面意思,在类的内部编写的类就叫内部类!即一个类的内部又完整的嵌套了另一个类结构,被嵌套的类称为内部类(inner class),嵌套其他类的类称为外部类(outer class)。 内部类是类的第五大成员→【提示:类的五大成员…

分享15款很棒的 JavaScript 开发工具javascript

在开发中,借助得力的工具可以事半功倍。今天,这篇文章向大家分享最新收集的15款非常有用的 javascript 开发工具。 testswarm: continious & distributed js testing testswarm是mozilla实验室推出的一个开源项目,它旨在为开发者提供在多个浏览器版本上快速轻松测试自己j…

27 个面向开发人员的最佳 Vue.js 开发工具

英文 | https://javascript.plainenglish.io/best-27-vuejs-development-tools-for-developers-bd972bb5f573 01、BootstrapVue 地址:https://bootstrap-vue.org/ 一个用于 Vue.js 构建引导接口的开源库。 02、Vuex 地址:https://vuex.vuejs.org/ Vue.js…

15 款非常有用的 JavaScript 开发工具

开发者有个趁手的工具将事半功倍。今天这篇文章分享给大家最新的15款非常有用的JavaScript 开发工具。 列表如下: TestSwarm: Continious & Distributed JS Testing TestSwarm提供分布式的JavaScript持续集成测试。最初它的创造者John Resig只是将它作为…

03【WebStorm开发工具】

上一篇:02【HTML快速入门】 下一篇:04【】 目录:【HTML5系列教程】 文章目录 三、WebStorm开发工具3.1 WebStorm简介3.2 WebStorm安装3.3 WebStorm基本使用3.3.1 创建项目3.3.2 调整字体大小3.3.3 代码自动补全3.3.4 WebStorm常用快捷键 三…