当前位置:网站首页>MCU: NEC protocol infrared remote controller

MCU: NEC protocol infrared remote controller

2022-06-13 03:53:00 DC-STDIO


NEC Protocol infrared remote control

The communication distance of home appliance remote controller is often not high , The cost of infrared is much lower than other wireless devices , Therefore, infrared always occupies a place in the application of home appliance remote control . There are many baseband communication protocols for the remote controller , There are about dozens , The common ones are ITT agreement 、NEC agreement 、Sharp agreement 、Philips RC-5 agreement 、Sony SIRC Agreements, etc . The most used is NEC It's agreed , So we KST-51 The remote controller matched with the development board directly adopts NEC agreement , Our class is also based on NEC Protocol standards to explain .

NEC The data format of the protocol includes the boot code 、 User code 、 User code ( Or user code inversion )、 Key codes and key codes are inversely coded , The last stop bit . The stop bit is mainly used for isolation , Generally, no judgment is made , We also ignore it when programming . The total number of data codes is 4 Bytes 32 position , As shown in the figure below . The first byte is the user code , The second byte may also be user code , Or the inverse of the user code , It is up to the manufacturer to decide , The third byte is the key data code of the current key , The fourth byte is the inverse of the key data code , Can be used to correct data .

 Insert picture description here
This NEC agreement , The way to represent data is not like what we have learned before, such as UART As intuitive , Instead, each bit of data itself needs to be encoded , After coding, carry out carrier modulation .

  • Pilot code :9 ms Carrier of +4.5 ms The free .
  • Bit value “0”:560 us Carrier of +560 us The free .
  • Bit value “1”:560 us Carrier of +1.68 ms The free .

Combined with the above figure, we can see , The first dark section , It's the boot code 9 ms carrier , Then there is the boot code 4.5 ms The free , And the data code behind , There are many carriers and idle crossover , Their length is determined by the specific data they want to transmit .HS0038B This infrared integrated receiver , When a carrier signal is received , A low level will be output , When idle, it will output high level , We use a logic analyzer to grab an infrared button to pass HS0038B Decoded graphics to understand , As shown in the figure below .

 Insert picture description here
As you can see from the diagram , First, 9 ms Carrier plus 4.5 ms Idle start code , The data code is in the low order , High position behind , The first byte of the data code is 8 Group 560 us Carrier plus 560 us The free , That is to say 0x00, The second byte is 8 Group 560 us Carrier plus 1.68 ms The free , It can be seen that it is 0xFF, These two bytes are the inverse of user code and user code . The key code binary of the key is 0x0C, The inverse is 0xF3, Finally, I followed a 560 us Carrier stop bit . For our remote control , Different buttons , It is the difference between key code and key code inverse code , The user code is the same . In this way, we can pass the program of single-chip microcomputer , Parse the key code of the current key .

When our previous study was interrupted , Acquire 51 MCU has external interrupt 0 And external interruptions 1 These two external interrupts . Our infrared receiving pin is connected to P3.3 On the pin , The second function of this pin is external interrupt 1. In the register TCON Medium bit3 and bit2 These two , Yes and external interrupts 1 The two concerned . among IE1 Is the external interrupt flag bit , When an external interrupt occurs , This bit is automatically set 1, And timer interrupt flag bit TF be similar , After entering the interrupt, it will be reset automatically , You can also clear the software .bit2 It is used to set the external interrupt type , If bit2 by 0, So as long as P3.3 An interrupt can be triggered when the level is low , If bit2 by 1, that P3.3 Only when the falling edge from high level to low level occurs can the interrupt be triggered . Besides , External interrupt 1 The enabling bit is EX1. Now let's write the program , Use the nixie tube to display the user code and key code of the remote control .

Infrared.c The file is mainly used to detect infrared communication , When an external interrupt occurs , Enter external interrupt , By timer 1 timing , First, judge the pilot code , Then, the time of high and low levels is obtained for each bit of the data code bit by bit , So we can know that everyone is 0 still 1, Finally, the data code is solved . Although the final function is very simple , But because of the complexity of the code itself , It makes the interrupt program of infrared receiving more complicated in logic , Then we first provide the program flow chart of the interrupt function , You can refer to the flow chart to understand the program code

 Insert picture description here

/***************************Infrared.c  File program source code *****************************/
#include <reg52.h>
sbit IR_INPUT = P3^3; // Infrared receiving pin 
bit irflag = 0; // Infrared receiving sign , After receiving a frame of correct data  1
unsigned char ircode[4]; // Infrared code receiving buffer 

/*  Initialize the infrared receiving function  */
void InitInfrared(){
    
    IR_INPUT = 1; // Ensure that the infrared receiving pin is released 
    TMOD &= 0x0F; // Zero clearing  T1  Control bit of 
    TMOD |= 0x10; // To configure  T1  For mode  1
    TR1 = 0; // stop it  T1  Count 
    ET1 = 0; // prohibit  T1  interrupt 
    IT1 = 1; // Set up  INT1  Trigger for negative edge 
    EX1 = 1; // Can make  INT1  interrupt 
}
/*  Gets the duration of the current high level  */
unsigned int GetHighTime(){
    
    TH1 = 0; // Zero clearing  T1  Count the initial value 
    TL1 = 0;
    TR1 = 1; // start-up  T1  Count 
    while (IR_INPUT){
     // The infrared input pin is  1  Time cycle detection wait , Turn into  0  End this cycle 
        // When  T1  The count is greater than  0x4000, That is, the duration of high level exceeds about  18ms  when ,
        // Force out of loop , To avoid abnormal signals , The program pretends to die here .
        if (TH1 >= 0x40){
    
            break;
        }
    }
    TR1 = 0; // stop it  T1  Count 
    return (TH1*256 + TL1); //T1  The count values are synthesized into  16bit  Integer numbers , And return the number 
}
/*  Gets the duration of the current low level  */
unsigned int GetLowTime(){
    
    TH1 = 0; // Zero clearing  T1  Count the initial value 
    TL1 = 0;
    TR1 = 1; // start-up  T1  Count 
    while (!IR_INPUT){
     // The infrared input pin is  0  Time cycle detection wait , Turn into  1  End this cycle 
        // When  T1  The count is greater than  0x4000, That is, the duration of low level exceeds about  18ms  when ,
        // Force out of loop , To avoid abnormal signals , The program pretends to die here .
        if (TH1 >= 0x40){
    
            break;
        }
    }
    TR1 = 0; // stop it  T1  Count 
    return (TH1*256 + TL1); //T1  The count values are synthesized into  16bit  Integer numbers , And return the number 
}
/* INT1  Interrupt service function , Perform infrared receiving and decoding  */
void EXINT1_ISR() interrupt 2{
    
    unsigned char i, j;
    unsigned char byt;
    unsigned int time;

    // Receive and determine the pilot code  9ms  Low level 
    time = GetLowTime();
    // The time determination range is  8.5~9.5ms,
    // If it exceeds this range, it means error code , immediate withdrawal 
    if ((time<7833) || (time>8755)){
    
        IE1 = 0; // Clear before exiting  INT1  Interrupt flag 
        return;
    }
    // Receive and determine the pilot code  4.5ms  High level 
    time = GetHighTime();
    // The time determination range is  4.0~5.0ms,
    // If it exceeds this range, it means error code , immediate withdrawal 
    if ((time<3686) || (time>4608)){
    
        IE1 = 0;
        return;
    }
    // Receive and determine the subsequent  4  Bytes of data 
    for (i=0; i<4; i++){
     // Cyclic reception  4  Bytes 
        for (j=0; j<8; j++){
     // Cyclic receive determines the number of bytes per byte  8  individual  bit
            // Receive decision every  bit  Of  560us  Low level 
            time = GetLowTime();
            // The time determination range is  340~780us,
            // If it exceeds this range, it means error code , immediate withdrawal 
            if ((time<313) || (time>718)){
    
                IE1 = 0;
                return;
            }
            // Receive every  bit  High level time , Determine the  bit  Value 
            time = GetHighTime();
            // The time determination range is  340~780us,
            // Describe the... Within this scope  bit  The value is  0
            if ((time>313) && (time<718)){
    
                byt >>= 1; // Because the low position comes first , So the data is shifted to the right , The high position is  0
                // The time determination range is  1460~1900us,
                // Describe the... Within this scope  bit  The value is  1
            }else if ((time>1345) && (time<1751)){
    
                byt >>= 1; // Because the low position comes first , So the data is shifted to the right ,
                byt |= 0x80; // High position  1
            }else{
     // If it is not within the above range, it means error code , immediate withdrawal 
                IE1 = 0;
                return;
            }
        }
        ircode[i] = byt; // After receiving a byte, save it to the buffer 
    }
    irflag = 1; // Set the flag after receiving 
    IE1 = 0; // Clear before exiting  INT1  Interrupt flag 
}

When you read this program , It will be found that the senior student made a timeout judgment when obtaining the high and low level time if(TH1 >= 0x40), This timeout judgment is mainly used to deal with the abnormal input signal ( Such as accidental interference ) Situational , If you do not make a timeout judgment , When the input signal is abnormal , It is possible that the program will be waiting for an unreachable jump edge , And cause the program to fake death .

Add a little more , The signal sent by a single press of the key on the remote control is different from that by a continuous press of the key . Let's first compare the measured signal waveforms of the two key pressing modes

Infrared single key sequence diagram
 Insert picture description here

Infrared continuous key sequence diagram  Insert picture description here

The result of a single keystroke 16-9 And our previous figure 16-8 It's the same , There is no need to explain this . And keep pressing , First, it will send out the same waveform as a single key , After about 40 ms after , Will produce a 9 ms Carrier plus 2.25 ms Free , Followed by a stop bit waveform , This is called repetition code , Then as long as you keep pressing the button , Then every about 108 ms A duplicate code will be generated . For this duplicate code, our program does not parse it separately , Instead, it directly ignores , This does not affect the reception of normal key data . If you need to use this repetition code when you do the program in the future , Then you just need to add the analysis of duplicate codes .


原网站

版权声明
本文为[DC-STDIO]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/164/202206130337494054.html