任务要求:
- ZigBee节点盒通电或重置,节点盒的LED1、LED2灯都不亮。
- 长按SW1键不松开,LED1灯亮,LED2灯熄灭。
- 松开SW1键,LED1、LED2亮灯都常亮。
- 双击SW1可以控制LED1灯实现呼吸灯效果,LED2灯保持熄灭状态。
- 再次双击SW1可以控制LED1维持当前亮度不再发生变化,LED2继续保持熄灭状态。
- 将编写好的程序发布到蓝色ZigBee节点盒中。
任务分析:
这道题其实并不难,主要考的是思维逻辑,这边我们只写平常常用的按键与呼吸灯,通过变量控制来达到想要的效果,不用定时器,只在循环中完成任务。我们按照任务步骤一步一步开发,先写初始化,然后编写按键触发代码,最后在相应位置加入灯的效果。
代码实现:
※本次代码使用library版竞赛工程
在工程app目录下新建Breath.c与.h文件,该呼吸灯代码是从别的工程移植过来的,有明显bug,建议动手修改,改不来留言
以下为Breath.c文件,
#include "iocc2530.h"
#include "Breath.h"
#define false 0
#define true 1
unsigned char levelCount = 8;
unsigned char led_levet_timer = 2;
unsigned char devideCount = 16;
unsigned char level = 1;
unsigned char timeTic = 0;
unsigned char isUprise = 1;
void _pwmLevelUp() {
static unsigned long led_level_tick = 0;
led_level_tick++;
if (led_level_tick > led_levet_timer) {
led_level_tick = 0;
if (isUprise)
level++;
else
level--;
if (level > levelCount) {
level = levelCount;
isUprise = false;
} else if (level == 0) {
isUprise = true;
}
}
}
void _pwm() {
timeTic++;
if (timeTic > level) {
P1_0 = 1;
}
if (timeTic > levelCount) {
timeTic = 0;
P1_0 = 0;
}
}
unsigned char timeDevice = 0;
void _breathLed() {
timeDevice++;
if (timeDevice >= devideCount) {
timeDevice = 0;
_pwmLevelUp();
}
_pwm();
}
以下为Breath.h文件
#ifndef _BREATH_H_
#define _BREATH_H_
#endif
void _pwm(void);
void _breathLed(void);
以下为Main.c内容
引入头文件,定义所需变量
#include "Breath.h"
#define Sw1 P1_2
#define Led1 P1_0
#define Led2 P1_1
unsigned int keyTime=0, keyCnt=0, bFlag=0;
//keyTime长按时间,keyCnt按键次数,bFlag是否呼吸1呼吸0暂停
初始化函数,基本io最简化版
void Init()
{
P1DIR = 0X1B;
P1=0X00;
}
以下为按键功能,比较简单,不理解就自己断点跑一跑
void key()
{
if(Sw1==0)
{
keyTime = 0;
while(Sw1==0)
{
halMcuWaitMs(1);
//按下时间大于300ms视为长按,
if(++keyTime>300)
{
Led1 = 1;
Led2 = 0;
}
}
if(Sw1==1)
{
//长按后灯全部亮起,短按则计算按键次数
if(keyTime>300)
Led1 = Led2 = 1;
else
keyCnt+=1;
}
}
//0.3s内没有第二次点击按钮则失效当前次数
//短时间内连续触发即为连击
if(keyCnt>1)
{
halMcuWaitMs(1);
if(++keyTime>300)
{
if(bFlag==0)
bFlag=1;
else if(bFlag==1)
bFlag=2;
else if(bFlag==2)
bFlag=1;
keyCnt=0;
}
}
}
以下为呼吸灯控制代码
void BreathLed()
{
//几连击就填几
if(keyCnt==2)
{
Led2=0;
bFlag=!bFlag;
keyCnt=0;
}
if(bFlag==1)
_breathLed();
else if(bFlag==2)
_pwm();
}
以下为main函数
void main(void)
{
Init();
while(1)
{
halMcuWaitMs(1);
key();
BreathLed();
}
}
main.c源代码文章来源:https://www.toymoban.com/news/detail-719263.html
/**
******************************************************************************
* File Name : main.c
* Description : Main program body
* By :Azhuo
******************************************************************************
*/
#include <string.h>
#include <stdio.h>
#include "basic_rf.h"
#include "hal_defs.h"
#include "hal_cc8051.h"
#include "hal_int.h"
#include "hal_mcu.h"
#include "hal_board.h"
#include "hal_led.h"
#include "hal_rf.h"
#include "hal_uart.h"
#include "Breath.h"
#define Sw1 P1_2
#define Led1 P1_0
#define Led2 P1_1
unsigned int keyTime=0, keyCnt=0, bFlag=0;
//keyTime长按时间,keyCnt按键次数,bFlag是否呼吸1呼吸0暂停
void Init()
{
P1DIR = 0X1B;
P1=0X00;
}
void key()
{
if(Sw1==0)
{
keyTime = 0;
while(Sw1==0)
{
halMcuWaitMs(1);
//按下时间大于300ms视为长按,
if(++keyTime>300)
{
Led1 = 1;
Led2 = 0;
}
}
if(Sw1==1)
{
//长按后灯全部亮起,短按则计算按键次数
if(keyTime>300)
Led1 = Led2 = 1;
else
keyCnt+=1;
}
}
//0.3s内没有第二次点击按钮则失效当前次数
//短时间内连续触发即为连击
if(keyCnt>1)
{
halMcuWaitMs(1);
if(++keyTime>300)
{
if(bFlag==0)
bFlag=1;
else if(bFlag==1)
bFlag=2;
else if(bFlag==2)
bFlag=1;
keyCnt=0;
}
}
}
void BreathLed()
{
//几连击就填几
if(keyCnt==2)
{
Led2=0;
bFlag=!bFlag;
keyCnt=0;
}
if(bFlag==1)
_breathLed();
else if(bFlag==2)
_pwm();
}
/**
* Main application entry point.
*/
void main(void)
{
Init();
while(1)
{
halMcuWaitMs(1);
key();
BreathLed();
}
}
今天的训练就到这,下了鬼泣5所以比较急,代码是有些bug的,不过如果这点bug都解决不了就别比了,加油各位,奥利给。文章来源地址https://www.toymoban.com/news/detail-719263.html
到了这里,关于【23物联网国赛样题第二套】单片机,CC2530单片机呼吸灯与按键控制--单击双击长按、呼吸灯与亮度维持,物联网竞赛今年历年国赛样题真题代码的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!