目录
一、实验的背景和意义
二、实验目的
三、实验步骤
四、实验仪器
五、实验任务及要求
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){ // 如果移到最右边了,就右移位数重置位0r_move=0;}}}
2,从其他小灯并向右依次点亮其他小灯
以下是我的草稿:
呈现效果都测试过,都OK。如果不OK就评论区留言或者是私信我,最近放假,都在线。
1)从led3开始右移
令P0= ~(0x02>>r_move);
因为led3加上右边的led2,只需要进行两个位移,所以需要修改下面代码👇
if(r_move==2){ // 如果移到最右边了,就右移位数重置位0r_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>16){ r_move=0; //第一次从左到右再从右到左完成后,让位移重置为0}else if(r_move<8){P0=~(0x80>>r_move); // 从led9开始右移for(i=0;i<30000;i++); //软件延时}else if(r_move>=8 && r_move<=16){ P0=~(0x01<<(r_move-8)); // 如果移到最右边,就将P0重新赋值,变成左移for(i=0;i<30000;i++); //软件延时}r_move++; //移动的位数自增}}
有问题请在评论区留言或者是私信我,一天8h在线。