【单片机】06流水灯

这篇具有很好参考价值的文章主要介绍了【单片机】06流水灯。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

上次课布置的流水灯实验,硬件上我们用8根导线分别将P1口的第0脚接到第0个灯,第1脚接到第1个灯,以此类推,直到将第7脚接到第7个灯上。软件上相信大家能想到的最简单的办法是先将第0个灯点亮,延时,再将1个灯点亮,再延时,依次类推直到将第7个灯点亮,延时,再将上面的步骤无限的循环执行,代码如下:

#include <reg51.h>
void main()
{
	unsigned int i;
	while(1)
	{
		P1=0xFE;             
		//11111110B 第0个灯亮,其他的灯灭
		for(i=0;i<=10000;i++);  //延时
		P1=0xFD;             
		//11111101B 第1个灯亮,其他的灯灭
		for(i=0;i<=10000;i++);  //延时
		P1=0xFB;             
		//11111011B 第2个灯亮,其他的灯灭
		for(i=0;i<=10000;i++);  //延时
		P1=0xF7;             
		//11110111B 第3个灯亮,其他的灯灭
		for(i=0;i<=10000;i++);  //延时
		P1=0xEF;             
		//11101111B 第4个灯亮,其他的灯灭
		for(i=0;i<=10000;i++);  //延时
		P1=0xDF;             
		//11011111B 第5个灯亮,其他的灯灭
		for(i=0;i<=10000;i++);  //延时
		P1=0xBF;             
		//10111111B 第6个灯亮,其他的灯灭
		for(i=0;i<=10000;i++);  //延时
		P1=0x7E;             
		//01111111B 第7个灯亮,其他的灯灭
		for(i=0;i<=10000;i++);  //延时
	}
}

将上面的程序我们编译下载到单片机中运行,我们看到了LED灯依次点亮的流水灯效果。我们来分析一下上面的程序的还能不能优化。

我们发现点亮每个灯的语句都差不多,都是给P1赋值,然后延时,我们能不能用循环来做呢?能否用循环来做,取决于点亮每个灯的语句中不同部分是否有规律,若有规律我们就能用循环来写。我们发现从第0个灯到第7个灯点亮赋的值不同,这些值程序中使用的是16进制形式,看不出规律,但我们分析这些值的二进制(见上面程序的注释部分),发现每次赋的值是将上次赋的值循环左移了一下,初始值为0xFE,那我们有没有循环左移操作符呢?汇编语言中有循环左移指令,这里我们不做介绍,那C51中有循环移位运算符吗?答案是否定的。我们直接能想到的是C语言中有“<<”(左移)和“>>”(右移)运算符。下面我们详细复习一下这个运算符的使用。
1、“<<”(左移)
“<<”表达式的形式是:操作数<<n,意思是将操作数按二进制的形式,每位向左移n位,最右边空出来的n位统一全补0。例如0xFE<<1结果是多少呢?我们先把0xFE写成二进制形式111111110B,左移一位后得到11111100B,最后的结果是0xFA。
2、“>>”(右移)
“>>”表达式的形式是:操作数<<n,意思是将操作数按二进制的形式,每位向右移n>>位,这里要注意最左边空出来的n位,若操作数是无符号数则补0,若操作数是有符号数则>>补符号位。例如:
unsignedchar x=0xFE;
x=x>>1;
上面的语句x定义的是无符号字符型,x的初始值写成二进制是111111110B,x>>1后x的值为01111111B,空出的最高位补的是0。但若是下面的语句结果就不一样了。
char x=0xFE;
x=x>>1;
上面的语句x定义的是有符号字符型,x的初始值写成二进制是111111110B,注意了符号位是1,x>>1后x的值为11111111B,空出的最高位补的是符号位1。再看下面的语句。
char x=0x7E;
x=x>>1;
上面的语句x定义的是有符号字符型,x的初始值写成二进制是011111110B,注意了符号位是0,x>>1后x的值为00111111B,空出的最高位补的是符号位0。

综上分析,C51没有直接的循环移位运算符,但在intrins.h头文件中已经定义了这些功能的函数,可以直接调用,移位函数有:
(1)unsigned char cror (unsigned char, unsignedchar);无符号字符型变量循环右移位
函数。
(2)unsigned int iror (unsigned int, unsigned char);无符号整型变量循环右移位函
数。
(3)unsigned long lror (unsigned long, unsigned char);无符号长整型变量循环右移位
函数
(4)unsigned char crol (unsigned char, unsigned char);无符号字符型变量循环左移位
函数。
(5)unsigned int irol (unsigned int, unsigned char);无符号字符型变量循环左移位
函数。
(6)unsigned long lrol (unsigned long, unsigned char);无符号字符型变量循环左移位
函数。
以上6个函数第一形参是循环移位的数据,第二形参是循环移位的次数,例如要将P0寄存器循环左移一位,函数的调用形式为:
P0=_crol_ (P0, 1);
所以上面的流水灯代码可以改写为循环结构:

#include <reg51.h>
#include <intrins.h>
void main()
{
	unsigned int i;
	P1=0xFE;
	while(1)
	{
		for(i=0;i<=10000;i++);  //延时
		P1=_crol_(P1, 1);//循环左移1位
	}
}

大家思考一下,如果没有这样的库函数,我们怎么自己写出循环左移1的功能代码呢?
我们分析发现,循环左移1位就是左移一位后,最右边空出来位补最左边移出去的那个位,我们可以先让操作数的值“左移”一位,最右边的位补的0,得到一个值1,再将操作数里的值右移7位,也就是,将被左移出去的最高位移到最低位上,得到值2,再将值1和值2或一下,就能实现循环左移功能了。例如,将P0循环左移一位我们可以写成如下代码:
P0=(P0<<1) | ( P0>>7);
上面的流水灯还可以用下面的代码实现:

#include <reg51.h>
#include <intrins.h>
void main()
{
	unsigned int i;
	P1=0xFE;
	while(1)
	{
		for(i=0;i<=10000;i++);  //延时
		P1=(P1<<1) | ( P1>>7);//循环左移1位
	}
}

1111 1110
1111 1100 | 0000 0001 = 1111 1101
1111 1010 | 0000 0001 = 1111 1011
… = 0111 1111
1111 1110 | 0000 0000 = 1111 1110
1111 1100 | 0000 0001 = 1111 1101
1111 1010 | 0000 0001 = 1111 1011
文章来源地址https://www.toymoban.com/news/detail-718122.html

到了这里,关于【单片机】06流水灯的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 51单片机实现流水灯

    我们之前说过可以控制管脚口电平来控制LED的亮灭,低电平灯亮,高电平灯灭,具体可以看我之前的博客。 P20~P27可以用八位二进制数来表示每一位的电平,第八位是P20,第一位是P27,那么11111110就代表P20亮,其他灭,11101111就代表P24亮,其他灭。流水灯的代码就可以写成这样

    2024年02月11日
    浏览(47)
  • 51单片机入门流水灯

    上次已经实现了LED的点亮了,这篇文章将带大家实现流水灯。 要想实现流水灯首先就得知道什么是延时函数,延时函数的作用就是等待。比如延时一毫秒就是让程序在这里等待一毫秒。延时函数的本质就是执行一些空指令,因为执行指令需要耗费时间,所以执行一定数量的空

    2024年02月04日
    浏览(44)
  • 【51单片机】键控流水灯

    设置k3作为启动键,只有先按下k3才能开始控制流水灯,按下k3后LED闪烁提示开始成功。 在按下k3后,其余键即可控制流水灯。其中k1执行从右到左,k2执行从左到右。 按下k4,执行外部中断,立马中止流水灯运行,需重新按下启动键重启。

    2024年02月06日
    浏览(40)
  • 51单片机按键控制流水灯

    1独立按键的原理图 按键所对应的引脚为P3的0、1、2、3引脚口,并且这里总共有四个独立按键,它们公共的一段都接到了 GND 电源的负极。这样我们就知道按键上电的默认电平为高电平。所以我们只需要控制按键按下时给一个低电平0,不按下时默认高电平1就行。  2按键控制

    2024年02月11日
    浏览(55)
  • 【51单片机】:闪灯、流水灯(从左往右)、流水灯(从右往左)、蜂鸣器。

            言归正传,一切都回归本源,从51再来一次,首先就是最简单的点灯大师。         这么些年从51 到  32  再到  arduino  再到  ESP  等等,都是从点灯大师开始的。 于是介绍如下: 闪灯 流水灯(从左往右) 流水灯(从右往左) 蜂鸣器         LED灯的原理:LED是发

    2024年02月11日
    浏览(54)
  • 基于51单片机设计的花样流水灯设计

    花样流水灯是一种常见的LED灯效果,被广泛应用于舞台表演、节日庆典、晚会演出等场合。在现代智能家居、电子产品中,花样流水灯也被广泛使用,通过调整亮灭顺序和时间,可以实现各种炫酷的灯光效果,增强用户体验。而51单片机作为一种常见的嵌入式开发平台,具有

    2024年02月09日
    浏览(47)
  • 51单片机通过两个按键控制流水灯方向

    按键一接单片机P3_1,按键2接P3_0 8个流水灯接P2口 以下是代码:

    2024年02月11日
    浏览(48)
  • 单片机c51中断 — 中断键控流水灯

    项目文件 文件 关于项目的内容知识点可以见专栏单片机原理及应用 的第五章,中断   在第4章的实例2中,按键检测是采用查询法进行的,其流程图如图所示 问题是这样的:由于查询法 -按键查询、标志位修改及彩灯循环几个环节是串联关系,当CPU运行于彩灯时,将因不能及

    2024年02月08日
    浏览(60)
  • 51单片机流水灯三种实现方法

    流水灯可以用三种方法实现 一.通过移位函数  _crol_()  和  _cror_() 二.位移实现流水灯 三.数组流水灯实现 首先说一下流水灯的原理 让0从左往右位移或者从右往左位移 从而实现流水灯依次点亮 电路图如下,使用软件是project 使用左移函数代码如下  ///运行结果是LED灯从上到

    2023年04月09日
    浏览(55)
  • 【51单片机】按键操作(单个灯闪烁&&流水灯)

    🎊专栏【51单片机】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【如愿】 大一同学小吉,欢迎并且感谢大家指出我的问题🥰 目录 ⭐注意 🍔同一个灯  🏳️‍🌈效果 🏳️‍🌈代码 🏳️‍🌈问题分析 ⭐注意 ⭐P3_1=0,表示按下按键  ⭐为什么while(

    2024年02月01日
    浏览(73)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包