任务要求
选择找到一块国赛Zigbee小模块或者XMF09B开发板,由选手独立新建工程并编写、编译代码,模拟红绿灯的工作过程,实现以下任务要求:
【1】程序开始运行时:D4、D3、D5、D6灯灭。
【2】单击模块上的SW1按键(按键时间不超过1秒)松开后,启动红绿灯的工作过程,实现D4灯亮3秒,D3灯熄灭,再到D4灯熄灭,D3灯亮2秒的循环过程。
【3】在红绿灯的工作过程中,长按模块上的SW1按键(按下时间超过2秒)松开后,D5灯开始秒闪,即循环亮0.5秒,灭0.5秒。再次长按SW1按键松开后,D5灯停止秒闪,如此反复。在D5灯秒闪的过程中,不能打断或影响红绿灯的正常工作。
【4】双击模块上的SW1按键,停止红绿灯工作,即D4、D3、D5灯灭。
【5】重复上述模拟红绿灯的工作工程。
参考源码
#include "ioCC2530.h"
#define D4 P1_1
#define D3 P1_0
#define D5 P1_3
#define SW1 P1_2
unsigned char count_t = 0; //0.1秒时间累计
unsigned char count_k = 0; //按键触发时间累计
unsigned char K_Press = 0; //按键按下标志
unsigned char F_Start = 0; //红绿灯工作标志
unsigned char F_Shan = 0; //D5灯闪烁标志
/*=======================简单的延时函数========================*/
void Delay(unsigned int t)
{
while(t--);
}
/*======================端口初始化函数========================*/
void Init_Port()
{
P1SEL &= ~0x1b; //P1_0、P1_1、P1_3和P1_4作为通用I/O端口
P1DIR |= 0x1b; //P1_0、P1_1、P1_3和P1_4端口输出
P1 &= ~0x1b; //关闭所有的LED灯
P1SEL &= ~0x04; //P1_2作为通用I/O端口
P1DIR &= ~0x04; //P1_2端口输入
P1INP &= ~0x04; //P1_2设置为上拉/下拉模式
P2INP &= ~0x40; //P1_2设置为上拉
}
/*=======================定时器1初始化========================*/
void Init_Timer1()
{
T1CC0L = 0xd4;
T1CC0H = 0x30; //16MHz时钟,128分频,定时0.1秒
T1CCTL0 |= 0x04; //开启通道0的输出比较模式
T1IE = 1; //开启定时器中断
EA = 1; //开启总中断
T1CTL = 0x0e; //分频系数是128,模模式
}
/*====================定时器1服务函数========================*/
#pragma vector = T1_VECTOR
__interrupt void Timer1_int()
{
T1STAT &= ~0x20; //清除定时器1的溢出中断标志位
if(K_Press == 1) //有按键触发
{
count_k++; //计算按键按下时间
}
if(F_Start == 1) //红绿灯工作启动
{
count_t++; //累计0.1秒间隔定时
if(count_t == 30) //间隔定时3秒
{
D4 = 0;
D3 = 1;
}
else if(count_t == 50) //间隔定时5秒
{
D4 = 1;
D3 = 0;
count_t = 0;
}
if(count_t % 5 == 0) //0.5秒间隔定时
{
if(F_Shan == 1) //秒闪标志有效
{
D5 = ~D5; //D5灯秒闪
}
}
}
else if(F_Start == 0) //红绿灯工作停止
{
D4 = 0;
D3 = 0;
D5 = 0;
F_Shan = 0;
}
}
/*====================按键扫描处理函数========================*/
void Scan_Keys()
{
if(SW1 == 0)
{
Delay(100); //去抖动处理
if(SW1 == 0)
{
K_Press = 1;
while(SW1 == 0); //等待按键松开
if(count_k > 20) //长按确认
{
if(F_Shan == 0)
{
F_Shan = 1; //D5开始秒闪
}
else if(F_Shan == 1)
{
F_Shan = 0; //D5停止秒闪
D5 = 0;
}
K_Press = 0; //按键触发标志清除
count_k = 0; //按键按下时间清零
return; //长按有效,推出按键扫描
}
else
{
while(count_k <= 20)
{
if(SW1 == 0) //在一个按键生命周期内
{
Delay(100);
if(SW1 == 0) //再次有按键有效按下
{
while(SW1 == 0);
F_Start = 0; //双击确认
K_Press = 0;
count_k = 0;
return;
}
}
}
}
F_Start = 1; //单击确认
F_Shan = 0; //D5灯秒闪标志清除
D4 = 1; //启动红绿灯工作
D3 = 0;
K_Press = 0; //按键触发标志清除
count_k = 0; //按键按下时间清零
}
}
}
/*==========================主函数============================*/
void main()
{
Init_Port(); //初始化端口
Init_Timer1(); //初始化定时器1
while(1)
{
Scan_Keys(); //扫描按键
}
}