用遥控器控制pwm信号占空比的幅度。
//****************************************
//定义 STC12C2052 系列 PCA/PWM寄存器列表。
sfr   CCON =0xd8;
sfr   CMOD =0xd9;
sfr   CCAPM0 =0xda;
sfr   CCAPM1 =0xdb;
sfr   CCAPM2 =0xdc;
sfr   CCAPM3 =0xdd;
sfr   CL   =0xe9;
sfr   CH   =0xf9;
sfr   CCAP0L =0xea;
sfr   CCAP0H =0xfa;
sfr   CCAP1L =0xeb;
sfr   CCAP1H =0xfb;
sfr   CCAP2L =0xec;
sfr   CCAP2H =0xfc;
sfr   CCAP3L =0xed;
sfr   CCAP3H =0xfd;
sfr   PCA_PWM0=0xf2;
sfr   PCA_PWM1=0xf3;
sfr   PCA_PWM2=0xf4;
sfr   PCA_PWM3=0xf5;
//*****************************************
//***************************
sbit CR   =CCON^6;
//***************************
unsigned char PWM_ZKB;   //设置外部变量,对PWM占空比进行微调改变。
//*******************************
//关于红外线遥控器的一些定义。
#define uchar     unsigned char
#define uint        unsigned int 
#define         IR_RE P3_2
bit         k=0;                                            //红外解码判断标志位,为0则为有效信号,为1则为无效
uchar        date[4]={0,0,0,0};                              //date数组为存放地址原码,反码,数据原码,反码 
//*******************************
/*--------------------------延时1ms程子程序-----------------------*/
delay1000()
{
uchar i,j;
i=200;
do{j=13;
   do{j--;}
   while(j);
   i--;
   }while(i);
}
//****************************************
/*---------------------------延时882us子程序-----------------------*/
delay882()
{
uchar i,j;
i=84;
do{j=30;
        do{j--;}
        while(j);
        i--;
        }while(i);
}
/*--------------------------延时2400us程子程序-----------------------*/
delay2400()                                          
{
uchar i,j;
i=200;
do{j=34;
        do{j--;}
        while(j);
        i--;
        }while(i);
}
//**************************************************************
//**************************************************************
/*----------------------------------------------------------*/
/*-----------------------红外解码程序(核心)-----------------*/
/*----------------------------------------------------------*/
void IR_decode()
{
        uchar        i,j;
        while(IR_RE==0);
        delay2400();
        if(IR_RE==1)                                     //延时2.4ms后如果是高电平则是新码
        {
            delay1000();
            delay1000();
        for(i=0;i<4;i++)
        {
          for(j=0;j<8;j++)
          {
                 while(IR_RE==0);                             //等待地址码第1位高电平到来
                 delay882();                               //延时882us判断此时引脚电平
           ///CY=IR_RE;
                 if(IR_RE==0)
                 {       
           date[i]>>=1;
           date[i]=date[i]|0x00;     
                 }
                 else if(IR_RE==1)
           {
           delay1000();
           date[i]>>=1;
           date[i]=date[i]|0x80;
           }
        }                                          //1位数据接收结束
           }                                             //32位二进制码接收结束
         } 
}
//*****************************************************************
//********************************************************************
/*------------------------外部中断0程序-------------------------*/
/*------------------主要用于处理红外遥控键值--------------------*/
void int0() interrupt 0
{ 
         uchar i;
         k=0;
         EX0=0;                                      //检测到有效信号关中断,防止干扰
         for(i=0;i<4;i++)
         { 
           delay1000();
        if(IR_RE==1){k=~k;}                         //刚开始为9ms的引导码.
         }
         if(k==0)
         { 
//         EX0=0;                                      //检测到有效信号关中断,防止干扰
         IR_decode();                                //如果接收到的是有效信号,则调用解码程序
   }
         delay2400();
         delay2400();
         delay2400();
        EX0=1;                                       //开外部中断,允许新的遥控按键
}
//*********************************************************************
//***************************
//PCA计数器初始化程序。
void PCA_INIT()
{
CMOD=0x80; //PCA在空闲模式下停止。PCA时钟模式为fose/12.禁止PCA计数器溢出中断。 
CCON=0x00; //禁止PCA计数器工作,清除中断标志、计数器溢出标志。
CL =0x00; //清0计数器。
CH =0x00;
//---------------
//设置模块0为8位PWM输出模式。
CCAPM0 =0x42;
PCA_PWM0=0x00;
//----------------
CR=1; //将PCA计数器打开。
}
//**************************
//******************************
//主函数。
void main()
{
SP=0x60;
PCA_INIT(); //PCA计数器的初始化。
EX0=1;   //开外部中断。
EA=1;
//----------------------------------
//用红外线遥控器的若干按键微调PWM信号占空比。
while(1)
{
if(date[2]==0x0c) //确定一个固定占空比的PWM信号。
{
         delay2400();
   PWM_ZKB =0x80;
   CCAP0H =PWM_ZKB;
   date[2] =0xff;
}
if(date[2]==0x19)   //微调PWM占空比。
{
         delay2400();
   if(PWM_ZKB>0xf0)
   {
   PWM_ZKB=0xf9;
   CCAP0H =PWM_ZKB;
   }
   else
   {
   PWM_ZKB +=0x05;   //由于设置PWM的寄存器是8位的,最小是0x00,最大是0xff.那么微调的
        //设置是一次加0x05. 
   CCAP0H =PWM_ZKB;
   }
   date[2]=0xff;
}
if(date[2]==0x1d)
{
         delay2400();
   if(PWM_ZKB<0x10)
   {
   PWM_ZKB =0x09;
   CCAP0H =PWM_ZKB;
   }
   else
   {
   PWM_ZKB -=0x05;
   CCAP0H =PWM_ZKB;
   }
   date[2]=0xff;
}
}
}
//总结:此观点是我个人的看法:由于本人用的是STC12C5410单片机速度相对51系列是很快的,
//所以在遥控器解码的程序段上面我适当加了一些延迟
//例如:
// if(date[2]==0x1d)
// {
//         delay2400();
//如果不加延迟,单片机就无法去执行以下的程序段(我在实验时已经验证过了)。所以我归纳
//是单片机速度太快而导致的原因。
//以上程序适宜使用STC5410系列的单片机.