• 回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

RGB遥控C程序

写了个遥控RGB程序分享下,随便请教下高手怎么用单片机EEPROM写断电记忆
include    //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#define uint unsigned int
#define uchar unsigned char
sbit IR=P3^2;  //红外接口标志
unsigned char  irtime;//红外用全局变量
unsigned char eeprom_read(unsigned int addres);
bit LEDDirection=0;//LED控制方向0:渐亮1:渐灭
bit  kg_flag;
bit  zb_flag,irprosok,irok;
bit  m_flag;
bit  s_flag;
bit  f_flag;
bit irpro_ok,irok;
sbit ledr=P1^0;
sbit ledg=P1^2;
sbit ledb=P1^6;
sfr isp_data  =0xe2;
sfr isp_addrh =0xe3;
sfr isp_addrl =0xe4;
sfr isp_cmd   =0xe5;
sfr isp_trig  =0xe6;
sfr isp_contr =0xe7;
uchar temp1,ee_temp,ee_temp1;
uchar IRcord[4];
uchar irdata[33];
uchar pwm_r,pwm_g,pwm_b;
uchar pwmr,pwmg,pwmb,scw;
uint t;
void TIM0init(void)//定时器0初始化
{

  TMOD=0x12;//定时器0工作方式2,TH0是重装值,TL0是初值
  TH0=0x00; //重载值
  TL0=0x00; //初始化值
  ET0=1;    //开中断
  TR0=1;
  
}
void TIM1init(void)//定时器0初始化
{

  TMOD=0x12;//定时器0工作方式2,TH0是重装值,TL0是初值
  TH1=(65536-10)/256;
  TL1=(65536-10)%256; //初始化值
  EA=1; 
  ET1=1;    //开中断
  TR1=1;
  EX1=1;  
}
void EX0init(void)
{
 IT0 = 1;   //指定外部中断0下降沿触发,INT0 (P3.2)
 EX0 = 1;   //使能外部中断
 EA = 1;    //开总中断
}

   //eeprom擦除
//***********************************/
void eeprom_eares(unsigned int addres)//扇区擦除。
     {
   unsigned i;
      isp_addrl=addres;     //低位地址
      isp_addrh=addres>>8;  //高位地址
      isp_contr=0x01; 
      isp_contr=isp_contr|0x80; //设时间与充ISP操作。
      isp_cmd=0x03;         //扇区命命令
      isp_trig=0x46;        //触发
      isp_trig=0xb9;        //触发启动。
      for(i=0;i<3;i++);
      isp_addrl=0xff;
      isp_addrh=0xff;
      isp_contr=0x00;
      isp_cmd=0x00;
      isp_trig=0x00;
      }
/******************************************
   EEPROM写
*******************************************/
void eeprom_write(unsigned int addres,unsigned char write_data)
     {
   unsigned char i;
      isp_data=write_data;   //要写入的数据。
      isp_addrl=addres;     //低位地址
      isp_addrh=addres>>8;  //高位地址
      isp_contr=0x01; 
      isp_contr=isp_contr|0x80; //设时间与充ISP操作。
      isp_cmd=0x02;         //写命令
      isp_trig=0x46;        //触发
      isp_trig=0xb9;        //触发启动。
      for(i=0;i<3;i++);
      isp_addrl=0xff;
      isp_addrh=0xff;
      isp_contr=0x00;
      isp_cmd=0x00;
      isp_trig=0x00;     
       }
/**********************************************
   EEPROM读
***********************************************/
unsigned char eeprom_read(unsigned int addres)
     { 
   unsigned char i,z;
      isp_addrl=addres;    
      isp_addrh=addres>>8;  
      isp_contr=0x01; 
      isp_contr=isp_contr|0x80; 
      isp_cmd=0x01;         
      isp_trig=0x46;        
      isp_trig=0xb9;        
      for(i=0;i<3;i++);
      isp_addrl=0xff;
      isp_addrh=0xff;
      isp_contr=0x00;
      isp_cmd=0x00;
      isp_trig=0x00;
      z=isp_data;
      return(z);
      }
void Ircordpro(void)//红外码值处理函数
{ 
  unsigned char i, j, k;
  unsigned char cord,value;

  k=1;
  for(i=0;i<4;i++)      //处理4个字节
     {
      for(j=1;j<=8;j++) //处理1个字节8位
         {
          cord=irdata[k];
          if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差
             value|=0x80;
          if(j<8)
            {
             value>>=1;
            }
           k++;
         }
     IRcord[i]=value;
     value=0;     
     } 
     irpro_ok=1;//处理完毕标志位置1
}

void Ir_work(void)//红外键值散转程序
{temp1=eeprom_read(0x2000);
 	//temp1=isp_data;

 	//ee_temp=ee_temp1&0x0f;
       switch(temp1)//判断第三个数码值
             {
             case 0x07:{kg_flag=1;
      
       	
       f_flag=0;
       s_flag=0;
       zb_flag=0;
       
       m_flag=0;
       
       pwm_r=0;  
       pwm_g=0;
       pwm_b=0;

       
}break;//1 显示相应的按键值
             case 0x06:{kg_flag=0;
        
}break;//2
             case 0x04:{if(kg_flag==1)
         {if((m_flag==0)&&(s_flag==0)&&(f_flag==0)
  &&(zb_flag==0))
         { 
          if(pwm_r<180)
          {pwm_r=pwm_r+20;}
          if(pwm_b<180)
          {pwm_b=pwm_b+20;} 
          if(pwm_g<180)
          {pwm_g=pwm_g+20;} }
          }
}break;//3
             case 0x05:{if(kg_flag==1)
         {if((m_flag==0)&&(s_flag==0)&&(f_flag==0)
  &&(zb_flag==0))
  
          {if((pwm_r>0)&&(pwm_r!=199))
          {pwm_r=pwm_r-20;}
          if((pwm_b>0)&&(pwm_b!=199))
          {pwm_b=pwm_b-20;} 
          if((pwm_g>0)&&(pwm_g!=199))
          {pwm_g=pwm_g-20;}}
          
          }
}break;//4
             case 0x09:   
         {if(kg_flag==1)
          {flag();

        pwm_r=0; 
         pwm_g=199;
          pwm_b=199;
         } 
break;}//5
             case 0x08:{if(kg_flag==1)
         {flag();

          pwm_r=199; 
          pwm_b=199;
          pwm_g=0;} 
break;}//6
             case 0x0A:{if(kg_flag==1)
         {pwm_r=199; 
          pwm_b=0;
          pwm_g=199;
      flag();}
    break;}//7
             case 0x0B:{if(kg_flag==1)
         {pwm_r=0; 
          pwm_b=0;
          pwm_g=0;
       flag();}
break;}//8
             case 0x0D:{if(kg_flag==1)
         {pwm_r=0; 
          pwm_b=199;
          pwm_g=160;
       flag();} 
break;}
        case 0x0C:{if(kg_flag==1)
         {pwm_r=199; 
          pwm_b=160;
          pwm_g=0;
       flag();} 
break;}
       case 0x0E:{if(kg_flag==1)
         {pwm_r=160; 
          pwm_b=0;
          pwm_g=199;
      flag();} 
         break;}
       case 0x15:{if(kg_flag==1)
         {pwm_r=0; 
          pwm_b=199;
          pwm_g=120;
       flag();} 
break;}
        case 0x14:{if(kg_flag==1)
         {pwm_r=199; 
          pwm_b=120;
          pwm_g=0;
      flag();} 
break;}
        case 0x16:{if(kg_flag==1)
         {pwm_r=120; 
          pwm_b=0;
          pwm_g=199;
      flag();} 
break;}
         case 0x19:{if(kg_flag==1)
         {pwm_r=0; 
          pwm_b=199;
          pwm_g=80;
      flag();} 
break;}
         case 0x18:{if(kg_flag==1)
         {pwm_r=199; 
          pwm_b=80;
          pwm_g=0;
      flag();} 
break;} case 0x1A:{if(kg_flag==1)
         {pwm_r=80; 
          pwm_b=0;
          pwm_g=199;
        flag();} 
break;}
        case 0x11:{if(kg_flag==1)
         {pwm_r=0; 
          pwm_b=199;
          pwm_g=0;
       flag();} 
break;}
        case 0x10:{if(kg_flag==1)
         {pwm_r=199; 
          pwm_b=0;
          pwm_g=0;
      flag();} 
break;}
  case 0x12:{if(kg_flag==1)
         {pwm_r=0; 
          pwm_b=0;
          pwm_g=199;
      flag();}
 break;}
 case 0x13:{if(kg_flag==1)
         {pwm_r=0; 
          pwm_b=0;
          pwm_g=0;
         f_flag=0;
       s_flag=0;
       zb_flag=0;
       
       m_flag=1;} 
break;}
       case 0x1B:{if(kg_flag==1)
         {pwm_r=0; 
          pwm_b=0;
          pwm_g=0;
         f_flag=0;
       s_flag=0;
       zb_flag=1;
       
       m_flag=0;} 
break;}
        case 0x17:{if(kg_flag==1)
         {pwm_r=0; 
          pwm_b=0;
          pwm_g=0;
         f_flag=0;
       s_flag=1;
       zb_flag=0;
       
       m_flag=0;} 
break;}
     case 0x0F:{if(kg_flag==1)
         {pwm_r=0; 
          pwm_b=0;
          pwm_g=0;
         f_flag=1;
       s_flag=0;
       zb_flag=0;
       
       m_flag=0;
              } 
break;}
       
       

             }     
             

          irpro_ok=0;//处理完成标志

  }
void main(void)
{
    EX0init(); //初始化外部中断
    TIM0init();//初始化定时器
    TIM1init();
    //取位码 第一位数码管选通,即二进制1111 1110
    

 while(1)//主循环
   {
    if(irok)                        //如果接收好了进行红外处理
      {   
       Ircordpro();
        irok=0;
      if(IRcord [2]>=0x04)
       {if(IRcord [2]<=0x1b)
	 	{
		  
	 	  temp1=IRcord[2];

		  eeprom_eares(0x2000);				     //STC_EEROM_0X2000 temp1
 		 eeprom_write(0x2000,temp1);

		  temp1=eeprom_read(0x2000);
 		  //temp1=isp_data;
		 // ee_temp=ee_temp1&0x0f;
		
		}
	else
		{
		 temp1=eeprom_read(0x2000);
		 //temp1=isp_data;
         //ee_temp=ee_temp1&0x0f;
}
		}
      }
    if(irpro_ok)                   //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等
      {
       Ir_work();
        }
   }
}
void tim0_isr (void) interrupt 1 using 1
{ 
  irtime++;  //用于计数2个下降沿之间的时间
}
void tim1_isr (void) interrupt 3
{TH1=(65536-10)/256;
  TL1=(65536-10)%256;
  TR1=0;
  scw++;
if(kg_flag==1) 
 { if(m_flag==1)
 { if(scw==200)//20ms时间到
  { 
   scw=0;
    t++;

if((t>0)&&(t<400))
    {rjb();}
 if((t>400)&&(t<800))
    {gjb();}
 if((t>800)&&(t<1200))
    {bjb();}
 if((t>1200)&&(t<1600))
    {rjb();gjb();}
  if((t>1600)&&(t<2000))
    {rjb();bjb();}
if((t>2000)&&(t<2400))
    {gjb();bjb();}
if((t>2400)&&(t<2800))
    {rjb();gjb();bjb();}

   if(t>2800){t=0;}      

   }
         
       if(pwm_r>0){ledr=0;pwm_r--;}
      else{ledr=1;}
      if(pwm_g>0){ledg=0;pwm_g--;}
      else{ledg=1;}
      if(pwm_b>0){ledb=0;pwm_b--;}
      else{ledb=1;}
    }
 if(f_flag==1)
{ 
sjb();
   }
if(s_flag==1)
{
    fjb();
}
 if(zb_flag==1)
{if(scw==200)//20ms时间到
  { 
   scw=0;
    


    {rjb();bjb();gjb();}
  }
  
       if(pwm_r>0){ledr=0;pwm_r--;}
      else{ledr=1;}
      if(pwm_g>0){ledg=0;pwm_g--;}
      else{ledg=1;}
      if(pwm_b>0){ledb=0;pwm_b--;}
      else{ledb=1;}
}
 if((m_flag==0)&&(s_flag==0)&&(f_flag==0)
  &&(zb_flag==0))
  {if(scw==200)//20ms时间到
  { 
   scw=0;
}
 if(scw<=pwm_r)
{
  ledr=1;
}
else {ledr=0;}
if(scw<=pwm_g)
{
  ledg=1;
}
else {ledg=0;}
if(scw<=pwm_b)
{
  ledb=1;
}
else {ledb=0;}

  } 
   
   
 }
else{ledr=1;ledg=1;ledb=1;}
TR1=1;       
}
void EX0_ISR (void) interrupt 0 //外部中断0服务函数
{
    static unsigned char  i;             //接收红外信号处理
    static bit startflag;                //是否开始处理标志位

    if(startflag)                         
    {
        if(irtime<63&&irtime>=33)//引导码 TC9012的头码,9ms+4.5ms
        i=0;
        irdata[i]=irtime;//存储每个电平的持续时间,用于以后判断是0还是1
        irtime=0;
        i++;
        if(i==33)
        {
            irok=1;
            i=0;
        }
    }
    else
    {
        irtime=0;
        startflag=1;
    }
}




全部回复(3)
正序查看
倒序查看
sunnke
LV.1
2
2016-05-28 14:49
**此帖已被管理员删除**
0
回复
ae10257
LV.5
3
2016-10-26 09:32
辛苦 了。。。。。。。。。。。。
0
回复
2017-02-18 15:32
要有掉电检测电路,当检测到AC220已经断开,利用电路中电解电容的存电的那点时间存储你所需要记忆的寄存器
0
回复