基于SDCC和Edsim51的代码仿真
一、在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
注意:在仿真运行之前,Edsim51的Update Frequency (刷新频率)要加大到10000或更亮
(2)使LED周期性闪烁
在点亮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,并使其周期性闪烁
(1)点亮一个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;}
}
注意:
- 上面包含头文件
mcs51
目录下的8051.h
,里面定义了各个寄存器的宏定义,比如P1
、TCON
等,不同公司的芯片其寄存器的地址可能不一样,edSim51
仿真的芯片采用的就是mcs51
的8051芯片。- 另一个注意的地方是
main
函数是没有返回值的。- 程序里为了表示
P1
口的各个位( bit )的值,使用了011111110
这样的进制字面 量,这是非标准的sdcc
扩展,为此,需要在编译的时候指定-std-sdccxx
编译选项,这里xx
需要按需要替换为89
、99
、11
、2x
以适应不同标准,下面是一-个参考命令:sdcc --std-sdcc89 led1.c
sdcc --std-sdcc89 led1.c
然后按住windows+R
,输入cmd
,打开windows
命令行窗口。此时目录在C
盘下,输入G:
,切换当前
工作目录到G:
根目录下,接下来输入cd G:\SOFTWARE\SDCC3.0\SDCC\bin
,切换到bin
目录下。
如果编译成功的话,可以在当前目录下生成需要的led1.*
的文件,其中包括ihx
文件。
然后需要用sdcc
配套的工具程序packihx
将ihx
文件转换为hex
文件,操作命令如下:
packihx led1.ihx > led1.hex
成功得到led1.hex
文件后,打开Edsim51仿真器,点击new按键,再点击load按键:
选择生成的led1.hex文件:
将刷新频率改为50000,点击run,得到如下结果:
(2)使LED周期性闪烁
按照上文中点亮一个LED时,使C程序借助SDCC转换为二进制可执行文件(.hex),再进行仿真运行。
源程序文件:
#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);
}
仿真结果如下:
二、在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;}
}
将生成的.hex文件导入到AT89C51芯片中
仿真结果:
(2)Proteus+keil c51的C程序编写
代码如下:
#include<reg51.h>
void main()
{
while(1)
{P1=0xFE;}
}
将生成的.hex文件导入到AT89C51芯片中
仿真结果:
(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
仿真结果: