2011年12月8日 星期四

NEC protocol IR remote TX program

//=========================
//Project:     NEC protocol TX
//Author:      Leo.Tseng
//Date:        2011/12/09
//MCU:         W78E054D
//CRYSTAL:     25Mhz
//Description: Use uart for input/output, set boudrate=9600,
//             Press Keypad to transmit NEC protocol code
//             SW20=0x08E647B8, power key.
//             SW15=0x08E618E7, channel up.
//             SW19=0x08E610EF, channel down.
//=========================
#include  <reg52.h>
#include  <stdio.h>
void uart_initinal(int boudrate);

int PERIOD,i;
unsigned KEY,temp;
unsigned long ir_data;

sbit PWMOUT = P3^2;
//sbit PWMOUT1 = P2^0;
//sbit PWMOUT2 = P2^1;
sbit SCAN0 = P2^7;                 // KEY SCAN0
sbit SCAN1 = P2^6;                 // KEY SCAN1
sbit SCAN2 = P2^5;                 // KEY SCAN2
sbit SCAN3 = P2^4;                 // KEY SCAN3
sbit DET3 = P2^3;                  // KEY DETECT0, always high
sbit DET2 = P2^2;                  // KEY DETECT2
sbit DET1 = P2^1;                  // KEY DETECT1
sbit DET0 = P2^0;                  // KEY DETECT0

//副程式宣告
void TIMER1_initinal(int baudrate);
void delay (int j);
void NEC_LEADER_CODE(void);
void NEC_low(void);
void NEC_high(void);
void NEC_stop(void);
//------------------------------------------------
//MAIN C function
//------------------------------------------------
void main (void)
{
 uart_initinal(9600);              // 起始 UART 設定,baudrate=9600

 TMOD = (TMOD & 0xF0) | 0x02;      // 設定 T/C0 Mode
 PERIOD = 200;
 TH0 = PERIOD;
 TL0 = TH0;
// ET0 = 1;                          // 致能 Timer 0 Interrupts
// TR0 = 1;                          // 啟動 Timer 0 計時
 EA = 1;                             // 全部致能始動
 PWMOUT = 0;
 SCAN0=0;
 SCAN1=SCAN2=SCAN3=1;
 DET3=DET2=DET1=DET0=1;
 //ir_data = 0x1067E21D; // for transmission 1
 //ir_data = 0xB847E608; // for transmission 2

 printf("NEC編碼紅外線發射程式\n");    // 顯示操作訊息

 while (1)
   {
    if((P2&0x0F)!=0x0F)                // 偵測是否按按鍵?
    {
      temp=P2&0xFF;                    // 第一次儲存按鍵值
      delay(6000);                     // 延遲 0.48us*6000=2.88ms,防彈跳調整
      KEY=P2&0xFF;                     // 第二次讀取按鍵值
      if(KEY&&temp)                    // 判別是否為按鍵
        {                            
     /* 
         ET0 = 1;
         TR0 = 1;
         // ***** transmission 1 *****
         NEC_LEADER_CODE();     
         NEC_low();NEC_low();NEC_low();NEC_high();    // 1:0001 > 8
         NEC_low();NEC_low();NEC_low();NEC_low();     // 0:0000 > 0
         NEC_low();NEC_high();NEC_high();NEC_low();   // 6:0110 > 6
         NEC_low();NEC_high();NEC_high();NEC_high();  // 7:0111 > E
         NEC_high();NEC_high();NEC_high();NEC_low();  // E:1110 > 7
         NEC_low();NEC_low();NEC_high();NEC_low();    // 2:0010 > 4
         NEC_low();NEC_low();NEC_low();NEC_high();    // 1:0001 > 8
         NEC_high();NEC_high();NEC_low();NEC_high();  // D:1101 > B
         NEC_stop();                                  // 停止位元
         //PWMOUT=0;
         ET0 = 0;
         TR0 = 0;
         delay(11030);                                // 補足108ms
         //ET0 = 1;
         //TR0 = 1; 
     */
         switch(KEY)                         
             {
              case 0x7B: printf("SW20 pressed, code=0x7B\n");
                        ir_data = 0xB847E608;  // SW20,等於 0x08E647B8
                        break;
                        
              case 0x7D: printf("SW15 pressed, code=0x7D\n");
                        ir_data = 0xE718E608;  // SW15,等於 0x08E618E7
                        break;
                 
              case 0x7E: printf("SW19 pressed, code=0x7E\n");
                        ir_data = 0xEF10E608;  // SW19,等於 0x08E610EF
                        break;
                                             
                                           
              default: break;                
             }
        
      // ******* transmission 2 ********
         NEC_LEADER_CODE();
          for(i=0;i<32;i++ )     
           {
            if(ir_data & 0x0001)
             {
              //printf("1");      // 除錯用
              NEC_high();
             }
             else
                {
                 //printf("0");   // 除錯用
                 NEC_low();
                }
           ir_data=ir_data>>1;
          }
         NEC_stop();
         //PWMOUT=0;
         ET0 = 0;
         TR0 = 0;
         delay(11030);                                // 補足108ms
         //ET0 = 1;
         //TR0 = 1; 
        }
    }  
   } 
}

//UART副程式使用timer1
void uart_initinal(int boudrate)      
{
 PCON  = 0x00;                                  // PCON: if SMOD=1(b7), Baud Rate is Doubled                         
 SCON  = 0x52;                                  // SCON: mode 1, 8-bit UART, enable rcvr                   
 TMOD  = (TMOD & 0x0f) | 0x20;                  // TMOD: timer 1, mode 2, 8-bit reload; keeps timer0 default.        
 TH1   = 256-(25000000/372/boudrate);           // 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, 產生38Khz 載波
void timer0_ISR(void) interrupt 1              
{
   PWMOUT^=1;   // 設為高電位
   PWMOUT&=1;
   PWMOUT&=1;
   PWMOUT&=1;
   PWMOUT&=1;
   PWMOUT&=1;
   PWMOUT^=1;   // 設為低電位
   PWMOUT&=1;
   PWMOUT&=1;
   PWMOUT&=1;
   PWMOUT&=1;
   PWMOUT&=1;
   //PWMOUT&=1;
}

void delay (int j)
{
 while(j)
  j--;
}

// NEC前導碼: 9ms高電位, 4.5ms低電位
void NEC_LEADER_CODE(void)
{
 ET0=1;
 TR0=1;
 //PWMOUT1=1; // 除錯用
 delay(336);
// PWMOUT1=0; // 除錯用
 ET0 = 0;
 TR0 = 0;
 delay(1170);
}
// NEC碼0: 0.56ms高電位, 0.56ms低電位
void NEC_low(void)
{
 ET0=1;
 TR0=1;
 //PWMOUT1=1; // 除錯用
 delay(19);
 //PWMOUT1=0; // 除錯用
 ET0 = 0;
 TR0 = 0;
 delay(140);   
}
// NEC碼1: 0.56ms高電位, 1.69ms低電位
void NEC_high(void)
{
 ET0=1;
 TR0=1;
 //PWMOUT1=1; // 除錯用
 delay(19);
 //PWMOUT1=0; // 除錯用
 ET0 = 0;
 TR0 = 0;
 delay(440); 
}
// NEC碼,停止位元: 0.56ms高電位
void NEC_stop(void)
{      
 ET0 = 1;
 TR0 = 1;
 //PWMOUT1=1; // 除錯用
 delay(19);
 //PWMOUT1=0; // 除錯用
 ET0 = 0;
 TR0 = 0;
}      

// =====    Test Result ========================                 


SW15, Code : 0x08E618E7

 SW19, Code : 0x08E610EF


SW20, Code : 0x08E647B8






沒有留言:

張貼留言