找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 74033|回复: 5
打印 上一主题 下一主题
收起左侧

单片机LED流水灯实验及流程图源代码详解

  [复制链接]
跳转到指定楼层
楼主
利用实验室提供的单片机实验开发板的最小系统电路模块、流水灯电路模块,以及Protues仿真软件搭建电路,实现I/O口循环流水灯演示效果。
LED流水灯控制电路如图2-1所示,八个LED灯D0-D7(可选择LED-RED)阳极接到+5V,阴极通过300欧姆电阻分别接到单片机的P1.0-P1.7八个IO口上。I/O口循环流水灯效果实现流程如图2-2所示,依次从第一盏灯开始,分别点亮每一盏灯,中间调用延时子函数便可使得流水灯的效果清晰可见。点亮LED灯的具体实现方法与上节相同,只需让相应的IO口输出低电平即可,程序实现代码已给出。按照上节给出的项目开发流程,从仿真电路搭建到程序编写,再到仿真调试以及最后的实物调试完成循环流水灯的实现。
电路硬件连接图

图2-1 流水灯控制电路图

程序流程图


图2-2 程序流程图
实验程序
#include "reg52.h"
void Delay(void)                                                        //延时子函数
{
              int i,j;
              for(i=0;i<1000;i++)
              for(j=0;j<100;j++)
              ;
}                                                                                                
void main(void)
{
              while(1)
              {
                            P1 = 0xfe;                                          //点亮第一盏灯
                            Delay();                                                        //延时
                            P1 = 0xfd;                                          //点亮第二盏灯
                            Delay();                                                        //延时
                            P1 = 0xfb;
                            Delay();
                            P1 = 0xf7;
                            Delay();
                            P1 = 0xef;
                            Delay();
                            P1 = 0xdf;
                            Delay();
                            P1 = 0xbf;
                            Delay();
                            P1 = 0x7f;
                            Delay();
              }
}
四、实验内容及步骤:
1、采用移位的方式实现循环流水灯功能。
将上述LED流水灯的程序更改如下,重新编译程序生成.hex文件,仿真运行通过后,上传至单片机系统进行观察。
#include "reg52.h"
char temp = 0x01;                                                        //定义一个字符变量
void Delay(void)
{
              int i,j;
              for(i=0;i<1000;i++)
              for(j=0;j<100;j++)
              ;
}                                                                                                  //延时子函数
void main(void)
{
              while(1)
              {
                            P1 = ~temp;                                          //变量temp的值按位取反后赋给P1
                            temp = temp << 1;                            //变量temp左移1位
                            if(temp == 0)                                          //判断变量temp的值是否为“0”
                            temp = 0x01;                                          //若temp的值为“0”,将其赋值为“0x01”
                            Delay();                                                        //调用延时函数
              }
}
【说明】观察主函数死循环while(1)中的语句,其中temp初始值为0x01,对应二进制位00000001,“~”表示对temp进行按位取反,取反后结果为11111110,再将该结果赋给P1后,此时P1的值为11111110,即点亮P1.0口对应的LED灯。第二行代码表示将temp的值也就是00000001左移1位,最右边(也就是最低位)补“0”,左移后结果为00000010,并将其赋给temp,此时temp的值为00000010。第三行判断temp是否为“0”,可以看出,此时temp并不等于“0”,不执行if后的赋值语句,直接执行Delay函数。延时一段时间后,又回到死循环中的第一条语句,将temp按位取反后,结果为11111101,赋值给P1,此时点亮P1.1口对应的LED灯。程序一直循环该流程,当temp=10000000时,再执行第二行语句,左移后,temp=00000000,此时条件“temp == 0”成立,将执行if后的赋值语句,将temp重新赋值为0x01,程序继续循环执行,实现流水灯功能。
2、采用循环移位指令实现循环流水灯功能。
将上述LED流水灯的程序更改如下,重新编译程序生成.hex文件,仿真运行通过后,上传至单片机系统进行观察。
#include "reg52.h"
#include "intrins.h"                                                                      //包含本征库函数
char temp = 0x01;                                                                      //定义一个字符变量
void Delay(void)                                                                        //延时子函数
{
              int i,j;
              for(i=0;i<1000;i++)
              for(j=0;j<100;j++)
              ;
}                                                                                                
void main(void)
{
              while(1)
              {
                            P1 = ~temp;                                                                      //变量temp的值按位取反后赋给P1
                            temp = _crol_(temp,1);                                          //变量temp左移1位
                            Delay();                                                                                    //调用延时函数
              }
}
【提高】根据上述流水灯循环方式(D0-D7循环)的程序,尝试编写程序实现双向循环流水灯(D0-D7-D0-D7……)。
编程实现D0-D7的变速循环流水灯功能。
将上述LED流水灯的程序更改如下,重新编译程序生成.hex文件,仿真运行通过后,上传至单片机系统进行观察。
#include "reg52.h"
#include "intrins.h"
char temp = 0x01;                                                                      //定义一个字符变量
int time = 1000;                                                                      //定义一个整形变量
void Delay(int T)                                                                      //延时子函数,延时时间与T值成比例
{
              int i,j;
              for(i=0;i<T;i++)
              for(j=0;j<100;j++)
              ;
}                                                                                                
void main(void)
{
              while(1)
              {
                            P1 = ~temp;                                                        //变量temp的值按位取反后赋给P1
                            temp = _crol_(temp,1);                            //变量temp左移1位
                            if(temp == 0x01)                                          //判断变量temp的值是否为“0x01”
                            {
                                          time = time - 200;                            //延时时间递减200
                                          if(time < 100)                                          //判断延时时间是否小于100
                                          time = 1000;                                          //若延时时间小于100,将其重新赋值为1000
                            }            
                            Delay(time);                                                        //调用延时函数                           
              }
}
【说明】本程序中有两个不同,首先延时子函数Delay(int T)可通过对T进行赋值(传入参数值)来改变延时的时间;其次while(1)死循环中在判断temp值是否为“0x01”中增加了三个语句,其作用是每循环一次流水灯,延时的时间递减200(若延时时间低于100,将其赋值为1000),实现了变速流水灯的功能。
编程实现用按键切换双样式流水灯显示:按一下按键,流水灯以样式1循环;再按一下按键,流水灯以样式2循环,如此反复。
实验程序如下,编译程序生成.hex文件,仿真运行通过后,上传至单片机系统进行观察。
#include "reg52.h"
#include "intrins.h"
char temp = 0x01;                                                                      //定义字符变量
int Yangshi;                                                                                    //定义整形变量
sbit KEY = P2^0;                                                                      //定义按键位变量
void Delay(void)                                                                      //定义延时子函数
{
              int i,j;
              for(i=0;i<1000;i++)
              for(j=0;j<100;j++)
              if(KEY == 0)                                                                      //判断按键是否按下
              {
                            Yangshi++;                                                        //若按下,Yangshi值加1
                            while(!KEY);                                                        //等待按键松开
              }
}
void Yangshi1(void)                                                        //定义Yangshi1子函数
{
              P1 = ~temp;                                                                      //变量temp的值按位取反后赋给P1
              temp = _crol_(temp,1);                                          //temp值左移1位
              Delay();                                                                                    //调用延时子函数
}
void Yangshi2(void)                                                        //定义Yangshi2子函数
{
              P1 = ~temp;                                                                      //变量temp的值按位取反后赋给P1
              temp = _cror_(temp,1);                                          //temp值左移1位
              Delay();                                                                                    //调用延时子函数
}                                                                                   
void main(void)
{
              while(1)
              {
                            switch(Yangshi%2)                                          //Yangshi的值对2求余
                            {
                                          case 0:                                                         //若值为0
                                                                      Yangshi1();               //调用Yangshi1子函数
                                                                      break;
                                          case 1:                                                         //若值为1
                                                                      Yangshi2();               //调用Yangshi2子函数
                                                                      break;                                         
                            }            
              }
}

完整的Word格式文档51黑下载地址:
LED流水灯实验.docx (51.68 KB, 下载次数: 81)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏5 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:496061 发表于 2019-8-12 13:42 | 只看该作者
谢谢分享
回复

使用道具 举报

板凳
ID:552117 发表于 2019-9-8 10:16 来自手机 | 只看该作者
感谢大佬
回复

使用道具 举报

地板
ID:738667 发表于 2020-4-26 17:01 | 只看该作者
大佬求这个程序的原理图。谢谢
回复

使用道具 举报

5#
ID:762275 发表于 2020-5-27 10:40 | 只看该作者
感谢分享
回复

使用道具 举报

6#
ID:748788 发表于 2020-5-28 09:48 | 只看该作者
写的不错,由浅入深,展现了编程的魅力与乐趣,尤其适合初学者
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表