一、在Edsim51虚拟开发板上点亮一个LED并使其周期性闪烁
1.Edsim开发板原理图
2、用汇编语言点亮LED,并使其周期性闪烁
(1)点亮一个LED
由原理图可知,LED0接在P1.0的端口上,而51单片机中P1.0的地址为90H。要使LED点亮,需要使P1.0输出低电平,即可。汇编命令如下:
MOV 90H,#0xFE
或
MOV 0x90,#0xFE
或
MOV 0x90,#254
(2)在点亮LED的基础上,为了使LED周期性闪烁,我们可以采用将P1.0端口置0或置1的操作来控制其亮灭。在亮灭的基础上加上延时函数即可实现周期性闪烁的效果。汇编命令如下
LOOP:SETB 90H ;LED0置1
LCALL DELAY ;调用延时函数
CLR 90H; LED0置0
LCALL DELAY
AJMP LOOP ;跳转到LOOP
DELAY:MOV R7,#250 ;延时函数
D1: MOV R6,#250
D2: DJNZ R6,D2
DJNZ R7,D1
RET ;返回函数
END
3、用C语言点亮LED,并使其周期性闪烁
Edsim51自身只能编译汇编语言,C语言程序需要借助其他C编译器(比如SDCC for 805 1或Keil for 8051)转换为汇编和二进制执行程序(.hex) 才能仿真运行。
以SDCC for 8051 v3为例,请下载,再将其尽量安装到除系统盘C之外的分区目录,比如D:\SDCC3.0 (如果之前安装过其他版本的SDCC, 先卸载)。安装最后-步注意把SDCC安装目录添加到path路径变量中,这样才可以在任意位置运行SDCC编译命令。安装好后,编译链工具程序均在D:\SDCC3.0\bin目录下。
首先到D:\SDCC\bin目录下先新建一个文本文档led1.text, copy 下列C代码文件在此目录下,然后
将文件名改为led1.c。
#include <mcs51/8051. h>
void main()
{
while(1)
{P1=0b11111110;}
}
然后采用下列命令编译
sdcc --std-sdcc89 led1.c
注意:上面包含头文件 mcs51 目录下的 8051.h ,里面定义了各个寄存器的宏定义,比如 P1 、 TCON
等,不同公司的芯片其寄存器的地址可能不一样, edSim51 仿真的芯片采用的就是 mcs51 的8051芯
片。
另一个注意的地方是 main 函数是没有返回值的。
第三个注意的地方是程序里为了表示 P1 口的各个位( bit )的值,使用了 0b11111110 这样的二进制字面
量,这是非标准的 sdcc 扩展,为此,需要在编译的时候指定 --std-sdccxx 编译选项,这里 xx 需要按需
要替换为 89 、 99 、 11 、 2x 以适应不同标准,下面是一个参考命令:sdcc --std-sdcc89 led1.c
如果编译成功的话,可以在当期目录下生成需要 led1.* 的文件,其中包括 ihx 文件: led1.ihx ,然后
需要用 sdcc 配套的工具程序 packihx 把ihx文件转换为 hex 文件,操作命令如下:
packihx led1.ihx > led1.hex
成功的话可以得到 led1.hex 执行程序,然后我们就可以用 edSim51 仿真器中的 load 按钮加载 hex 进
行仿真 run。
二、在Edsim51,把汇编语言点亮Led1灯的代码,手工翻译转换为机器指令,与Edsim51 编译生成的机器码指令进行对比
汇编语言:
MOV 90H,#0xFE
机器语言:
(1)手工翻译
MOV对应机器码为75
90H对应机器码为90
#0xFE对应机器码为FE
(2) Edsim51 编译生成的机器码指令
MOV对应机器码为75
90H对应机器码为90
#0xFE对应机器码为FE
三、在Proteus中画出一个与Edsim虚拟电路原理基本相同的电路,用Proteus仿真完成LED的点亮和闪烁
1.点亮LED
(1)Proteus+SDCC的C程序编写
代码
#include <mcs51/8051. h>
void main()
{
while(1)
{P1=0b11111110;}
}
仿真结果:
2)Proteus+keil c51的C程序编写
代码
#include<reg51.h>
void main()
{
while(1)
{P1=0xFE;}
}
仿真结果:
(3)Proteus内置汇编语言编译
右键点击AT89C51芯片,选择“编辑源代码”进行程序编写
在start:后面编辑代码,编写完成后点击三角形仿真运行
代码如下:
ORG 0000H
MOV 90H,#0FEH
仿真结果:
2、LED周期性闪烁
(1)Proteus+SDCC的C程序编写
代码如下:
#include <mcs51/8051.h>
void Delay(unsigned int t);
void main (void)
{
while (1)
{ P1=0x11111110;
De1ay(100) ;
P1=0x11111111;
De1ay(100);
}
}
void Delay(unsigned int t)
{ while(--t);}
(2)Proteus+keil c51的C程序编写
#include<reg51.h>
sbit LED0=P1^0;
void Delay(unsigned int t);
void main (void)
{
while (1)
{ LED0=0;
De1ay(10000);
LED0=1;
De1ay(10000) ;
}
}
void Delay(unsigned int t)
{ while(--t);}
(3)Proteus内置汇编语言编译
ORG 0000H
SETB 90H ; led0置1
LCALLDELAY;调用延时函数
CLR 90H ; 1ed0置0
LCALL DEL AY
AJMP Start ; 跳转到Start
DELAY: MOV R7, #250 ;延时函数
D1 :MOV R6, #250
D2:DJNZ R6, D2
DJNZ R7 ,D1
RET ;返回主函数
END
仿真结果如下: