专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

最牛的LED遥控控制器---调整无闪烁(C语言)

作者:佚名   来源:本站原创   点击数:  更新时间:2012年05月04日   【字体:

/*一款遥控LED控制器,所有功能均由遥控器控制,
它主要有如下功能:1、遥控调光2、旋钮调光 3、
开关机功能 4、渐变 5、跳变 6、循环变化(渐
变、跳变等)7、变化速度可调整,并断电能记忆*/

一、原理图:

二、参考图片:



三、参考程序:下载地址:http://www.51hei.com/f/ledtt.rar
#include <reg51.h>
#include <intrins.h>
/*********定义EEPROM寄存器地址*********/
sfr DATA=0xC2;//数据寄存器
sfr ADDRH=0xC3;//地址寄存器高八位
sfr ADDRL=0xC4;//地址寄存器低八位
sfr CMD=0xC5;//命令模式寄存器
sfr TRIG=0xC6;//命令触发寄存器
sfr CONTR=0xC7;//控制寄存器
/*********定义AD转换寄存器地址*********/
sfr ADC_RES=0xbd;//AD转换结果寄存器
sfr ADC_C=0xbc;//AD转换控制寄存器
sfr P1ASF=0x9d;
#define c(x) (x*120000/120000)
#define uchar unsigned char
#define uint unsigned int
#define dengji 2//手动调光等级定义

sbit IR=P3^3;
sbit LED=P3^0;

uint temp;//红外线解码变量
uchar i;
uchar j;

char dat=0;//PWM变量
uchar num;//PWM定时器变量
 
uint flashnum;//渐变跳变定时器变量
uchar IRBUF[4]; //用于保存解码结果
uchar shudu=1;

bit power=1;//电位器调光与遥控调光切换标志位
bit flag;//遥控开关机切换标志位
bit flash;//跳变切换标志位
bit jian;//渐变切换标志位
bit zeng;//综合变化变量

/***************************************************************/
/****************************EEPROM子函数***********************/
/***************************************************************/
/****************************************/
/**********EEPROM读数据子函数************/
/****************************************/
uchar read(uint add)
{
 CONTR=0x82;
 CMD=0x01;
 ADDRH=(add>>=8);
 ADDRL=add&(0x00ff);
 TRIG=0x5a;
 TRIG=0xa5;
  _nop_();
 CONTR=0x00;
 TRIG=0X00;
 return DATA;
}
/****************************************/
/**********EEPROM写数据子函数************/
/****************************************/
void write(uint add,uchar vale)
{
 CONTR=0x82;
 CMD=0X02;
 ADDRH=(add>>=8);
 ADDRL=add&(0x00ff);
 DATA=vale;
 TRIG=0x5a;
 TRIG=0xa5;
  _nop_();
 CONTR=0x00;
 TRIG=0X00;
}
/****************************************/
/**********EEPROM擦除数据子函数**********/
/****************************************/
void sector(uint add)
{
 CONTR=0x82;
 CMD=0x03;
 ADDRH=(add>>=8);
 ADDRL=add&(0x00ff);
 TRIG=0x5a;
 TRIG=0xa5;
  _nop_();
 CONTR=0x00;
 TRIG=0X00;
}

/****************************************/
/***************AD转换部分***************/
/****************************************/
uint adzhang1()
{
 uint zona;
 zona=0;
 ADC_C=0;//控制寄存器清0
 P1ASF=0;//IO口控制寄存器清0
 ADC_C|=0x80;//打开控制寄存器电源
 P1ASF|=0x80;//设置P1.7为AD输入口
 ADC_C|=0xe7;//打开控制寄存器电源,并选择P1.7为AD输入端
 //以上是初始化程序
 ADC_RES=0;//转换结果寄存器清0
 ADC_C|=0x08;//开始转换
 //delay1(2);
 while((ADC_C&0x10)==0);//判断结束标志位是否为不为1?若不为1则等待
 ADC_C&=0xe7;//清除等待标志位
 zona=ADC_RES*0.392156;//将255个等级变为100个等级 等级=100/255=0.392156
 if(zona<1)
 zona=0;
 return zona; 
}


/****************************************/
/***********遥控解码低电平检测***********/
/****************************************/
uint Low()
{
 TL0=0;
 TH0=0;
 TR0=1;
 while(!IR&&(TH0&0x80)==0);              
 TR0=0;         
 return TH0*256+TL0;
}
/****************************************/
/***********遥控解码高电平检测***********/
/****************************************/
uint High()
{
 TL0=0;
 TH0=0;
 TR0=1;
 while(IR&&(TH0&0x80)==0);
 TR0=0;
 return TH0*256+TL0;
}
/****************************************/
/************AD转换处理子函数************/
/****************************************/
void ADzhuan()
{
 if(!power)//如果此标志位为1,则执行AD转换
 dat = adzhang1();
}
/****************************************/
/**************LED闪烁子函数*************/
/****************************************/
void LEDflash()
{
 if(flash==1)//如果此标志位为1,则执行闪烁程序
 {
  if(flashnum>=(shudu*800))//定时器时间到了吗?
  {
   bit kl;//定义一个标志位
   flashnum=0;//到了就清0
   kl=~kl;//将它取反,以便形成亮灭变化
   if(kl==0)//如果为1,就让LED亮
   dat=100;//等级为100,就最亮
   else//否则灭
   dat=0;//等级为0就为熄灭
  }
 }
}
/****************************************/
/**************LED渐变子函数*************/
/****************************************/
void LEDjian()
{
 if(jian==1)//如果此标志位为1,则执行渐变程序
 {
  bit a;//定义一个标志位
  if(flashnum>=(shudu*100))//定时器时间到了吗?
  {
   flashnum=0;//到了就清0
   if(a==0)//如果为0就执行渐亮子函数
   {
    dat++;//时间到了就自动加1
    if(dat>100)//如果加到大于100
    {
     a=1;//将标志位变为1
     dat=100;//将变量变为最亮状态
    }
   }
   else//如果a为1就执行渐暗子函数
   {
    dat--;//时间到了就自动减1
    if(dat<(0-1))//如果减到小于0了,就将它变为0
    {
     a=0;//标志位变为0,以便执行渐亮子函数
     dat=0;
    }
   }
  }
 }
}

/**********************************************/
/**************LED综合子函数*************/
/**********************************************/
void zonghe()
{
 uchar ci,ii;
 bit a,fla;//定义一个标志位
 bit kl;//定义一个标志位
 if(zeng==1)
 {
  if(flashnum>=(shudu*100))//定时器时间到了吗?
  {
   flashnum=0;
   ii++;
   if(ii>7)
   {
    ii=0;
    if(fla==1)
    {
 
     kl=~kl;//将它取反,以便形成亮灭变化
     if(kl==0)//如果为1,就让LED亮
     dat=100;//等级为100,就最亮
     else//否则灭
     dat=0;//等级为0就为熄灭
     ci++;
     if(ci>=30)
     {
      ci=0;
      fla=0;
     }
    }
   }
   if(fla==0)
   {
    if(a==0)//如果为0就执行渐亮子函数
    {
     dat++;//时间到了就自动加1
     if(dat>100)//如果加到大于100
     {
      a=1;//将标志位变为1
      dat=100;//将变量变为最亮状态
     }
    }
    else//如果a为1就执行渐暗子函数
    {
     dat--;//时间到了就自动减1
     if(dat<(0-1))//如果减到小于0了,就将它变为0
     {
      a=0;//标志位变为0,以便执行渐亮子函数
      dat=0;
      ci++;
      if(ci>=4)
      {
       fla=1;
       ci=0;
      }
     }
    }
   }
  }
 }   
}
/****************************************/
/************遥控解码核心部分************/
/****************************************/
void decode()
{
 while(1)
 {
  restart:
  while(IR)/******空闲时处理其它的事情,即当遥控没有按下时,处理其它事情******/
  {
   ADzhuan();
   LEDflash();
   LEDjian();
   zonghe();
  }/******空闲时处理其它的事情,即当遥控没有按下时,处理其它事情******/
  temp=Low();
  if(temp<c(8500) || temp>c(9500)) continue;//引导脉冲低电平9000
  temp=High();
  if(temp<c(4000) || temp>c(5000)) continue;//引导脉冲高电平4500
  for(i=0;i<4;i++) //4个字节
  {
   for(j=0;j<8;j++) //每个字节8位
   {
    temp=Low();
    if(temp<c(200) || temp>c(800)) goto restart;
    temp=High();
    if(temp<c(200) || temp>c(2000)) goto restart;
    IRBUF[i]>>=1;
    if(temp>c(1120))
    {
     IRBUF[i]|=0x80;
    
    }
   }
  }
  return;
 }

}
/****************************************/
/*********遥控解码键值处理子函数********/
/****************************************/
void numzhi()
{
 switch(IRBUF[2])//判断数组2键值注:因为只有第2组才是按键码,所以判断数组2

 {
/****************如果此键按下了,则遥控开关机****************11111**/
  case 0x58:
  flag=~flag;
  if(flag==0)
  dat=100;//dat为100时最亮
  else
  dat=0;//为0时熄灭
  jian=0;//将渐变变量置0,以防止渐变子程序动作
  flash=0;//将闪烁变量置0,以防止跳变子程序动作
  zeng=0;//将综合程序变量置0,以防止综合子程序动作
  break;

/***如果此键按下了,每按一次亮度会增加1个等级 共为100等级**22222**/
  case 0x1b:if(flag==0)
  {
  
   dat+=dengji;
   if(dat>=100)
   dat=100;
   jian=0;//将渐变变量置0,以防止渐变子程序动作
   flash=0;//将闪烁变量置0,以防止跳变子程序动作
   zeng=0;//将综合程序变量置0,以防止综合子程序动作
  }
  break;

/***如果此键按下了,每按一次亮度会减小1个等级 共为100等级**33333**/
  case 0x1f:if(flag==0)
  {
   dat-=dengji;
   if(dat<=(0-1))
   dat=0;
   jian=0;//将渐变变量置0,以防止渐变子程序动作
   flash=0;//将闪烁变量置0,以防止跳变子程序动作
   zeng=0;//将综合程序变量置0,以防止综合子程序动作

  }
  break;

/***每按一次跳变和渐变速度会减小1个等级 共为60等级,并写入改变的数值,以便开机记忆**44444**/
  case 0x0f:if(flag==0)
  {
   shudu-=1;
   if(shudu<=1)
   shudu=1;
   sector(0x0200);//擦除EEPROM,擦除地址为0X200
   write(0x0200,shudu);//写入EEPROM,写入地址为0X200
  }
  break;

/***每按一次跳变和渐变速度会增加1个等级 共为60等级,并写入改变的数值,以便开机记忆**55555**/
  case 0x1a:if(flag==0)
  {
   shudu+=1;
   if(shudu>=30)
   shudu=30;
   sector(0x0200);//擦除EEPROM,擦除地址为0X200
   write(0x0200,shudu);//写入EEPROM,写入地址为0X200
  }
  break;

/*********如果此键按下了,则执行手动调光与遥控切换,两者不能同时工作***********66666**/
  case 0x1e:if(flag==0)
  {
   flash=1;//进入遥控后,让它先进入关机状态
   dat=0;
   power=~power;//手动调光与遥控切换标志位
   jian=0;//将渐变变量置0,以防止渐变子程序动作
   flash=0;//将闪烁变量置0,以防止跳变子程序动作
   zeng=0;//将综合程序变量置0,以防止综合子程序动作
  }
  break;

/***********************如果此键按下了,则执行渐变子函数*******************77777**/
  case 0x0e:if(flag==0)
  {
   jian=~jian;
   dat=0;
   flash=0;//将闪烁变量置0,以防止跳变子程序动作
   zeng=0;//将综合程序变量置0,以防止综合子程序动作
  }
  break;
/***********************如果此键按下了,则执行跳变子函数*******************88888**/
  case 0x19:if(flag==0)
  {
   flash=~flash;
   dat=0;
   jian=0;//将渐变变量置0,以防止渐变子程序动作
   zeng=0;//将综合程序变量置0,以防止综合子程序动作
  }
  break;
  case 0x1d:if(flag==0)
  {
   zeng=~zeng;
   dat=0;
  }
  break;
  
 }
}
/****************************************/
/***************主程序部分***************/
/****************************************/
main()
{
 TMOD=0x11;//设置定时器0定时器1工作方式为1的状态下工作
 EA=1;

 TR0=1;//设置定时器0
 ET0=1;
 TL0=0;
 TH0=0;

 TR1=1;//设置定时器1
 ET1=1;
 TH1=(65536-20)/256; //定时器初值
 TL1=(65536-20)%256;
 shudu=read(0x0200);//开机读取EEPROM里面的速度变量shudu,从而形成断电记忆功能
 while(1)
 {
  decode();//调用解码子函数
  numzhi();//调用遥控键值子函数
 }
}
/****************************************/
/***************定时器1部分**************/
/****************************************/
void zhong3() interrupt 3 //利用PWM来改变亮度
{

 TH1=(65536-20)/256; //定时器0设定约1000us中断一次
 TL1=(65536-20)%256;
 num++;//PWM定时器
 flashnum++;//闪烁渐变变量
 if(num>=100)//此PWM等级为100,它由变量num与dat完成
 num=0;
 if(num<dat)
 LED=0;//如果计数器变量小于PWM时,LED亮
 else
 LED=1;
 
}
/****************************************/
/***************定时器0部分**************/
/****************************************/
void zhong1() interrupt 1//用来产生遥控解码计时
{
 TL0=0;
 TH0=0;

 

关闭窗口

相关文章