一、实验目标
设计51单片机最小系统电路,使用AT89C52单片机控制发光二极管的点亮。为此我们需要使用proteus完成晶振电路、复位电路以及发光二极管控制电路在内的电路设计,然后加载使用Keil编写的控制二极管点亮的嵌入程序,以验证程序的运行结果。
晶振电路是单片机运行的基础,它提供了单片机工作所需的时钟信号。复位电路则负责在必要时重置单片机的状态,确保其从已知的初始状态开始运行。发光二极管控制电路则是我们实现单片机功能的具体体现,通过控制单片机的I/O口来点亮或熄灭发光二极管。
完成电路设计后,将使用Proteus软件进行电路仿真。在仿真环境中,我们将加载用Keil编写的嵌入式程序,并观察发光二极管的亮灭情况,以验证程序的运行结果是否符合预期。
通过这一实验,我们不仅能够加深对51单片机最小系统电路的理解,还能够提升我们在嵌入式系统开发方面的实践能力。
二、电路设计
1.晶振电路
晶振电路构成时钟脉冲振荡电路,为单片机提供时钟脉冲,下图为AT89C52单片机的外部晶振电路。

上图是应用proteus设计的晶振电路,该电路由单片机AT89C52(U1)、晶振(X1)、电容器件构成。
晶振电路的电容称为匹配电容或负载电容,它们并联到晶振两端,为晶体振荡提供电流回路,若没有这两个电容,晶振的振荡会因为没有电流回路而停振,这两个电容的容量都很小,选择几十皮法即,两个电容的另一端都需要接地。
AT89C52单片机的XTAL1和XTAL2是外接时钟引脚,XTAL1为片内振荡电路的输入端,XTAL2为片内振荡电路的输出端,这两个引脚外接晶振和电容,晶振一般取值为12MHZ,电容一般取值为10P~30P。
晶振为单片机提供稳定的时钟脉冲,确保单片机内部的所有操作都在精确的时序控制下有条不紊地执行。无论是数据处理、指令执行还是I/O操作,都离不开晶振提供的时钟信号的驱动。

上图为晶振提供的时钟脉冲时序图,它有8个时序脉冲,开始是低电平,过一段时间后出现一个上升沿,并跃变到高电平,高电平持续一段时间后,出现下降沿,并跃变到低电平。
时钟周期是晶振工作频率的倒数,这一关系反映了晶振频率与单片机操作速度之间的直接联系。例如,使用12M的晶振意味着其时钟周期为1/12μs,而1MHZ的时钟频率对应着1μs的时钟周期;若频率提升至4MHZ,则时钟周期缩短至250ns。这些数值直接影响了单片机的运行速度和处理能力。
2.复位电路
51单片机的复位电路是为了让单片机在特定的情况下回到初始状态。就好像你玩游戏时,有时候游戏会卡顿或者出错,这时候你可能就需要重新开始游戏,回到游戏的起始点,重新开始。51单片机的复位电路就是这个作用。
复位电路通常包含一个电容和一个电阻,它们一起工作来产生一个电压脉冲。当单片机需要复位时,这个电压脉冲会被送到单片机的复位引脚,告诉单片机:“嘿,你需要回到初始状态,重新开始!”
什么情况下需要复位呢?比如单片机刚上电时,或者程序运行出错时,都可能需要用到复位电路。复位电路确保单片机在这些关键时刻能够重新开始,从而避免了一些可能出现的问题。
AT89C52单片机的RST引脚为复位引脚,该引脚连续输入两个机器周期以上高电平时有效,机器周期是单片机完成一个基本操作所需要的时间,一个机器周期大约为12个时钟周期。下图为AT89C52的复位电路。

复位电路由一个极性电容和一个电阻串联构成,电容的正极接5V电源,负极接1K的电阻,电阻的一端接地,RST引脚接电容的负极。该电路为上电复位,当单片机在通电瞬间,确保复位端为高电位并持续大约2个机器周期。当单片机加电时,复位电路通过电容给RST端加一个高电平,此高电平信号随着对电容的充电而逐渐降低,因此要保持电容充电时间足够长来完成复位操作。
3.发光二极管控制电路
发光二极管控制电路用于控制二极管的发光状态,下图为发光二级管控制电路。

电路图的D1为发光二极管,一端接单片机P1第0位,一端接200欧姆的电阻,电阻的一端接5V电源,该电阻对电路进行限流,因为发光二级管允许流过的电流较小,所以需要串联一个几百欧姆的电阻。
在当前电路下,单片机加电后,发光二级管并不会点亮,因为单片机I/O口(包括P1口)所有位引脚都输出高电平,该电路无电流流通。前面我们使用keil编写了一个嵌入程序,该嵌入程序将P1口第0位改变为低电平,在这种情况下,该电路将有电流通过,发光二级管被点亮。
三、应用proteus绘制电路模型
应用proteus仿真软件绘制电路模型。

四、编写51单片机程序
启动keil开发工具,展开“Project”菜单,选择“New µVision Project ……”命令,在弹出的“Create New Project”对话框内,选择项目保存位置,输入项目名称。
在项目内创建一个main.c文件,代码如下:
#include<reg51.h>
sbit led1 = P1^0;
void main()
{
led1=0;
}
reg51.h是通用80C51和80C31单片机的头文件。头文件有两个keil定义的关键字sbit和sfr,sbit用来定义位变量,sfr用来定义地址变量。
sbit的用法:
sbit X = A^n
其中X是位变量,A是一个可进行位寻址的变量,n表示变量A的第n位,注意这里的^不是C语言的异或操作符,是keil定义的一个特殊符号,用于确定可进行位寻址变量的第几位。例如代码:
sbit led1 = P1^0;
sbit定义了led1变量,该变量指向P1口的第0位,若执行语句led1=0; 则P1口的第0位被置为低电平。
sfr的用法:
sfr X = 0x80
其中X是地址变量,0x80是一个地址。例如代码:
sfr P0 = 0x80;
sfr定义了P0变量,该变量指向0x80地址,该地址为单片机P0口的地址。
51单片机只能运行HEX或BIN文件,HEX是十六进制文件,英文全称为“hexadecimal”,BIN文件是二进制文件,英文全称为binary,这两种文件可以通过软件相互转换。若需要Keil编译后输出HEX文件,需要对Keil输出选项进行配置。在Keil工作窗口,展开【Project】菜单,选择“Options for Targets”命令,在弹出的对话框中,选择“Output”标签页,确定“Create Hex File”被选中。

重新编译C源代码,在项目的输出目录可以看到扩展名为“hex”的HEX文件。
五、装载和运行Keil编写的嵌入式程序
实际上51单片机要正常工作,还需要在Vcc引脚接入电源,在Vss引脚或GND引脚接公共接地端。proteus默认单片机已经接电源和接地,无需再进行导线连接。
C程序编译完成后,回到proteus工作窗口,在电路模型窗口使用鼠标双击单片机,或选中单片机后单击鼠标右键,在弹出的菜单中选择“Edit Properties”命令,proteus弹出Edit Component对话框(见下图),选择使用keil编译的HEX文件,单击【OK】按钮即可装载C程序到单片机。

在电路模型内仿真运行前面装载的单片机程序,运行程序有两种方式:一种方式是展开【Debug】菜单,选择“Start/Restart Debugging”命令来运行程序;一种方式是用鼠标单击调试工具条的启动按钮(见下图)来运行程序。

程序运行后电路模型各端口状态如下图所示。

观察电路模型状态,D1发光二级管已经点亮,蓝色方块表示该端口为低电平,红色方块表示该端口为高电平,灰色方块表示电压不确定。下一节实验课程解释P0口电压不确定的问题。