题目要求
1.实现按下K1启动呼吸流水灯,由LED1~LED8依次进行呼吸,再按下一次K1,流水的方向从当前正在呼吸的LED开始逆向流水变化。
2.按下K1不松手,停止流水变化和当前正在呼吸的LED的亮度不变,松手后继续呼吸和流水变化。
3.每个LED灯,缓慢点亮0.5秒,缓慢熄灭0.5秒。
【注】 题目要求和程序的部分思路参考自小蜜蜂老师
原文链接:https://blog.csdn.net/ohy3686/article/details/88372244
本例采用普中的51开发板测试
【程序】
#include <REGX52.H>
#include <INTRINS.H>
sbit K1=P3^1;
unsigned int count_Breath;//用于呼吸时长的计数
unsigned char count_pwm;//用于占空比的计数
unsigned char pwm_duty;//占空比
unsigned char breath_Direct;//控制是‘呼’还是‘吸’
unsigned char led_index;//保存当前进行呼吸的LED下标
unsigned char led_run_direct;//流水灯的方向。1为LED1-LED8,0为LED8-LED1
unsigned char K1_Keep_flag;//K1持续按下的标志,K1按下不松手时将其置1
void Delay(unsigned int xms) //@12.000MHz
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
void Timer0_init(void)//12MHz@1ms
{
TMOD = 0x01;
TH0 = (65535 - 1000) / 256;
TL0 = (65535 - 1000) % 256;
ET0 = 1;
EA = 1;
}
void Timer0_routine(void) interrupt 1
{
TH0 = (65535 - 1000) / 256;
TL0 = (65535 - 1000) % 256;
//当K1按下不松手时,K1_Keep_flag=1,此时就不会执行K1_Keep_flag++,那么就可以实现按住K1停止呼吸和流水变化了
if(K1_Keep_flag==0)
{
count_Breath++;
}
count_pwm++;
count_pwm%=10;//将pwm分成10份
if(count_pwm<pwm_duty)
{
P2=~(0x01<<led_index);
}
else
{
P2=0xFF;
}
if(count_Breath>=50 && breath_Direct==1)//占空比增加
{
pwm_duty++;
count_Breath=0;
if(pwm_duty>=10)
{
breath_Direct=0;
pwm_duty=9;
}
}
if(count_Breath>=50 && breath_Direct==0)//占空比减小
{
pwm_duty--;
count_Breath=0;
if(pwm_duty==255)
{
breath_Direct=1;
pwm_duty=0;
//当一个LED执行完一次呼吸以后跳转到下一个LED
if(led_run_direct==1)
{
led_index++;
led_index%=8;
}
else if(led_run_direct==0)
{
led_index--;
if(led_index==255)//已经溢出了
{
led_index=7;
}
}
}
}
}
//按键扫描,通过按键K1控制流水灯的方向
void alone_key_scan(void)
{
if(K1==0)
{
Delay(5);
while(K1==0)//当K1按下不松手时,保持当前的正在呼吸的LED和它的亮度不变
{
K1_Keep_flag=1;
}
Delay(5);
K1_Keep_flag=0;
TR0 = 1;//上电以后要按下K1才开始流水呼吸灯
led_run_direct=!led_run_direct;
}
}
void main()
{
Timer0_init();
while(1)
{
alone_key_scan();
}
}