1、实验项目:
基于AT89C51单片机的流水灯控制系统设计
2、实验目的:
本系统设计的目的是通过实践操作掌握Proteus硬件仿真软件的使用技巧和Keil uvision程序开发的使用技巧,理解单片机应用系统软硬件开发的过程,掌握基本的/0控制方法。
基本要求:
1)用51单片机控制8只LED灯左右来回循环滚动点亮,产生来回走马灯的效果。
2)在proteus中设计仿真硬件电路,在keil uvision中分别设计出汇编语言和C语言的源程序,然后用proteus来进行整体系统的仿真运行。
提高要求:用51单片机控制16只LED灯按自设花式点亮。
3、实验原理:
在本实验中,我们使用AT89C51单片机的I/O口来控制LED灯的亮灭。使用Proteus软件进行硬件电路仿真,使用Keil uVision编译器来编写源代码,并将其烧录到单片机中。当程序运行时,单片机的P2口循环进行显示信号的输出,控制LED灯的亮灭,让LED灯从左往右进行循环和从右往左进行循环,让二者相互循环进行,在实验的仿真的效果图中,产生走马灯效果。
4、硬件电路图:
实验现象:在实验的结果中,我们可以看到灯的循环效果为从左往右进行循环和从右往左进行循环,二者相互循环进行,产生走马灯效果。
5、C语言代码:
#include<reg51.h> //包含51单片机的头文件,用于定义AT89C51单片机的寄存器和端口
#define uchar unsigned char //定义两个无符号的字符型和整数型常量
#define uint unsigned int //uchar代表unsigned char,uint代表unsigned int
void delay(uint time) //延时函数,循环嵌套time为延迟的时间,循环嵌套循环执行i的值,实现延迟
{
uchar i;
while(time--)
for(i=0;i<200;i++);
}
void main() // 主函数
{
uint i; // 定义无符号整型变量i
uchar temp; // 定义无符号字符型变量temp
while(1) // 死循环
{
temp=0x01; // 初始化temp为0x01,二进制下标为0000 0001
for(i=0;i<8;i++) // 循环8次,每次循环将temp向左移一位
{
P2=temp; // 将temp的值赋给P2口
delay(100); // 延时100ms
temp<<=1; // temp向左移一位,相当于乘以2 }
temp=0x80; // 初始化temp为0x80,二进制下为1000 0000
for(i=0;i<8;i++) // 循环8次,每次循环将temp向右移一位
{
P2=temp; // 将temp的值赋给P2口
delay(100); // 延时100ms
temp>>=1; // temp向右移一位,相当于除以2
}
}
}
6、汇编语言代码:
ORG 0000H ; 程序起始地址
LJMP MAIN ; 无条件跳转到MAIN函数
ORG 0100H ; 指定代码段地址为0100H
MAIN: ; 主函数标签
MOV A,#01H ; 将A寄存器设置为01H,即0000 0001
MOV R0,#07H ; 将R0寄存器设置为07H,即0000 0111
Left:
MOV P2,A ; 将A寄存器的值移动到P2口,P2口用于控制LED灯
LCALL DELAY ; 调用延时函数
RL A ; 循环左移A寄存器的值,等同于将A寄存器的值乘以2
DJNZ R0,Left ; R0寄存器减1,如果R0不为0则跳转到L1标签处继续执行,否则执行下一条指令
MOV R0,#07H ; 将R0寄存器设置为07H,即0000 0111
Right:
MOV P2,A ; 将A寄存器的值移动到P2口,P2口用于控制LED灯
LCALL DELAY ; 调用延时函数
RR A ; 循环右移A寄存器的值,等同于将A寄存器的值除以2
DJNZ R0,Right ; R0寄存器减1,如果R0不为0则跳转到L2标签处继续执行,否则执行下一条指令
LJMP MAIN ; 无条件跳转到MAIN函数
DELAY: ; 延时函数
MOV R1,#200 ; 将R1寄存器设置为200
D1:
MOV R2,#250 ; 将R2寄存器设置为250
D2:
DJNZ R2,D2 ; R2寄存器减1,如果R2不为0则跳转到D2标签处继续执行,否则执行下一条指令
DJNZ R1,D1 ; R1寄存器减1,如果R1不为0则跳转到D1标签处继续执行,否则执行下一条指令
RET ; 返回调用DELAY函数之前的指令
END ; 程序结束