这道题其实并不难,主要考的是思维逻辑,这边我们只写平常常用的按键与呼吸灯,通过变量控制来达到想要的效果,不用定时器,只在循环中完成任务。我们按照任务步骤一步一步开发,先写初始化,然后编写按键触发代码,最后在相应位置加入灯的效果。
※本次代码使用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源代码
/** ****************************************************************************** * File Name : main.c * Description : Main program body * By :Azhuo ****************************************************************************** */ #include#include #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都解决不了就别比了,加油各位,奥利给。