專注電子技術學習與研究
當前位置:單片機教程網(wǎng) >> MCU設計實例 >> 瀏覽文章

最牛的LED遙控控制器---調(diào)整無閃爍(C語言)

作者:佚名   來源:本站原創(chuàng)   點擊數(shù):  更新時間:2012年05月04日   【字體:

/*一款遙控LED控制器,所有功能均由遙控器控制,
它主要有如下功能:1、遙控調(diào)光2、旋鈕調(diào)光 3、
開關機功能 4、漸變 5、跳變 6、循環(huán)變化(漸
變、跳變等)7、變化速度可調(diào)整,并斷電能記憶*/

一、原理圖:

二、參考圖片:



三、參考程序:下載地址:http://www.torrancerestoration.com/f/ledtt.rar
#include <reg51.h>
#include <intrins.h>
/*********定義EEPROM寄存器地址*********/
sfr DATA=0xC2;//數(shù)據(jù)寄存器
sfr ADDRH=0xC3;//地址寄存器高八位
sfr ADDRL=0xC4;//地址寄存器低八位
sfr CMD=0xC5;//命令模式寄存器
sfr TRIG=0xC6;//命令觸發(fā)寄存器
sfr CONTR=0xC7;//控制寄存器
/*********定義AD轉(zhuǎn)換寄存器地址*********/
sfr ADC_RES=0xbd;//AD轉(zhuǎn)換結果寄存器
sfr ADC_C=0xbc;//AD轉(zhuǎn)換控制寄存器
sfr P1ASF=0x9d;
#define c(x) (x*120000/120000)
#define uchar unsigned char
#define uint unsigned int
#define dengji 2//手動調(diào)光等級定義

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;//電位器調(diào)光與遙控調(diào)光切換標志位
bit flag;//遙控開關機切換標志位
bit flash;//跳變切換標志位
bit jian;//漸變切換標志位
bit zeng;//綜合變化變量

/***************************************************************/
/****************************EEPROM子函數(shù)***********************/
/***************************************************************/
/****************************************/
/**********EEPROM讀數(shù)據(jù)子函數(shù)************/
/****************************************/
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寫數(shù)據(jù)子函數(shù)************/
/****************************************/
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擦除數(shù)據(jù)子函數(shù)**********/
/****************************************/
void sector(uint add)
{
 CONTR=0x82;
 CMD=0x03;
 ADDRH=(add>>=8);
 ADDRL=add&(0x00ff);
 TRIG=0x5a;
 TRIG=0xa5;
  _nop_();
 CONTR=0x00;
 TRIG=0X00;
}

/****************************************/
/***************AD轉(zhuǎn)換部分***************/
/****************************************/
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;//轉(zhuǎn)換結果寄存器清0
 ADC_C|=0x08;//開始轉(zhuǎn)換
 //delay1(2);
 while((ADC_C&0x10)==0);//判斷結束標志位是否為不為1?若不為1則等待
 ADC_C&=0xe7;//清除等待標志位
 zona=ADC_RES*0.392156;//將255個等級變?yōu)?00個等級 等級=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轉(zhuǎn)換處理子函數(shù)************/
/****************************************/
void ADzhuan()
{
 if(!power)//如果此標志位為1,則執(zhí)行AD轉(zhuǎn)換
 dat = adzhang1();
}
/****************************************/
/**************LED閃爍子函數(shù)*************/
/****************************************/
void LEDflash()
{
 if(flash==1)//如果此標志位為1,則執(zhí)行閃爍程序
 {
  if(flashnum>=(shudu*800))//定時器時間到了嗎?
  {
   bit kl;//定義一個標志位
   flashnum=0;//到了就清0
   kl=~kl;//將它取反,以便形成亮滅變化
   if(kl==0)//如果為1,就讓LED亮
   dat=100;//等級為100,就最亮
   else//否則滅
   dat=0;//等級為0就為熄滅
  }
 }
}
/****************************************/
/**************LED漸變子函數(shù)*************/
/****************************************/
void LEDjian()
{
 if(jian==1)//如果此標志位為1,則執(zhí)行漸變程序
 {
  bit a;//定義一個標志位
  if(flashnum>=(shudu*100))//定時器時間到了嗎?
  {
   flashnum=0;//到了就清0
   if(a==0)//如果為0就執(zhí)行漸亮子函數(shù)
   {
    dat++;//時間到了就自動加1
    if(dat>100)//如果加到大于100
    {
     a=1;//將標志位變?yōu)?
     dat=100;//將變量變?yōu)樽盍翣顟B(tài)
    }
   }
   else//如果a為1就執(zhí)行漸暗子函數(shù)
   {
    dat--;//時間到了就自動減1
    if(dat<(0-1))//如果減到小于0了,就將它變?yōu)?
    {
     a=0;//標志位變?yōu)?,以便執(zhí)行漸亮子函數(shù)
     dat=0;
    }
   }
  }
 }
}

/**********************************************/
/**************LED綜合子函數(shù)*************/
/**********************************************/
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就執(zhí)行漸亮子函數(shù)
    {
     dat++;//時間到了就自動加1
     if(dat>100)//如果加到大于100
     {
      a=1;//將標志位變?yōu)?
      dat=100;//將變量變?yōu)樽盍翣顟B(tài)
     }
    }
    else//如果a為1就執(zhí)行漸暗子函數(shù)
    {
     dat--;//時間到了就自動減1
     if(dat<(0-1))//如果減到小于0了,就將它變?yōu)?
     {
      a=0;//標志位變?yōu)?,以便執(zhí)行漸亮子函數(shù)
      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個字節(jié)
  {
   for(j=0;j<8;j++) //每個字節(jié)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;
 }

}
/****************************************/
/*********遙控解碼鍵值處理子函數(shù)********/
/****************************************/
void numzhi()
{
 switch(IRBUF[2])//判斷數(shù)組2鍵值注:因為只有第2組才是按鍵碼,所以判斷數(shù)組2

 {
/****************如果此鍵按下了,則遙控開關機****************11111**/
  case 0x58:
  flag=~flag;
  if(flag==0)
  dat=100;//dat為100時最亮
  else
  dat=0;//為0時熄滅
  jian=0;//將漸變變量置0,以防止?jié)u變子程序動作
  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,以防止?jié)u變子程序動作
   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,以防止?jié)u變子程序動作
   flash=0;//將閃爍變量置0,以防止跳變子程序動作
   zeng=0;//將綜合程序變量置0,以防止綜合子程序動作

  }
  break;

/***每按一次跳變和漸變速度會減小1個等級 共為60等級,并寫入改變的數(shù)值,以便開機記憶**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等級,并寫入改變的數(shù)值,以便開機記憶**55555**/
  case 0x1a:if(flag==0)
  {
   shudu+=1;
   if(shudu>=30)
   shudu=30;
   sector(0x0200);//擦除EEPROM,擦除地址為0X200
   write(0x0200,shudu);//寫入EEPROM,寫入地址為0X200
  }
  break;

/*********如果此鍵按下了,則執(zhí)行手動調(diào)光與遙控切換,兩者不能同時工作***********66666**/
  case 0x1e:if(flag==0)
  {
   flash=1;//進入遙控后,讓它先進入關機狀態(tài)
   dat=0;
   power=~power;//手動調(diào)光與遙控切換標志位
   jian=0;//將漸變變量置0,以防止?jié)u變子程序動作
   flash=0;//將閃爍變量置0,以防止跳變子程序動作
   zeng=0;//將綜合程序變量置0,以防止綜合子程序動作
  }
  break;

/***********************如果此鍵按下了,則執(zhí)行漸變子函數(shù)*******************77777**/
  case 0x0e:if(flag==0)
  {
   jian=~jian;
   dat=0;
   flash=0;//將閃爍變量置0,以防止跳變子程序動作
   zeng=0;//將綜合程序變量置0,以防止綜合子程序動作
  }
  break;
/***********************如果此鍵按下了,則執(zhí)行跳變子函數(shù)*******************88888**/
  case 0x19:if(flag==0)
  {
   flash=~flash;
   dat=0;
   jian=0;//將漸變變量置0,以防止?jié)u變子程序動作
   zeng=0;//將綜合程序變量置0,以防止綜合子程序動作
  }
  break;
  case 0x1d:if(flag==0)
  {
   zeng=~zeng;
   dat=0;
  }
  break;
  
 }
}
/****************************************/
/***************主程序部分***************/
/****************************************/
main()
{
 TMOD=0x11;//設置定時器0定時器1工作方式為1的狀態(tài)下工作
 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();//調(diào)用解碼子函數(shù)
  numzhi();//調(diào)用遙控鍵值子函數(shù)
 }
}
/****************************************/
/***************定時器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;//如果計數(shù)器變量小于PWM時,LED亮
 else
 LED=1;
 
}
/****************************************/
/***************定時器0部分**************/
/****************************************/
void zhong1() interrupt 1//用來產(chǎn)生遙控解碼計時
{
 TL0=0;
 TH0=0;

 

關閉窗口

相關文章