一:代码展示
#include "stc15.h"
#include "intrins.h"
#include "iic.h"
#include "Display.h"
sbit S4=P3^3;
sbit S5=P3^2;
sbit S6=P3^1;
sbit S7=P3^0;
unsigned char ADC_num;
u8 mode=0;
u8 mode_set=0;
bit lz=0; //0:启动流转 1:停止流转
u16 lztime1=400,lztime2=400,lztime3=400,lztime4=400; //400ms-1200ms
u8 lztime_h[4],lztime_l[4];
u16 lztime;
u16 lztime_set;
u8 jiemian=0; //0:熄灭数码管 1:设置界面 2:亮度界面
bit temp=0; //0:设置运行模式 1:设置流转间隔
u8 liangdu=0; //亮度等级
u8 liangdu_set=1;
u8 Key_Slow_Flag,Data_Slow_Flag,Smg_Slow_Flag,Led_Slow_Flag;
u8 led=0xFF;
u8 count=0;
bit shanshuo=0; //数码管闪烁标志
u8 zkb=0; //pwm占空比
u8 i1=0;
u8 i2=0;
u8 i3=0;
u8 i4=0;
void Key_Proc(void);
void Data_Proc(void);
void Smg_Proc(void);
void Led_Proc(void);
void LedDisplay(u8 LED);
void Delay2ms(void) //@12.000MHz
{
unsigned char data i, j;
i = 24;
j = 85;
do
{
while (--j);
} while (--i);
}
void Timer0_Init(void) //2毫秒@12.000MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x40; //设置定时初始值
TH0 = 0xA2; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
EA=1;
}
void Timer1_Init(void) //100微秒@12.000MHz
{
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x50; //设置定时初始值
TH1 = 0xFB; //设置定时初始值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1=1;
EA=1;
}
void Init(u8 i)
{
P2&=0x1F;
switch(i)
{
case 4:P0=0xFF;HC138(i);P2&=0x1F;P0=0x00;break;
case 5:HC138(i);break;
case 6:HC138(i);break;
case 7:P2&=0x1F;P0=0xFF;HC138(i);break;
}
P2&=0x1F;
}
void main(void)
{
u8 i;
Init(4);
Init(5);
Init(6);
Init(7);
AT24C02_Read(lztime_h,lztime_l,0,4); //每次上电读取LED流转时间
for(i=0;i<4;i++)
{
if(((lztime_h[i]<<8)|lztime_l[i])>=400&&((lztime_h[i]<<8)|lztime_l[i])<=1200)
{
}
else
break;
}
if(i==4)
{
lztime1=(lztime_h[0]<<8)|lztime_l[0];
lztime2=(lztime_h[1]<<8)|lztime_l[1];
lztime3=(lztime_h[2]<<8)|lztime_l[2];
lztime4=(lztime_h[3]<<8)|lztime_l[3];
}
lztime=lztime1;
lztime_set=lztime;
Timer0_Init();
Timer1_Init();
while(1)
{
Key_Proc();
Data_Proc();
Smg_Proc();
Led_Proc();
}
}
void Timer0(void) interrupt 1
{
static u16 i=0;
if(++Key_Slow_Flag==5) Key_Slow_Flag=0;
if(++Data_Slow_Flag==100) Data_Slow_Flag=0;
if(++Smg_Slow_Flag==100) Smg_Slow_Flag=0;
if(++Led_Slow_Flag==lztime/2) Led_Slow_Flag=0;
i++;
if(i==400)
{
shanshuo=~shanshuo; //当处于设置界面时选中的模式或流转时间设置每隔0.8秒闪烁
i=0;
}
SmgDisplay();
LedDisplay(led);
}
void Timer1(void) interrupt 3 //pwm控制LED四个亮度等级
{
static u8 cnt=0;
cnt++;
led=0xFF;
if(cnt<=zkb)
{
if(mode==0)
{
led=led&(~(1<<i1));
}
else if(mode==1)
{
led=led&(~(0x80>>i2));
}
else if(mode==2)
{
led=led&(~(0x80>>i3));
led=led&(~(1<<i3));
}
else if(mode==3)
{
led=led&(~(0x10<<i4));
led=led&(~(0x08>>i4));
}
}
else if(cnt>zkb)
{
if(mode==0)
{
led=led|(1<<i1);
}
else if(mode==1)
{
led=led|(0x80>>i2);
}
else if(mode==2)
{
led=led|(0x80>>i3);
led=led|(1<<i3);
}
else if(mode==3)
{
led=led|(0x10<<i4);
led=led|(0x08>>i4);
}
}
if(cnt>99)
cnt=0;
}
void Key_Proc(void)
{
if(Key_Slow_Flag) return;
Key_Slow_Flag=1;
if(S7==0) //控制是否启动流转
{
Delay2ms();
if(S7==0)
{
lz=~lz;
while(1)
{
if(S7==1)
{
Delay2ms();
if(S7==1)
break;
}
}
}
}
else if(S6==0)
{
Delay2ms();
if(S6==0)
{
count++;
if(count==1) //S6按下一次进入界面1且选中模式设置
{
jiemian=1;
temp=0;
}
else if(count==2) //S6按下两次进入界面1且选中流转时间设置
{
jiemian=1;
temp=1;
}
else //再次按下数码管熄灭,将设置的模式及流转时间赋值
{
jiemian=0;
mode=mode_set;
switch(mode)
{
case 0:lztime1=lztime_set;lztime=lztime1;break;
case 1:lztime2=lztime_set;lztime=lztime2;break;
case 2:lztime3=lztime_set;lztime=lztime3;break;
case 3:lztime4=lztime_set;lztime=lztime4;break;
}
count=0;
}
while(1)
{
if(S6==1)
{
Delay2ms();
if(S6==1)
break;
}
}
}
}
else if(S5==0&&jiemian==1)
{
Delay2ms();
if(S5==0)
{
if(temp==0)
{
if(mode_set<=2)
mode_set++;
}
else if(temp==1)
{
if(lztime_set<=1100)
lztime_set+=100;
}
while(1)
{
if(S5==1)
{
Delay2ms();
if(S5==1)
break;
}
}
}
}
else if(S4==0&&jiemian==1)
{
Delay2ms();
if(S4==0)
{
if(temp==0)
{
if(mode_set>=1)
mode_set--;
}
else if(temp==1)
{
if(lztime_set>=500)
lztime_set-=100;
}
while(1)
{
if(S4==1)
{
Delay2ms();
if(S4==1)
break;
}
}
}
}
if(S4==0&&jiemian!=1)
{
Delay2ms();
if(S4==0)
{
jiemian=2;
}
}
else if(S4==1&&jiemian==2)
{
Delay2ms();
if(S4==1)
{
jiemian=0;
}
}
}
void Data_Proc(void)
{
if(Data_Slow_Flag) return;
Data_Slow_Flag=1;
if(jiemian!=1) //当不处于设置界面时将流转时间写入EEPROM
{
lztime_h[0]=lztime1>>8;
lztime_h[1]=lztime2>>8;
lztime_h[2]=lztime3>>8;
lztime_h[3]=lztime4>>8;
lztime_l[0]=lztime1;
lztime_l[1]=lztime2;
lztime_l[2]=lztime3;
lztime_l[3]=lztime4;
AT24C02_Write(lztime_h,lztime_l,0,4);
}
AD_Trans();
if(ADC_num>=0&&ADC_num<64) //通过Rb2通过占空比不同设置四个亮度等级
{
liangdu_set=1;
zkb=25;
}
else if(ADC_num>=64&&ADC_num<128)
{
liangdu_set=2;
zkb=50;
}
else if(ADC_num>=128&&ADC_num<192)
{
liangdu_set=3;
zkb=75;
}
else if(ADC_num>=192&&ADC_num<=255)
{
liangdu_set=4;
zkb=100;
}
}
void Smg_Proc(void)
{
if(Smg_Slow_Flag) return;
Smg_Slow_Flag=1;
if(jiemian==0)
SmgOff();
else if(jiemian==1)
ConfigDisplay();
else if(jiemian==2)
LiangduDisplay();
}
void Led_Proc(void)
{
if(Led_Slow_Flag) return;
Led_Slow_Flag=1;
if(mode==0&&lz==0)
{
i1++;
if(i1==8)
i1=0;
}
else if(mode==1&&lz==0)
{
i2++;
if(i2==8)
i2=0;
}
else if(mode==2&&lz==0)
{
i3++;
if(i3==4)
i3=0;
}
else if(mode==3&&lz==0)
{
i4++;
if(i4==4)
i4=0;
}
}
void LedDisplay(u8 LED)
{
HC138(4);
P0=LED;
P2&=0x1F;
}
二、总结
本代码基本上实现了彩灯控制器的所有功能,但代码有点繁杂,希望大家可以给出改进建议,共同进步!