An infrared transmitter + decoding program + simulation file

Publisher:hfy13567003617Latest update time:2015-07-15 Source: 51hei Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
Any I/O can be defined as receiving pin, supporting long/short press, adaptive main frequency 6MHz~40


 

//*********************【NEC decoding header file】*******************
//
// Introduction: This program is suitable for NCE decoding: (9ms+4.5ms) boot code + 32-bit encoding.
// Compatible with all STC models (including 1T and 12T series), any I/O can be defined as infrared receiving pin,
// Adaptive decoding main frequency: 6MHz ~ 40MHz.
// 
// Usage conditions: occupy system timer 0, enable timer 0 interrupt (if using other timers, please modify IR_Init(); initialization function)
//
// Instructions for use: Fill in the relevant macro definitions: USER_H, USER_L, Check_EN, CPU_Fosc, IR,
// Power-on initialization function IR_Init(),
//Call the IR_NEC() decoding function in the timer 0 interrupt.
// When decoding is valid, IR_BT=2 means short press, IR_BT=3 means long press, cleared by the user,
// Decode and store: user code high 8 bits NEC[0], user code low 8 bits NEC[1], operation code NEC[2], operation code inverse NEC[3].
//
//【Function for users to call】
// IR_Init(); //Receive initialization, start timer 0 interrupt for 400us
// IR_NEC(); // Infrared decoding (NEC decoding)
//          
//***************************************************************/ 
#ifndef __IR_NEC_H__
#define __IR_NEC_H__


//[Required fields for users: USER_H, USER_L, Check_EN, CPU_Fosc, IR]
#define USER_H 0x80 // User code high 8 bits
#define USER_L 0x7F // User code lower 8 bits
#define Check_EN 0 //Whether to check the 16-bit user code: fill in 0 if not checked, fill in 1 if checked        
#define CPU_Fosc 12000000L // Input main frequency, adaptive decoding (unit: Hz, range: 6MHz ~ 40MHz)
#define CA_S 8 //Long press time setting, unit: 108mS (that is, integer multiples of 108mS, preferably more than 10 times)

sbit IR = P3^6; //Infrared interface (any pin)

#define Step 400 //Infrared sampling step: 400us
#define TH_H ((65536-Step*(CPU_Fosc/300)/40000)/256) //Timer high 8-bit reference value
#define TH_L ((65536-Step*(CPU_Fosc/300)/40000)%256) //Timer low 8-bit reference value

uint8 IR_BT; //Decoding effect return: 0 invalid, 1 valid, 2 short press, 3 long press
uint8 NEC[4]; //Decoding and storage: 16-bit user code, operation code positive and negative codes
uint8 cntCA; //Long press count
uint16 cntStep; //Step counter
bit IRa,IRb; //Save the receiving pin potential status
bit IRsync; //Synchronization flag
uint8 BitN; //bit code loading number


/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
Function: infrared decoding initialization
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void IR_Init()
{
   TMOD &= 0xF0; //Clear timer 0
   TMOD |= 0x01; //Timer 0: 16-bit timer
   TL0 = TH_L; //Time per step
   TH0 = TH_H;
   ET0 = 1;
   EA = 1;
   TR0 = 1;
}

/*┈┈┈┈┈┈┈┈┈┈┈ benchmark┈┈┈┈┈┈┈┈┈┈┈┈*/
#define Boot_Limit ((9000+4500 +1000)/Step) // Boot code cycle upper limit    
#define Boot_Lower ((9000+4500 -1000)/Step) //Boot code cycle lower limit    
#define Bit1_Limit ((2250 +800)/Step) //“1” cycle upper limit
#define Bit0_Limit ((1125 +400)/Step) //“0” cycle upper limit
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
Function: Infrared NEC periodic sampling decoding method (timing interrupt, falling edge query cycle time)
Global variable: IR_BT = 0 is invalid
                  1 is valid, waiting to continue to judge long and short presses (if long and short presses do not need to be judged, use it directly)
                  2 short press
                  3. Long press
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void IR_NEC()
{          
   TL0 = TH_L; //Reassign value
   TH0 = TH_H;        

   cntStep++; //Accumulate steps
   if(IR_BT==1)if(cntStep>300)IR_BT=2; //After decoding is effective, if there is no long press, the default short press will be after 120ms (400us×300)

   IRb = IRa; //Save the last potential state
   IRa = IR; //Save the current potential state
        
   if(IRb && !IRa) //Is it a falling edge (last high, current low)
   {
      if(cntStep > Boot_Limit) //Exceeded synchronization time?
      {        
          if(IR_BT==1)if(++cntCA>CA_S)IR_BT=3; //After decoding is effective, continue to press and hold the remote control>CA_S, that is, long press
          IRsync=0; //Synchronization bit cleared
      }
      else if(cntStep > Boot_Lower){ IRsync=1; BitN=32; } //Sync position 1, load bit number 32                          
      else if(IRsync) //If it is synchronized
      {
         if(cntStep > Bit1_Limit)IRsync=0;                   
         else
         {        
            NEC[3] >>= 1;                                
            if(cntStep > Bit0_Limit)NEC[3] |= 0x80; //“0” and “1”
            if(--BitN == 0)                                
            {
               IRsync = 0; //Synchronization bit cleared

               #if (Check_EN == 1)                                        
               if((NEC[0]==USER_H)&&(NEC[1]==USER_L)&&(NEC[2]==~NEC[3])) //Check 16-bit user code, operation code positive and negative codes
               { IR_BT=1; cntCA=0; } //Decoding is valid, next check: short press? long press?
               #else
               if(NEC[2]==~NEC[3]){ IR_BT=1; cntCA=0; } //Only check the positive and negative codes of the operation code
               #endif                                        
            }
            else if((BitN & 0x07)== 0) //NEC[3] is moved and saved every time it is filled with 8 bits (i.e. BitN%8 == 0)
            { NEC[0]=NEC[1]; NEC[1]=NEC[2]; NEC[2]=NEC[3]; }
         }
      }
      cntStep = 0; // step counter cleared to 0
   }
} 

//Cancel related macro definitions
#wheref CPU_Fosc

#endif





Main Program
#include "INCSTC89C52RC.H"
#include "INCMY_SET.H"
#include "INCIR_NEC.H" //Call NEC decoding header file

sfr SE = 0x80; //Digital tube segment selection P0: 0x80 P1: 0x90
sbit WX1 = P2^0; //digital tube position display
sbit WX2 = P2^1;
sbit WX3 = P2^2;
sbit WX4 = P2^3;
sbit WX5 = P2^4;
sbit WX6 = P2^5;
sbit WX7 = P2^6;
sbit WX8 = P2^7;

uint8c tab[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0X88,0X83,0XC6,0XA1,0X86,0X8E,0xFF};
uint8  Xn,X1,X2,X3,X4,X5,X6;

void KZ0(); //Short press processing
void KZ1(); //Long press processing


/***************** Main function************************/
void main(void)
{
   IR_Init(); //Initialize infrared decoding
                                                   
   while(1)
   { 
      //Remote control detection
      if((IR_BT==2)||(IR_BT==3))                          
      {
         if(IR_BT==2)KZ0(); //short press processing                  
         else KZ1(); //Long press processing        
         IR_BT =0; // Clear valid flag

         X1 = NEC[0]/16; //Update display
         X2 = NEC[0]%16;
         X3 = NEC[1]/16;
         X4 = NEC[1]%16;
         X5 = NEC[2]/16;
         X6 = NEC[2]%16;
      }
          
   }

}[page]
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
Function: Remote control short press processing
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void KZ0()
{
   switch(NEC[2])             
   {
          case 0x12: P10 = !P10; break;
          case 0x05: break;
          case 0x1E: break;
          case 0x55: break;

          case 0x01: break;
          case 0x1B: break;
          case 0x03: break;
          case 0x6B: break;

          case 0x07: break;
          case 0x08: break;
          case 0x09: break;
          case 0x68: break;

          case 0x22: break;
          case 0xE6: break;
          case 0x33: break;
          case 0xE2: break;
          default:break;
   }
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
Function: Remote control long press processing
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void KZ1()
{
   switch(NEC[2])             
   {
          case 0x12: P14 = !P14; break;
          case 0x05: break;
          case 0x1E: break;
          case 0x55: break;

          case 0x01: break;
          case 0x1B: break;
          case 0x03: break;
          case 0x6B: break;

          case 0x07: break;
          case 0x08: break;
          case 0x09: break;
          case 0x68: break;

          case 0x22: break;
          case 0xE6: break;
          case 0x33: break;
          case 0xE2: break;
          default:break;
   }
}
/*********************Digital tube scanning****************************/
void XS(void)
{ 
  if(++Xn > 7)Xn=0;
  switch(Xn)             
  {
            case 0: WX8=1; NOP; //shield the upper digit display
                    SE=tab[X1]; //Send segment code
                    WX1=0; //Open the display
                    break;
            case 1: WX1=1; NOP; SE=tab[X2]; WX2=0; break;
            case 2: WX2=1; NOP; SE=tab[X3]; WX3=0; break;        
         case 3: WX3=1; NOP; SE=tab[X4]; WX4=0; break;
         case 4: WX4=1; NOP; SE=tab[16]; WX5=0; break;
         case 5: WX5=1; NOP; SE=tab[16]; WX6=0; break;
         case 6: WX6=1; NOP; SE=tab[X5]; WX7=0; break;
         case 7: WX7=1; NOP; SE=tab[X6]; WX8=0; break;                 
         default:break;                         
  }
} 

/********************** Timer 0 interrupt function****************************/
void time0(void) interrupt 1
{ 
   IR_NEC();
   XS();         
}
 

Receive source program + simulation
Click here to download  http://www.51hei.com/f/hong1.rar

Remote control source code
Click here to download  http://www.51hei.com/f/hong2.rar

/***************************************************************
    Work: Infrared remote control transmitter (NEC code)
  Microcontroller: STC89C52RC
    Crystal: 12M
***************************************************************/
//
// Emitting pin (connected to the PNP transistor B)
//PNP transistor e-pole connected to 2Ω resistor, c-pole connected to infrared emitting tube
     
#include 
#include "INCMY_SET.h"
#include "INCLCD1602_6IO.h"  

sbit IR = P3^6; //Emitting pin (connected to the base of PNP transistor)

#define USER_H P2 // User code high 8 bits
#define USER_L P0 // User code lower 8 bits
uint8c tab[16] = { //Operation code
0x12,0x05,0x1e,0x55,
0x01,0x1b,0x03,0x6b,
0x07,0x08,0x09,0x68,
0x22,0xE6,0x33,0xe2};

#define m9    (65536-9000)           //9mS
#define m4_5  (65536-4500)           //4.5mS
#define m1_6  (65536-1650)           //1.65mS
#define m_56  (65536-560)           //0.56mS
#define m40   (65536-40000)       //40mS
#define m56   (65536-56000)       //56mS
#define m2_25 (65536-2250)        //2.25mS

void  SanZhuan();
uint8 KEY(void);
void ZZ(uint8 x); //NEC code sending program
void Z0(uint8 temp); //Single frame (8-bit data) sending program
void TT0(bit BT,uint16 x); //38KHz carrier transmission + delay program



/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
Function: Main program
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void main(void)
{
  TMOD = 0x01; //T0 16-bit working mode
  IR=1; //The transmitting port is normally high level
  L1602_Heat();
  L1602_clr();
  L1602_xy(0,0);
  L1602_ZIFUC("UserCode :0x"); 
  L1602_xy(0,1);
  L1602_ZIFUC("Opcode   :0x");

  while(1) 
  {           
   L1602_xy(12,0);
   L1602_JZ(USER_H,16,1);
   L1602_JZ(USER_L,16,1);
   SanZhuan();
  }
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
Function: 4×4 matrix keyboard
                      【Line flip method key value table】                    
P1.0 P1.1 P1.2 P1.3 P1.4 P1.5 P1.6 P1.7
│     │    │    │    │    │    │    │    
│ │ │ └──7e be de ee      
│     │    └─────7d    bd    dd   ed      
│     └────────7b    bb    db   eb      
77 b7 d7 e7    
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
uint8 KEY(void)
{
  uint8 Key = 0;

  P1 = 0xf0; //Keyboard initialization: row value = 0, column value = 1
  NOP; // Buffer, wait for the IO port potential to stabilize
  Key = P1&0xf0; //Get the row flag

  P1 = 0x0f; //Flip keyboard interface output
  NOP;
  Key |= (P1&0x0f); //column mark + row mark

  return Key; //Return key value
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
Function: Scattering program
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void SanZhuan()
{
uint8 v;
v = KEY(); //Keyboard detection
switch(v)
{
  case 0x7e:ZZ(tab[0]);break;                
  case 0xbe:ZZ(tab[1]);break;                
  case 0xde:ZZ(tab[2]);break;                
  case 0xee:ZZ(tab[3]);break;                
  case 0x7d:ZZ(tab[4]);break;                
  case 0xbd:ZZ(tab[5]);break;                
  case 0xdd:ZZ(tab[6]);break;                
  case 0xed:ZZ(tab[7]);break;
  case 0x7b:ZZ(tab[8]);break;                
  case 0xbb:ZZ(tab[9]);break;                
  case 0xdb:ZZ(tab[10]);break;                
  case 0xeb:ZZ(tab[11]);break;
  case 0x77:ZZ(tab[12]);break;                
  case 0xb7:ZZ(tab[13]);break;                
  case 0xd7:ZZ(tab[14]);break;                
  case 0xe7:ZZ(tab[15]);break;                                
  default:break;
}
v=0;
}

/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
Function: NEC code sending program
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void ZZ(uint8 Value)
{ 
  L1602_xy(12,1);
  L1602_JZ(Value,16,1); //Update display
  
  TT0(1,m9); //High level 9mS
  TT0(0,m4_5); //Low level 4.5mS

  /*┈ Send 4 frames of data┈*/
  Z0(USER_H); //user code high 8 bits
  Z0(USER_L); //lower 8 bits of user code
  Z0(Value); //Operation code
  Z0(~Value); //Operation code inverse

  /*┈┈ End code┈┈*/
  TT0(1,m_56);
  TT0(0,m40);

  /*┈┈ Repeat code┈┈*/
  while(KEY() != 0xFF)
   {
        TT0(1,m9);
        TT0(0,m2_25);

        TT0(1,m_56);
        TT0(0,m40);
        TT0(0,m56);                                  
    }                   
}

/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
Function: Single frame (8-bit data) sending program
Entry: temp
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void Z0(uint8 temp)
{
  uint8 v;
  for(v=0;v<8;v++)  
  {     
      TT0(1,m_56); //High level 0.65mS         
      if(temp&0x01) TT0(0,m1_6); //Send the lowest bit
      else          TT0(0,m_56);     
      temp >>= 1; //Shift right one bit
  }    
}

/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
Function: 38KHz carrier transmission + delay program
Entry: (whether to transmit carrier wave, delay about x (uS))
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void TT0(bit BT,uint16 x)
{
  TH0 = x>>8; // Input timing value
  TL0 = x;
  TF0=0; // Clear overflow flag
  TR0=1; //Start timer 0
  if(BT == 0) while(!TF0); //When BT=0, 38KHz carrier wave is not transmitted but only delayed;
  else while(1) //When BT=1, transmit 38KHz pulse + delay; 38KHz carrier (low level) duty cycle 5:26
       {
              IR = 0;
              if(TF0)break;if(TF0)break;
              AND = 1;
                if(TF0)break;if(TF0)break;
                 if(TF0)break;if(TF0)break;
                 if(TF0)break;if(TF0)break;
                 if(TF0)break;if(TF0)break;
                 if(TF0)break;if(TF0)break;
       }
  TR0=0; //turn off timer 0
  IR =1; //After the carrier stops, the transmitting port is normally high
}
Reference address:An infrared transmitter + decoding program + simulation file

Previous article:Atmel and STC 51 MCU Universal ISP Download Cable Production
Next article:A 24C read and write function that supports detecting device models

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号