6.2 项目二编程实现开发板上两个灯的亮灭
1.项目需求
通过程序设计实现对开发板(如图6-1所示)上两个灯D3、D4亮灭的控制。
2.项目分析
要想控制开发板上的两个灯D3和D4的亮灭,需要找到灯对应的引脚,通过引脚发送指令来控制灯的状态。要使两个引脚P1.0和P1.1能够输出指令控制两个灯D3和D4的亮灭,首先要设置引脚与灯的对应关系。可以通过宏定义#define D3 P1_0定义灯D3为P1.0口控制,通过宏定义#define D4 P1_1定义灯D4为P1.1口控制,这样就建立好了两个引脚和两个灯之间的对应关系。然后通过P1口的功能选择寄存器表查看到引脚值为1表示外设功能,为0表示普通输入输出口。要从引脚输出指令控制灯,就必须将引脚设为普通输入输出功能,因此引脚值应置为0。P1口的功能寄存器与16进制的03取反后进行逻辑与运算:
P1SEL&=~0x03
等价于:
P1SEL&=~00000011
等价于:
P1SEL&=11111100
因为逻辑与运算的规则为:
1&&1=1;
1&&0=0;
0&&1=0;
0&&0=0。
因此,无论P1口的功能寄存器原来的值为多少,与11111100做逻辑与运算后,最后两位的结果一定是0,这样引脚P1.0和P1.1的值一定是0,这就保证了这两个引脚为普通输入输出功能。
要想从引脚向灯输出指令,必须将引脚的方向设置为输出,从P1口的方向寄存器表中查看到引脚值0为输入,1为输出。因此要设置方向寄存器对应的引脚值为1,P1口的方向寄存器与16进制的03取反后进行逻辑或运算:
P1DIR|=0x03
等价于:
P1DIR|=00000011
因为逻辑或运算的规则为:
1||1=1;
1||0=1;
0||1=1;
0||0=0。
因此,无论P1口的方向寄存器原来的值为多少,与00000011做逻辑或运算后,最后引脚位P1.0和P1.1的结果一定是1,这就保证了这两个引脚方向为输出。
Delay为延时函数,通过5个for循环可实现延时一定的时间,每个for循环都是从0到n的计数延时。对于不同的单片机,延时函数的延时时间不同。
在主程序中,通过while循环设置两灯同时亮,延时一定的时间后,再同时灭,然后重复此过程。“D3=!D3;”和“D4=!D4;”是将两灯的状态分别取反后再赋值给两灯,也就是说,如果灯D3原来是亮的状态,取反后就变为灭的状态,如果原来是灭的状态,取反后就变为亮的状态,同理,灯D4也是一样的。
3.程序设计
程序设计如下:
#include ioCC2530.h
#def ine D3 P1_0(https://www.daowen.com)
#def ine D4 P1_1
void Delay(int n)

通过仿真器将程序烧写到开发板中,并运行程序,可以看到两灯间隔一定的时间实现了亮灭状态的转换。
4.举一反三
如果更改项目需求,要求实现开发板上D5和D6两个灯的亮灭,那程序该怎么编写?
分析:
要想控制开发板上两个灯D5和D6的亮灭,需要找到灯对应的引脚,通过引脚发送指令去控制灯的状态。从图6-2中,可以看出,D5和D6两个灯对应的引脚是P1.3和P1.4,要使两个引脚能够输出指令控制两个灯D5和D6的亮灭,首先要设置引脚与灯的对应关系。可以通过宏定义#define D5 P1_3定义灯D5为P1.3口控制,通过宏定义#define D6 P1_4定义灯D6为P1.4口控制,这样就建立好了两个引脚P1.3和P1.4与两个灯D5和D6之间的对应关系。然后通过P1口的功能选择寄存器表查看到引脚值为1表示外设功能,为0表示普通输入输出口。要从引脚输出指令控制灯,就必须将引脚设为普通输入输出功能,因此引脚值应置为0。P1口的功能寄存器与16进制的03取反后进行逻辑与运算:
P1SEL&=~0x18
等价于:
P1SEL&=~00011000
等价于:
P1SEL&=11100111
因此,无论P1口的功能寄存器原来的值为多少,与11100111做逻辑与运算后,P1.3和P1.4两位的结果一定是0,这就保证了这两个引脚为普通输入输出功能。
要想从引脚向灯输出指令,必须将引脚的方向设置为输出,从P1口的方向寄存器表中查看到引脚值0为输入,1为输出。因此要设置方向寄存器对应引脚值为1,P1口的方向寄存器与16进制的03取反后进行逻辑或运算:
P1DIR|=0x18
等价于:
P1DIR|=00011000
因此,无论P1口对应的方向寄存器原来的值为多少,与00011000做逻辑或运算后,P1.3和P1.4两位的结果一定是1,这就保证了这两个引脚方向为输出。
在主程序中,通过while循环设置两灯同时亮,延时一定的时间后,再同时灭,然后重复此过程。“D5=!D5;”和“D6=!D6;”是将两灯的状态分别取反后再赋值给两灯,也就是说,如果灯D5原来是亮的状态,取反后就变为灭的状态,如果原来是灭的状态,取反后就变为亮的状态,同理,灯D6也是一样的。
程序设计如下:


通过仿真器将程序烧写到开发板中,并运行程序,可以看到两灯D5和D6间隔一定的时间同时实现了亮灭状态的转换。
5.思考题
如果将项目需求改为实现控制两个灯D3和D5的亮灭或者控制D4和D6的亮灭,又该怎样设计程序呢?
提示:关键点在于设置引脚和灯的对应关系,一定要在程序开始,通过宏定义设置灯和引脚的对应。然后要注意的是功能寄存器和方向寄存器的赋值。必须使控制灯的那个引脚位设为普通输入输出口,该引脚才具有输入输出指令的功能。要从引脚往外输出指令,必须使该引脚位的方向为输出。因此如果要控制D3和D5两个灯,就要将引脚位P1.0和P1.3设置为输出,即
P1SEL&=~0x09
P1DIR|=0x09
这样就保证了两个引脚P1.0和P1.3为输出功能。最后在主程序中将对应的灯名字更改一下即可。
具体程序请读者自己编写完成。