51单片机实验02- P0口流水灯实验

目录

一、实验的背景和意义

二、实验目的

三、实验步骤

四、实验仪器

五、实验任务及要求 

1,从led4开始右移

1)思路 

①起始灯 (led4)

②右移

2)效果

3)代码☀

 2,从其他小灯并向右依次点亮其他小灯 

1)从led3开始右移

2)从led5开始右移

3)从led6开始右移

4)从led7开始右移

5)从led8开始右移

6)从led9开始右移

3,完成一个左移到头接着右移,右移到头再接着左移的花样流水灯程序。

 1)效果

2)代码


一、实验的背景和意义


通过流水灯实验进一步增进对51单片机电路的感性认识,加深对理论方面的理解。了解软硬件的有关知识,并掌握软硬件设计过程、方法及实现,为以后设计和实现应用系统打下良好基础。另外,通过简单课题的设计练习,使我们了解必须提交的各项工程文件,达到巩固、充实和综合运用所学知识解决实际问题的目的。
本实验采用STC89C52RC单片机为中心器件来实现P0并行口控制8只LED小灯进行流水灯显示实验。

二、实验目的


1、进一步掌握编程软件Keil uVision4和下载软件STC-ISP-v4.80等的使用方法;
2、掌握51单片机并行口输出方式的编程;
3、掌握延时程序的编写和应用。

三、实验步骤


51单片机实验01-点亮LED小灯-CSDN博客相应操作。

四、实验仪器


计算机1台、KST-51开发板1套。

五、实验任务及要求 

1,从led4开始右移


学号末位和小灯对应关系同51单片机实验01-点亮LED小灯-CSDN博客。具体操作见本实验的后续要求。按照上述学号末尾对应的小灯作为开始,依次向右点亮其他小灯并循环,进行流水灯显示实验,编写完整c语言代码。 

 相关资料请通过链接下载👇

链接:https://pan.baidu.com/s/1QEDpuNhcYVB6lmxFNW2z4Q?pwd=6666 
提取码:6666 
--来自百度网盘超级会员V1的分享

1)思路 

 因为我学号末尾时4,因此这里先以led4作为讨论的对象,其他的led灯皆可以此类推,进行点亮。

①起始灯 (led4)

在实验01中,因为我只需要点亮一个小灯,因此需要用到P0口的只有一位,但是如果我要实现流水灯的效果,就需要使用到P0口的其他七位,来依次点亮led灯,即用到P0.0~P0.7,分别对应led2~led9。

最右边的小灯led2的P0口需要输入0b1111 1110 ,就是将最后一个led灯输入为低电平。其它为高电平,就会亮指定的led灯。

同理,led3亮起的二进制为0b1111 1101,led4为0b1111 1011,led5为0b1111 0111.......

通过观察,不难发现,都是0的移动。如果想要实现小灯向右移动,就需要0向左移,其它位为1。这个时候就引入了位移(<<左移和>>右移)这个概念,顾名思义,位移需要在二进制中进行,因为只有二进制数的每一个位都是显示出来的。当一个数开始向左移动时,它的左边就会溢出舍弃,右边就会产生空位,且产生的空位会自动给零补全。

这个时候我将led4(0b1111 1011)向左平移<<一位

就会得到 0b1111 0110和led3的0b1111 1011不相等。显然,光通过位移是没法满足我的需求的,这个时候就可以再加上取反(~)这一运算,可以先将led4(0b1111 1011)取反→变成0b 0000 0100→之后再右移一位→得到0b 0000 0010。该二进制和led3 的0b1111 1011就差了取反。再次取反,就可得到led3。

【为什么会想到取反?主要是因为当用到位移,当一个二进制数中只有一个0,而其他位为1时,就可以对该二进制取反,进行位移,来得到我想要的效果。】

现在,我直接拿led4(0b1111 1011)取反后的结果0b 0000 0100来进行右移,最后再取反,来实现流水灯的效果。

一般来说,在代码中建议使用16进制来表示一个数,因此我将0b 0000 0100换算成十六进制,结果为0x04,之后再对0x04取反就可以表示led4这个灯,所以i编写语句:P0=~0x04。

就可以让led4灯作为起始灯亮起来。

②右移

实现右移就是让起始灯led4(因为我学号是4,就led4为例)的值0x04依次向右移>>1,并进行取反。并且需要在main方法里面定义一个变量r_move来控制向右移动的位数,当r_move为0时,表示没有移位,亮的是当前的起始灯led4,r_move=1时,向右移动1位,亮起led3,以此类推。

2)效果

从指定位置的led开始右移

3)代码☀

#include<reg52.h> 
sbit addr0=P1^0;  // 138译码器低位输入
sbit addr1=P1^1; // 138译码器中位输入
sbit addr2=P1^2;// 138译码器高位输入
sbit addr3=P1^3; // 使能端es
sbit enled=P1^4; // 使能端 e1和e2
void main(){
    unsigned int r_move=0;  // 右移变量
	unsigned int i=0;  // for循环的形参
	addr2=1;   // 高电平
	addr1=1;
	addr0=0;   // 低电平
	enled=0;
	addr3=1; 	 
	while(1){
	  P0=~(0x04>>r_move);  // 从led4开始右移
	  for(i=0;i<40000;i++);	  //软件延时
	  r_move++;			 //右移的位数自增
	  if(r_move==3){   // 如果移到最右边了,就右移位数重置位0
	     r_move=0;
	  }
	}
	}

 2,从其他小灯并向右依次点亮其他小灯 

以下是我的草稿:

 

呈现效果都测试过,都OK。如果不OK就评论区留言或者是私信我,最近放假,都在线。 

1)从led3开始右移

P0= ~(0x02>>r_move);

 因为led3加上右边的led2,只需要进行两个位移,所以需要修改下面代码👇

 if(r_move==2){   // 如果移到最右边了,就右移位数重置位0
	     r_move=0;
	  }

2)从led5开始右移

只需要修改下面两处👇 

3)从led6开始右移

 只需要修改下面两处👇

4)从led7开始右移

只需要修改下面两处👇

5)从led8开始右移

只需要修改下面两处👇

6)从led9开始右移

只需要修改下面两处👇

3,完成一个左移到头接着右移,右移到头再接着左移的花样流水灯程序。

 1)效果

从左到右再从右到左的流水灯1

2)代码

#include<reg52.h> 
sbit addr0=P1^0;  // 138译码器低位输入
sbit addr1=P1^1; // 138译码器中位输入
sbit addr2=P1^2;// 138译码器高位输入
sbit addr3=P1^3; // 使能端es
sbit enled=P1^4; // 使能端 e1和e2
void main(){
    unsigned int r_move=0;  // 右移变量
	unsigned int i=0;  // for循环的形参
	addr2=1;   // 高电平
	addr1=1;
	addr0=0;   // 低电平
	enled=0;
	addr3=1; 	 
	while(1){   // 一直循环下面的操作
     
	  if(r_move<8){
	  P0=~(0x80>>r_move);  // 从led9开始右移
	  for(i=0;i<30000;i++);	  //软件延时
	   }
	  else if(r_move>=8 && r_move<14){   // 右移8位之后,左移从倒数第二位开始,直到正数第二位。右移共6位。
	     P0=~(0x01<<(r_move-7));  // 将P0重新赋值,变成左移
	     for(i=0;i<30000;i++);	  //软件延时
	  }
	  r_move++;			 //移动的位数自增 
	  
       if(r_move==14){   // 左移8位,右移6位,之后让位移置零  
	  r_move=0;	  //第一次从左到右再从右到左完成后
	  }
	}
	
	}

 有问题请在评论区留言或者是私信我,一天8h在线。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值