任务要求
找到1块Zigbee开发呼吸流水灯控制,在“竞赛资料\任务三”中新建工程,实现功能如下:
【1】 Zigbee模块板程序运行时,D3灯亮,其余灯灭。
【2】 点按Zigbee板上的按键SW1(按下抬起),控制Zigbee板上D3-D6四个小灯每隔0.5s呼吸流水点亮;即:D4缓慢亮->D4缓慢灭-> D3缓慢亮->D3缓慢灭 ->D6缓慢亮->D6缓慢灭->D5缓慢亮->D5缓慢灭;循环重复。
【3】 再次点按Zigbee板的按键SW1,控制Zigbee板上从当前灯开始逆向呼吸流水;即:比如当前流水是D6缓慢灭->D5缓慢亮,按下SW1抬起D5缓慢灭->D6缓慢亮->D3缓慢亮->D3缓慢灭->D4缓慢亮->D4缓慢灭。
补充说明:
<1> 开发完成后编译程序,下载至Zigbee模块,在Zigbee板的小辣椒上贴“题1”;
<2> 将Zigbee板放在左工位桌面上,接上电源,待裁判评判。
D3-D6灯硬件电路详见:CC2530/Zigee开发板资料汇总
HEX烧写代码下载:2019年山东省赛-任务三题1-休闲区彩色灯控制
参考源码
#include "ioCC2530.h"
#define D3 P1_0
#define D4 P1_1
#define D5 P1_3
#define D6 P1_4
#define SW1 P1_2
unsigned char pwm = 0; //PWM信号变化单位
unsigned char pwm_duty = 0; //PWM信号占空比
unsigned char times = 0; //PWM信号周期累计
unsigned char led_go = 0; //LED流水方向标志
unsigned char stat_go = 0; //LED灯变化标志
unsigned char stat = 1; //LED灯状态标志
unsigned char key_puse = 0; //按键状态标志
void Init_Port()
{
//初始化LED灯的I/O端口
P1SEL &= ~0x1b; //P1_0、P1_1、P1_3和P1_4作为通用I/O端口
P1DIR |= 0x1b; //P1_0、P1_1、P1_3和P1_4端口输出
P1SEL &= ~0x04; //P1_2作为通用I/O端口
P1DIR &= ~0x04; //P1_2端口输入
P1INP &= ~0x04; //P1_2设置为上拉/下拉模式
P2INP &= ~0x40; //P1_2设置为上拉
//关闭所有的LED灯
P1 &= ~0x1b;
}
void Init_Timer1()
{
T1CC0L = 0x80; //16MHz时钟1分频定时1ms
T1CC0H = 0x3e; //设先填低8位,再填高8位
T1CCTL0 |= 0x04; //开启通道0的输出比较模式
T1IE = 1; //使能定时器1中断
T1OVFIM = 1; //使能定时器1溢出中断
EA = 1; //使能总中断
T1CTL = 0x02; //分频系数是1,模模式
}
#pragma vector = T1_VECTOR
__interrupt void Timer1_Sevice()
{
T1STAT &= ~0x01; //清除定时器1通道0中断标志
if(stat_go == 0) //开机后,D3点亮
{
D3 = 1;
return;
}
pwm++; //PWM信号单位累加
if(pwm <= pwm_duty)
{
switch(stat)
{
case 1: D4 = 1; break;
case 2: D3 = 1; break;
case 3: D6 = 1; break;
case 4: D5 = 1; break;
}
}
else if(pwm <= 10){
D4 = 0; D3 = 0; D6 = 0; D5 = 0;
}
else
{
switch(stat)
{
case 1: D4 = 1; break;
case 2: D3 = 1; break;
case 3: D6 = 1; break;
case 4: D5 = 1; break;
}
pwm = 0;
if(key_puse == 0) //按键按下,暂停呼吸
times++;
}
}
void LED_Control()
{
if(times == 5) //每50ms改变一次PWM信号的占空比
{
times = 0;
if(led_go == 0) //缓慢变亮
{
pwm_duty = pwm_duty + 1;
if(pwm_duty == 11)
{
pwm_duty = 10;
led_go = 1;
}
}
else if(led_go == 1) //缓慢变暗
{
pwm_duty = pwm_duty - 1;
if(pwm_duty == 255)
{
pwm_duty = 0;
led_go = 0;
if(stat_go == 1) //正方向时,切换LED灯
{
stat++; //进行正向流水切换
if(stat == 5)
stat = 1;
}
else if(stat_go == 2) //反方向时,切换LED灯
{
stat--; //进行反向流水切换
if(stat == 0)
stat = 4;
}
}
}
}
}
void Delay(unsigned char t)
{
while(t--);
}
void Scan_Keys()
{
if(SW1 == 0)
{
Delay(100); //去抖动
if(SW1 == 0)
{
while(SW1 == 0)
{
key_puse = 1; //标志按键按下
}
key_puse = 0;
stat_go++; //改变流水方向
if(stat_go == 3)
{
stat_go = 1;
}
}
}
}
void main()
{
Init_Port(); //初始化LED和按键的I/O端口
Init_Timer1(); //初始化定时器
while(1)
{
LED_Control(); //呼吸流水灯的核心控制
Scan_Keys(); //按键扫描与处理
}
}