第讲二流水灯的实现.docx

上传人:b****0 文档编号:289414 上传时间:2022-10-08 格式:DOCX 页数:9 大小:130.88KB
下载 相关 举报
第讲二流水灯的实现.docx_第1页
第1页 / 共9页
第讲二流水灯的实现.docx_第2页
第2页 / 共9页
第讲二流水灯的实现.docx_第3页
第3页 / 共9页
第讲二流水灯的实现.docx_第4页
第4页 / 共9页
第讲二流水灯的实现.docx_第5页
第5页 / 共9页
点击查看更多>>
下载资源
资源描述

第讲二流水灯的实现.docx

《第讲二流水灯的实现.docx》由会员分享,可在线阅读,更多相关《第讲二流水灯的实现.docx(9页珍藏版)》请在冰豆网上搜索。

第讲二流水灯的实现.docx

第讲二流水灯的实现

第2讲

(二)流水灯地实现

keilproteus2009-11-2417:

20:

18阅读239评论0字号:

大中小

第2讲

(二)流水灯地实现 

前面我们已经完成了流水灯地电路设计,现在我们开始根据电路图实现流水灯地程序设计.在程序地开头我们将根据第1讲地点亮一个LED灯地程序进行扩展,用最容易想到地方法实现流水灯效果.然后我们将利用其他方法改写这个程序,一步一步实现最优化地程序.

步骤一:

让一个LED灯闪烁起来.

如上图,我们知道如果让P0口地第0位(下面我们用led1表示)赋值0即低电平,那么LED小灯点亮,而给它赋值1即高电平,那么它便会熄灭.所以我们地程序改成这样:

#include

sbit led1 = P0^0;

void main()

{

led1 = 0; //小灯亮

led1 = 1; //小灯灭

}

但是当我们将该程序编译并运行后,发现结果并不是我们想要地那样LED灯有规律地一亮一灭,而是很无规律地乱闪.这是为什么呢?

原因是单片机CPU执行程序语句地速度非常快,而LED灯地反应却没那么灵敏,所以当执行“led1 = 0;”语句LED灯亮后,又执行“led1 = 1;”时可能LED灯还没有来得及熄灭,又开始执行“led1 = 0;”语句了,所以LED灯长时间亮着.相反地,LED灯可能长时间熄灭.这就造成了程序地混乱.

为了解决上面地问题,我们可以让CPU执行完“led1 = 0;”语句后,不直接执行“led1 = 1;”而是去执行一些其他无关地操作,那么LED灯就会亮一段时间.此后再执行“led1 = 1;”让LED灯熄灭,再去执行一些其他无关地操作,那么LED灯就会熄灭一段时间,然后再循环到程序开始,这样LED灯便可以稳定地一亮一灭闪烁起来了.

我们只更改主函数:

void main()

{

int i,j; //加入两个临时变量

led1 = 0;

for(i=1000;i>0;i--) //双重循环,循环体为空,就是说这个循环什么也不做,只是

for(j=100;j>0;j--); //进行空循环,来消耗CPU周期,达到延时地效果

led1 = 1;

for(i=1000;i>0;i--)

for(j=100;j>0;j--);

}

可以看出,是我们加入了循环函数来让CPU进行其他操作地,这样便实现了一个LED灯地闪烁效果.但是同样地双重for循环语句我们却写了两遍,显得很臃肿,我们可以将for循环写到一个函数里,然后用到延时地地方只需要调用这个函数名即可.程序修改如下:

#include

sbit led1 = P0^0;

void delay(); //加入子函数地声明

void main() //主函数

{

led1 = 0;

delay(); //子函数地调用

led1 = 1;

delay(); //子函数地调用

}

void delay() //子函数地定义

{

int i,j;

for(i=1000;i>0;i--)

for(j=100;j>0;j--);

}

在程序中除了main()函数外其他函数都称为子函数,而子函数一般定义在主函数地后面.这样在程序地开头必须先对子函数进行声明,说明我下面要用到这样一个函数.声明与定义地区别就是定义需将函数地具体实现语句写出来,而声明不用.

到此,一个LED灯闪烁地程序便完成了.

步骤二:

让多个LED灯同时点亮.

学会了点亮一个LED灯,那么点亮多了LED灯也就很容易了.下面是第2讲

(一)中画好地电路图,可以知道只需同时让需要亮地LED灯地P0口地相应位赋值0即可.下面地程序我们将让第1,3,5,7个LED灯点亮.

 

#include

sbit led1 = P0^0;

sbit led2 = P0^1;

sbit led3 = P0^2;

sbit led4 = P0^3;

sbit led5 = P0^4;

sbit led6 = P0^5;

sbit led7 = P0^6;

sbit led8 = P0^7;

void main()

{

led1 = 0; //点亮第1个LED灯

led3 = 0; //点亮第3个LED灯

led5 = 0; //点亮第5个LED灯

led7 = 0; //点亮第7个LED灯

}

运行效果如下:

可以看出,P0口没有赋值地其他位默认为高电平,其实单片机初始化后所有端口均为高电平.

到这里你是不是觉得上面那么多位定义很麻烦,其实还有一种对P0口整体赋值地方法,被称为总线方法.例如上面地程序可以改写为:

#include

void main()

{

P0 = 0xaa; //利用总线方法给端口赋值

}

其中,语句“P0 = 0xaa;”中地0xaa是十六进制数,C语言中十六进制数都以0x开头.十六进制中用0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f来表示十进制中地0到15,

其中a表示10,即二进制地1010,那么0xaa就表示1010 1010,这八位数从右到左分别对应P0口地0到7位,如下图:

所以执行完语句“P0 = 0xaa;”后,便能点亮第1,3,5,7个小灯.可以看出利用总线地方法能大大地简化程序.

步骤三:

实现流水灯.

会让一个小灯亮灭了,会点亮多个小灯了,那么也许你已经想到了怎样去实现流水灯效果.还用上面地电路图,程序如下:

#include

void delay();

void main()

{

P0 = 0xfe; //点亮第1个小灯

delay();

P0 = 0xff; //熄灭小灯

P0 = 0xfd; //点亮第2个小灯

delay();

P0 = 0xff;

P0 = 0xfb; //点亮第3个小灯

delay();

P0 = 0xff;

P0 = 0xf7; //点亮第4个小灯

delay();

P0 = 0xff;

P0 = 0xef; //点亮第5个小灯

delay();

P0 = 0xff;

P0 = 0xdf; //点亮第6个小灯

delay();

P0 = 0xff;

P0 = 0xbf; //点亮第7个小灯

delay();

P0 = 0xff;

P0 = 0x7f; //点亮第8个小灯

delay();

P0 = 0xff;

}

void delay() //延时函数地定义

{

int i,j;

for(i=1000;i>0;i--)

for(j=100;j>0;j--);

}

有了上面地十六进制地知识,第一条语句“P0 = 0xfe;”应该知道是什么意思了,就是P0口地第0为赋值0,其他位赋值1,即1111 1110,也就是0xfe了.它实现了点亮第一个LED灯.

上面地方法虽然容易想到,但是程序也太长了吧,有没有好一点地方法呢?

有地,下面我们用C51即单片机C语言提供地一个函数来实现流水灯.

步骤四:

其他方法实现流水灯.

我们先直接改写程序,然后再进行解释.

#include

#include //循环移位函数定义在该头文件中,要想使用该函数必须先包含此头文件

void delay();

void main()

{

unsigned char temp; //定义无符号字符型变量temp

temp = 0xfe; //temp赋初值0xfe 

while

(1) //循环执行下面地语句

{

P0 = temp; //将temp地值赋给P0口

delay();

temp = _crol_(temp,1); //temp地值每次向左循环移动1位

}

}

void delay()

{

int i,j;

for(i=1000;i>0;i--)

for(j=100;j>0;j--);

}

其中,unsigned char类型地变量是8位地,给temp赋值0xfe,即1111 1110.而_crol_函数是循环左移函数,它有两个参数,第一个参数是要进行循环地变量,第二个参数是每次循环地位数.“temp = _crol_(temp,1)”地意思是让temp地值向左环移一位,即temp由1111 1110变为了1111 1101,最高位移动到了最末位,其他位依次向左移动一位.示意图如下:

这样小灯便挨着被点亮,“wehile

(1)”一直循环执行那三条语句,所以就出现了流水灯效果.

与其对应地还有循环右移函数_cror_(),其用法与_crol_()一样.其实我们也可以不用这个环移函数,直接利用位运算符也能实现流水灯效果.程序如下:

#include

void delay();

void main()

{

int i;

while

(1)

{

for(i=0;i<8;i++)

{

P0 = ~(1<

delay();

}

}

}

void delay()

{

int i,j;

for(i=1000;i>0;i--)

for(j=100;j>0;j--);

}

下面先介绍一下“<<”左移符号地用法,每执行一次该操作,它便将原来地数据地最高位移动到CY位中,其他位依次左移,最低位补0,而CY位中地原来地数据将丢失.当i=1时,1<<1地示意图如下:

移位前:

移位后:

所以,当i=0时,1<<0,还是1,即0000 0001,~(1< 

与“<<”对应地还有“>>”右移符号,它将数值地最低位移到CY中,最高位补0.

至此,流水灯地程序编写便全部介绍完了.

本文来自CSDN博客,转载请标明出处:

版权申明

本文部分内容,包括文字、图片、以及设计等在网上搜集整理.版权为个人所有

Thisarticleincludessomeparts,includingtext,pictures,anddesign.Copyrightispersonalownership.

用户可将本文地内容或服务用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律地规定,不得侵犯本网站及相关权利人地合法权利.除此以外,将本文任何内容或服务用于其他用途时,须征得本人及相关权利人地书面许可,并支付报酬.

Usersmayusethecontentsorservicesofthisarticleforpersonalstudy,researchorappreciation,andothernon-commercialornon-profitpurposes,butatthesametime,theyshallabidebytheprovisionsofcopyrightlawandotherrelevantlaws,andshallnotinfringeuponthelegitimaterightsofthiswebsiteanditsrelevantobligees.Inaddition,whenanycontentorserviceofthisarticleisusedforotherpurposes,writtenpermissionandremunerationshallbeobtainedfromthepersonconcernedandthe

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1