一、实验目的
1、 熟悉HNIST-2型单片机系统相关硬件电路,程序下载方法;
2、 掌握采用汇编语言与C语言开发单片机系统的程序结构;
3、 掌握51系列单片机通用I/O口的使用。
二、实验前准备
1、 完成作业3;
2、 根据实验内容编写好相关程序,并进行Proteus仿真。
三、实验内容
实验内容为3项,其中第1、2项必做。
1、基本的流水灯。
根据图1电路,编写一段程序,使8个发光二极管D1、D2、D3、D4、D5、D6、D7、D8顺序(正序)点亮:先点亮D1,再点亮D2、D3……D8、D1……,循环点亮。每点亮一个LED,采用软件延时一段时间。
2、简单键控的流水灯。
不按键,按正序点亮流水灯;按下K1不松手,按倒序点亮流水灯,即先点亮D8,再顺序点亮D7、D6……D1、D8……。松手后,又按正序点亮流水灯。
3、键控的流水灯。
上电,不点亮LED,按一下K1键,按正序点亮流水灯。按一下K2键,按倒序点亮流水灯,按一下K3键,全部关闭LED。
四、实验原理图
如图3.1所示。
电路原理图如图3.1,AT89S52的P0.0~P0.7作为输出连接8个发光二极管,输出低电平0时对应发光二极管发光;由于发光二极管的导通电压为1.7V,所以HNIST-2型实验装置在电源与二极管之间加一个阻值为1K限流电阻保护二极管。
AT89S52的P2.0、P2.1作为输入连接2个按键K1、K2,若检测到P2.0=0,则说明K1键按下。
五. 方案设计
概要设计:
A. 硬件设计
用stc89c52rc单片机在HNIST-2开发板上实验,单片机P0.0到P0.7连接8个小灯泡,P2口P2.0到P2.3连接4个开关。
B. 软件设计思想
1、基本的流水灯
软件延时采用例题程序delay( j ),可调整延时时间。流水灯采用while(1)死循环保持,用循环左移函数crol(P0,1)控制流水灯流动。
2、简单键控的流水灯。
根据P2.0口的状态来判断是否按下K1开关,用if和while()来保持流水灯循环工作,if判断是否开关按下,然后点亮 D0或D7一个小灯泡,用while和循环左(右)移保持流水灯持续工作。
3、键控的流水灯
按一下键后马上松手,所以需要设置一个变量a保留按键键值,写一个单独检测开关状态的函数,在每一次延时后检测开关的状态并将状态保留在a中,然后根据a的值来实现不同的功能,功能实现和题2相似。
六、源代码
1、基本的流水灯
#include "reg52.h"
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
void delay(uint i){ //延时函数
uchar t;
while(i--){
for(t=0;t<120;t++) ;
}
}
void main()
{
P0=0xfe; //亮一个小灯泡
while(1)
{
delay(500);
P0=_crol_(P0,1); //循环左移
}
}
2、简单键控的流水灯。
#include "reg52.h"
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit key=P2^0;
void delay(uint i){ //延时函数
uchar t;
while(i--){
for(t=0;t<120;t++) ;
}
}
void main()
{
while(1){
if(key==0){ //按住k1
P0=0xfe;
while(key==0){
delay(500);
P0=_crol_(P0,1);
}
}
if(key==1){ //k1没有按下
P0=0x7f;
while(key==1){
delay(500);
P0=_cror_(P0,1);
}
}
}
}
3、键控的流水灯
#include "reg52.h"
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit key1=P2^0; //k1按键
sbit key2=P2^1;//k2按键
sbit key3=P2^2;//k3按键
uint a=0;//记录按键键值
void delay(uint i){ //延时
uchar t;
while(i--){
for(t=0;t<120;t++) ;
}
}
void key(){ //判断哪一个按键被按并用a记录
if(key1==0) a=1;
if(key2==0) a=2;
if(key3==0) a=3;
}
void main()
{
P0=0xff;
while(1){
key();
if(a==1){
P0=0xfe;
while(a==1){
key();
delay(500);
P0=_crol_(P0,1);
}
}
if(a==2){
P0=0x7f;
while(a==2){
key();
delay(500);
P0=_cror_(P0,1);
}
}
if(a==3){
P0=0xff;
}
}
}
七、实验思考题
1、采用I/O口作为输出口时要考虑哪些因素?为什么实验装置中LED要串联一个电阻?
答:作为输出口,要通过程序控制I/O口引脚的电平。LED是二极管,串联电阻做限流,防止二极管被击穿。
2、采用I/O口作为输入口时要注意什么?键控的流水灯时为什么要在延时程序中检测是否按键?
答:作为输入口,要先将相应端口的电平置1才能准确读取相应的状态。键控的流水灯在延时程序中检测是否按键是为了防止在延时过程中有键按下而导致未能检测到,
3、为什么延时程序要做一个函数?
答:延时函数使用频繁,做成一个函数方便调用。
八、实验总结心得体会收获
通过这一次的实验,确实接触到了许多新知识,首先就是单片机的工作原理和烧录过程以及仿真软件的使用,这是在这个实验中能够熟练掌握的,这个跑马灯的实验就是一个基础的单片机实验,实验的过程中要解决流水灯的问题,以及按键和流水灯之间的配合,是将硬件和软件结合的一次实验,为了让按键按下后流水灯依旧能持续循环的工作,我进行了多次调试,进一步理解了开关检测和流水灯的循环移动,还有就是在项目三中,如何按一次键就实现一个功能的问题,让我知道了将键值保存的方法,实验很成功,收益匪浅。