一、实验一
1、要求
安装SDCC和Edsim51,采用汇编语言与C语言两种方式,在Edsim51虚拟开发板上点亮一个Led灯,并思考尝试让Led灯周期性闪烁。
2、操作
(1)安装SDCC和Edsim51
链接:https://pan.baidu.com/s/1ebS3vYLCohNkVfDhwChzGA
提取码:0708
(取自他人博客)
(2)打开Edsim51
在上学期的学习中,我们已经安装好了Java环境,因此通过以下操作便能打开Edsim51软件
①Win+R打开运行窗口后,输入cmd打开控制台
②用cd命令切换当前工作目录到D:\根目录下。通过cd打开下载好的edsim51di文件夹,输入以下指令:
java -jar edsim51di.jar
具体完整操作如下图所示:
③打开之后我们不可以关闭控制台,因为控制台关闭,EdSim51也会关闭,所以将控制台最小化即可.
(3)点亮一个LED灯
C语言
下载完成SDCC和EdSim51之后,在SDCC的bin文件夹中新创文本文件复制以下代码到文本中,并将文本文件改名为led.c便于查找。
然后在键盘上按win+R键打开运行窗口,在运行窗口中输入cmd打开控制台,用cd命令切换当前工作目录到D:\根目录下。
#include<mcs51/8051.h>
void main()
{
while(1)
{
P1=0b11111110;
}
}
然后采取以下命令编译:
sdcc --std-sdcc89 led.c
注意:
- 上面包含头文件 mcs51目录下的 8051.h,里面定义了各个寄存器的宏定义,比如 P1、 TCON 等,不同公司的芯片其寄存器的地址可能不一样, edSim51仿真的芯片采用的就是 mcs51的8051芯 片。
- main 函数是没有返回值的。
- 程序里为了表示P1口的各个位( bit )的值,使用了 0b11111110 这样的二进制字面量,这是非标准的sdcc扩展,为此,需要在编译的时候指定--std-sdccxx编译选项,这里xx需要按需要替换为 89 、99 、11 、2x 以适应不同标准,下面是一个参考命令:sdcc --std-sdcc89led.c如果编译成功的话,可以在当期目录下生成需要 led.* 的文件,其中包括ihx文件: led.ihx ,然后需要用sdcc配套的工具程序 packihx 把ihx文件转换为 hex 文件,操作命令如下:
packihx led.ihx > led.hex
通过以上操作便得到了原先我们编辑的C语言的执行文件led.hex。控制台全程操作如下图:
得到的hex文件便被存在D:\SDCC\bin中。
返回到上一步打开的Edsim51中选择load按钮并加载放在SDCC中bin文件夹中的led.hex执行文件进行仿真run。
汇编语言
在Edsim51中点击new按钮输入以下汇编代码(同种代码的不同形式):
MOV 90H, #0xFE
或者
MOV 0x90, #0xFE
或者
MOV 0x90,c#254
点击Save按钮,再点击Run,观察现象:
(4)LED灯闪烁
C语言
同理在SDCC的bin文件夹中创建一个文本文档复制以下代码,并命名为led1.c,随后采取同样的操作得到led1.hex执行文件。
#include<mcs51/8051.h>
void delay(int i)
{
while (i--);
}
void main()
{
while (1) {
P1 = 0b11111110;
delay(50000);
P1 = 0b11111111;
delay(50000);
}
}
完整操作规程如下图:
同样在Edsim51中点击load并加载led1.c执行文件,随后点击run进行仿真运行观察结果
亮:
灭:
汇编语言
在Edsim51中点击new按钮输入以下汇编代码:
ORG 10 ;起始地址
START:SETB P1.0 ;端口置1
LCALL DELAY ;调用延时函数
CLR P1.0 ;端口置0
LCALL DELAY ;调用函数
AJMP START ;跳转到START
DELAY: MOV R7,#250 ;延时函数
D1: MOV R6,#250
D2: DJNZ R6,D2
DJNZ R7,D1
RET ;
END ;
点击Save按钮,再点击Run,观察现象得到与C语言相同的实验效果。
实验二
1、要求
参考8051指令集大全手册,在Edsim51,把汇编语言点亮Led1灯的代码,手工翻译转换为机器指令,与Edsim51 编译生成的机器码指令进行对比,查看是否一致。
2、实践
汇编代码点亮led的代码如下:
MOV 90H, #0xFE
通过对原先汇编代码的解读可知P1口的地址为0x90H即代码中的90H,代码意思为将立即数0xFE(1111 1110的二进制表示)移动到地址为0x90H(P1)的内存位置中。通过参考8051指令集大全手册可以得到MOV语句的意思如下图:
因此通过手动翻译得到的机器码指令为:74H 90H FEH(0x74 0x90 0xFE)
而通过Edsim编译得到的机器码为:
除了MOV所对应的机器码其余与手动翻译得到的均相同。
实验三
1、要求
在Proteus中画出一个与Edsim51虚拟电路原理基本相同的电路,用Proteus仿真完成Led灯的点亮和闪烁,须分别采用以下方式:
(1)采用Proteus+SDCC 的C程序编程。
(2)采用Proteus+Keil C51 的C程序编程。
(3)采用Proteus 内置汇编语言编译的方式。
2、操作
(1)采用Proteus+SDCC 的C程序编程
LED点亮:
#include<mcs51/8051.h>
void main()
{
while (1)
{
P2 = 0b11111110;
}
}
实验效果:
LED被点亮
LED闪烁:
#include<mcs51/8051.h>
void delay(int i)
{
while (i--);
}
void main()
{
while (1)
{
P1 = 0b11111110;
delay(50000);
P1 = 0b11111111;
delay(50000);
}
}
实验效果:
亮:
灭 :
(2)采用Proteus+Keil C51 的C程序编程
LED点亮:
#include <REGX51.H>
void main()
{
while(1)
{
P2=0xFE;
}
}
实验效果:
LED闪烁:
#include <REGX51.H>
#include <INTRINS.H>
void Delay500ms() //@12.000MHz
{
unsigned char i, j, k;
_nop_();
i = 4;
j = 205;
k = 187;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main()
{
while(1)
{
P2=0xFE;//1111 1110
Delay500ms();
P2=0xFF;//1111 1111
Delay500ms();
}
}
实验效果:
亮:
灭:
(3)采用Proteus 内置汇编语言编译的方式
LED点亮:
ORG 0000H
MOV P2,#0FEH
在Proteus的代码界面输入以上代码,如图所示:
实验效果:
LED闪烁:
ORG 0000H ;起始地址
CLR P2.0 ;端口置0
LCALL DELAY ;调用延时函数
SETB P2.0 ;端口置1
LCALL DELAY ;调用函数
AJMP START ;跳转到START
DELAY: MOV R7,#250 ;
D1: MOV R6,#250
D2: DJNZ R6,D2
DJNZ R7,D1
RET ;
在Proteus的代码界面输入以上代码,如图所示:
实验效果:
亮:
灭:
四、总结
通过本次实验进一步掌握汇编代码以及如何将汇编代码手动转化为机器码指令,同时学会实验Edsim51仿真工具以及使用SDCC编译文件。