2011年11月24日 星期四

IR Remote Control LED program

//=========================
//Project:     IR Remote Controller Decode
//Author:      Leo.Tseng
//Date:        2011/11/25
//MCU:         W78E054D
//CRYSTAL:     25Mhz
//Description: Use uart for output, set boudrate=9600,
//             Decode NEC transmission format
//=========================
#include  <reg52.h>
#include  <stdio.h>
// 變數宣告
sbit WAVEFORM_OUT = P2^0;
sbit IR_INT = P3^2;
sbit UP = P1^2;                    // LED1
sbit DOWN = P1^3;                  // LED2
sbit LEFT = P1^4;                  // LED3
sbit RIGHT = P1^5;                 // LED4
unsigned int ir_high;
unsigned int IR_BUFFER[33]=0;
unsigned int PERIOD_HIGH;
int index=0,i,j;
unsigned long ir_data=0;

//副程式宣告
void TIMER1_initinal(int baudrate);
//主程式開始
void main(void)
{
 WAVEFORM_OUT=1;
 PERIOD_HIGH=201;                     // Sample rate 38Khz.
 TIMER1_initinal(9600);               // 使用UART,baudrate=9600

 IT0 = 1;                             // Configure interrupt 0 for falling edge on /INT0 (P3.2)
 EX0 = 1;                             // Enable EX0 Interrupt
 
 TMOD = (TMOD & 0xF0) | 0x0a;         /* Set T/C0 Mode */
 TH0= PERIOD_HIGH;                    // load sampleing rate
 TL0= TH0;                            //
 ET0 = 1;                             /* Enable Timer 0 Interrupts */
 TR0 = 1;                             /* Start Timer 0 Running */
 EA = 1;                              /* Global Interrupt Enable */

 printf("\nPress IR remote controller to decoed\n\n");

 IR_INT=1;
 //WAVEFORM_OUT = IR_INT;
 ir_high=0;

 UP=DOWN=LEFT=RIGHT=0;

 while(1)
  {
  //if(blinking) UP^=DOWN^=LEFT^=RIGHT^=1;
   
   //WAVEFORM_OUT = IR_INT;             // 關閉38K輸出
   if(index==33)
     {
      //printf("index_loop index=%d\n",index);
      TR0=0;
      ET0=0;
      EX0=0;
      EA=0;
      ///*
      for(i=0;i<4;i++)
         for(j=0;j<4;j++)
            {
             IR_BUFFER[33]=IR_BUFFER[8*i+j];             
             IR_BUFFER[8*i+j]=IR_BUFFER[7+8*i-j];
             IR_BUFFER[7+8*i-j]=IR_BUFFER[33];
            }
      for(i=0;i<32;i++)
         {
          if((IR_BUFFER[i]>=18)&&(IR_BUFFER[i]<=28))
            {
             IR_BUFFER[i]=0;
             ir_data=ir_data<<1;
            }
          else if((IR_BUFFER[i]>=60)&&(IR_BUFFER[i]<=70))
                 {
                  IR_BUFFER[i]=1;
                  ir_data=(ir_data<<1)|0x01;
                 }
          printf("%d",IR_BUFFER[i]);
         }
      printf(" < The Binary Code\n");  
      printf("The Hexadecimal Code:%lX \t",ir_data);
      printf("\n\n");
      //*/
     
      /*
      for(i=0;i<32;i++)                       // for debug
        printf("[%d]:%d\n",i,IR_BUFFER[i]);
      */
          
      //============================ 
      switch(ir_data)                        
           {
            case 0x08e614eb:UP^=1;                               // 對應上鍵,亮滅LED1
                      break;
                     
            case 0x08e616e9:DOWN^=1;                            // 對應下鍵,亮滅LED2
                      break;
                     
            case 0x08e61de2:LEFT^=1;                             // 對應左鍵,亮滅LED3
                      break;
                     
            case 0x08e611ee:RIGHT^=1;                            // 對應右鍵,亮滅LED4
                      break;
                     
            case 0x08E65CA3:DOWN^=UP^=1;                         // 對應+鍵,LED做4位元上數計數器
                            LEFT^=(DOWN && UP);
                            RIGHT^=(LEFT && DOWN && UP);
                      break;
                     
            case 0x08E65DA2:DOWN^=!(UP^=1);                      // 對應-鍵,LED做4位元下數計數器 
                            LEFT^=(!DOWN && !UP);
                            RIGHT^=(!LEFT && !DOWN && !UP);
                      break;                            
                     
                                      
            default: break;                
           }
      //============================  
     
      index=0;
      ir_high=0;                     
      TL0=TH0;                            // 重新載入取樣頻率
      TR0=1;
      ET0=1;
      EX0=1;
     }
   EA=1;    
  }
}

//UART副程式
void TIMER1_initinal(int baudrate)      
{
 PCON  = 0x00;                          // PCON: if SMOD=1(b7), Baud Rate is Doubled                         
 SCON  = 0x52;                          // SCON: mode 1, 8-bit UART, enable rcvr                   
 TMOD  = 0x20;                            // TMOD: timer 1, mode 2, 8-bit reload          
 //TH1   = 256-(11059200/384/baudrate);   // TH1:  reload value for baud @ 11.0592MHz, TH=0xFD
 TH1   = 256-(25000000/372/baudrate);     // TH1:  reload value for baud @ 25MHz, TH=0xF9   
 TR1   = 1;                               // TR1:  timer 1 run                             
 //TI    = 1;                             // TI:   set TI to send first char of UART   
}
//計時器0中斷1
void timer0_ISR(void) interrupt 1
{
 WAVEFORM_OUT^=1;
 ir_high++;
 EX0=1;                                   // 外部中斷0致能
}
// INT0中斷0
void EXT_INT0(void) interrupt 0
{
 WAVEFORM_OUT = IR_INT;                   // 關閉38K輸出
 EX0=0;                                   // 外部中斷0禁能
 TR0=0;                                   // 計時器0停止
 ET0=0;                                   // 計時器0中斷禁能
 TL0= TH0;            
 IR_BUFFER[index]=ir_high;                //
 index++;                                 // 指向下一個儲存區
 if((ir_high>=160)&&(ir_high<=180))
  index=0;                                // 前導碼值 68@TH0=120, 167@TH0=200
 ir_high=0;                     
 ET0=1;                                   //                 
 TR0=1;                                   //  
}                     

沒有留言:

張貼留言