6.5 项目五编程实现四个灯的流水灯效果
1.项目需求
通过程序设计实现开发板上四个灯的流水灯效果。
2.项目分析
要实现开发板上四个灯D4、D3、D6、D5的流水灯效果,需要找到四个灯的对应引脚,通过引脚发送指令去控制灯的状态。
要使四个引脚P1.0、P1.1、P1.3、P1.4能够输出指令控制四个灯D4、D3、D6、D5的流水灯效果,首先要设置引脚与灯的对应关系。可以通过宏定义#define D3 P1_0定义灯D3为P1.0口控制;通过宏定义#define D4 P1_1定义灯D4为P1.1口控制;通过宏定义#define D5(P1_3)定义灯D5为P1.3口控制;通过宏定义#define D6(P1_4)定义灯D6为P1.4口控制。这样就建立好了四个引脚和四个灯之间的对应关系。
要从引脚输出指令控制灯,必须将引脚设为普通输入输出功能,因此引脚值应置为0。P1口的功能寄存器与16进制的1B取反后进行逻辑与运算:
P1SEL&=~0x1B
等价于:
P1SEL&=~00011011
等价于:
P1SEL&=11100100
因此,无论P1口的功能寄存器原来的值为多少,与11100100做逻辑与运算后,P1.0、P1.1、P1.3、P1.4的结果一定是0。这样引脚P1.0、P1.1、P1.3、P1.4的值一定是0,保证了这四个引脚为普通输入输出功能。
要从引脚向灯输出指令,必须将引脚的方向设置为输出,从P1口的方向寄存器表中查看到引脚值0为输入,1为输出。因此要设置方向寄存器对应引脚值为1,P1口的方向寄存器与16进制的1B取反后进行逻辑或运算:
P1DIR|=0x1B
等价于:
P1DIR|=00011011
因此,无论P1口的方向寄存器原来的值为多少,与00011011做逻辑或运算后,P1.0、P1.1、P1.3、P1.4的结果一定是1。这样引脚P1.0、P1.1、P1.3、P1.4的值一定是1,保证了这四个引脚方向为输出。
在主程序中,通过while循环设置两灯同时亮,延时一定的时间后,再同时灭,然后重复此过程。“D3=!D3;”和“D4=!D4;”是将两灯的状态分别取反后再赋值给两灯,也就是说,如果灯D3原来是亮的状态,取反后就是灭的状态,如果原来是灭的状态,取反后就是亮的状态,同理,灯D4也是一样的。(https://www.daowen.com)
3.程序设计
程序设计如下:


通过仿真器将程序烧写到开发板中,并运行程序,可以看到四个灯初始状态为全灭,然后在延时一定时间后依次亮,并分别延时亮的状态一定的时间,又依次灭,接着再次循环上述过程。该流水灯效果的设计是根据四个灯在开发板上的位置顺序设置的,读者可根据本项目去更改四个灯的点亮顺序和延时效果。
4.举一反三
思考:如果更改需求为按D5、D6、D3、D4的顺序设置流水灯效果,该怎么编写程序?
只需更改主函数中while循环中的循环语句,将四个灯的点亮顺序设置为要求的顺序即可。
程序如下:


思考:要求四个灯按D4、D3、D6、D5的顺序亮,按D5、D6、D3、D4的顺序灭,并且在灯全亮了之后再开始灭,则循环上述过程的程序该怎样编写?
分析:
除了考虑点亮和熄灭的顺序,延时的时间也要考虑,因此,第一个点亮的灯需要保持亮的状态直到第四个灯点亮,而且在灭的时候要保证在前三个灯熄灭后再熄灭。因此在调用延时函数时,每个灯的延时时间都是不同的。
程序如下:


将程序烧写进开发板,可观察到四个灯的流水效果。