单片机
返回首页

最牛的LED遥控控制器---调整无闪烁

2015-07-20 来源:51hei

/*一款遥控LED控制器,所有功能均由遥控器控制,

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

一、原理图:

二、参考图片:

三、参考程序:下载地址:http://www.51hei.com/f/ledtt.rar
#include
#include
/*********定义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(tempc(9500)) continue;//引导脉冲低电平9000
  temp=High();
  if(tempc(5000)) continue;//引导脉冲高电平4500
  for(i=0;i<4;i++) //4个字节
  {
   for(j=0;j<8;j++) //每个字节8位
   {
    temp=Low();
    if(tempc(800)) goto restart;
    temp=High();
    if(tempc(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  LED=0;//如果计数器变量小于PWM时,LED亮 
 else
 LED=1;
 
}
/****************************************/ 
/***************定时器0部分**************/
/****************************************/
void zhong1() interrupt 1//用来产生遥控解码计时
{
 TL0=0;
 TH0=0;

 

进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 家用电源无载自动断电装置的设计与制作

  • PIC单片机控制的遥控防盗报警器电路

  • 短波AM发射器电路设计图

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 如何构建一个触摸传感器电路

  • 基于TDA2003的简单低功耗汽车立体声放大器电路

    相关电子头条文章