发个PWM调光灯驱动16路LED+按键长按短按

2020-01-25 15:39发布

现在白光高亮LED红 {MOD}光谱缺失,晚上看起来很刺眼,加了红 {MOD}LED舒服多了。以后搞三基 {MOD}调光。
ULN2003驱动高电平LED亮,只占用一个定时器
#include < reg52.h >
#include <intrins.h>
#include "i2c.h"
#define OP_WRITE 0xa0          // 器件地址以及写入操作
#define OP_READ  0xa1          // 器件地址以及读取操作
sbit KEY_SAVE=P1^0;
sbit KEY_W=P1^1;
sbit KEY_R=P1^2;
sbit KEY_UP=P1^3;
sbit KEY_DOWN=P1^4;
sbit SDA = P3 ^ 1;
sbit SCL = P3 ^ 0;

//old 为24C04读出的值 W为白 {MOD} R为红 {MOD} 以后加入闪灯功能
volatile unsigned char pwm_w_old,pwm_w_new,pwm_r_old,pwm_r_new,PWM; //pwm_w_old 为白光的PWM值,如此类推
volatile unsigned int keytemp;
bit keystar,light_w,light_r,w_down,r_down,up_down,down_down, //按键按下值,有效值
    save_down,SAVE,long_save_down,long_save;


void keyscan(void)
{
if(KEY_W==0||KEY_R==0||KEY_UP==0||KEY_DOWN==0||KEY_SAVE==0)
{ keystar=1;
   if((KEY_W==0)&&keytemp>=200)    w_down=1;
   if((KEY_R==0)&&keytemp>=200)    r_down=1;
   if((KEY_UP==0)&&keytemp>=200)   up_down=1;
   if((KEY_DOWN==0)&&keytemp>=200) down_down=1;
   if(KEY_SAVE==0&&keytemp>=200) save_down=1;
   if(KEY_SAVE==0&&keytemp>=20000) {save_down=0; long_save_down=1;}
}
else {
   if((KEY_W==1)&&(w_down==1)) {light_w=~light_w; w_down=0;}         //等待按键抬起
   if((KEY_R==1)&&(r_down==1)) {light_r=~light_r; r_down=0;}
   if((KEY_UP==1)&&(up_down==1)&&(light_w==1)){ pwm_w_new++;}
   if((KEY_UP==1)&&(up_down==1)&&(light_r==1)){ pwm_r_new++;}
   if((KEY_UP==1)&&(up_down==1)) up_down=0;
   if((KEY_DOWN==1)&&(down_down==1)&&light_w&&pwm_w_new>0) pwm_w_new--;         
   if((KEY_DOWN==1)&&(down_down==1)&&light_r&&pwm_r_new>0) pwm_r_new--;
   if((KEY_DOWN==1)&&(down_down==1)) down_down=0;
   if((KEY_SAVE==1)&&(save_down==1)) {save_down=0; SAVE=1;}  
   if((KEY_SAVE==1)&&(long_save_down==1)) {long_save_down=0; long_save=1;}
   keystar=0;

}
}

void InitTimer0(void)
{
    TMOD = 0x01;
    TH0 = 0x0FF;
    TL0 = 0x9C;
    EA = 1;
    ET0 = 1;
    TR0 = 1;
}

void main(void)
{
sysinit();
InitTimer0();
pwm_w_old=read_byte(0x00);
if(pwm_w_old>100) pwm_w_old=100;
delayms(20);
pwm_r_old=read_byte(0x01);
if(pwm_r_old>100) pwm_r_old=100;
delayms(20);
pwm_w_new=pwm_w_old;
pwm_r_new=pwm_r_old;
if(pwm_w_old<=100){pwm_w_new=pwm_w_old;} else {pwm_w_new=100;}
if(pwm_r_old<=100){pwm_r_new=pwm_r_old;} else {pwm_r_new=100;}


while(1)
{
keyscan();
if(pwm_r_new>=100) pwm_r_new=100;
if(pwm_w_new>=100) pwm_w_new=100;
if (PWM<=pwm_r_new)         {P2=0xff;} else{P2=0;}
if (PWM<=pwm_w_new)         {P0=0xff;} else{P0=0;}
if (SAVE==1) //短按保存当前PWM值
{
if (pwm_w_new!=pwm_w_old){ write_byte(0x00,pwm_w_new); pwm_w_old=pwm_w_new;delayms(1);}
//不加delay老出错,估计是这个24C04为慢速器件
if (pwm_r_new!=pwm_r_old){ write_byte(0x01,pwm_r_new); pwm_r_old=pwm_r_new;delayms(1);}
SAVE=0;
}
if (long_save==1)
{
//没想好长按后有什么功能,先摆着把。
}

}

}

void Timer0Interrupt(void) interrupt 1
{
//100us 定时
   TH0 = 0x0FF;
    TL0 = 0x9C;
PWM++;
if (keystar)
{
keytemp++;
if (keytemp>=30000) keytemp=30000;
}
else
{
keytemp=0;
}
if (PWM>=100) PWM=0;


        }
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。