Infrared remote Control Protocol-NEC Protocol
To facilitate understanding of the waveform seen is the signal from the infrared receiver, and the protocol said the signal height (0 or 1) just the opposite
NEC protocol is one of many infrared remote control protocols, in addition to NEC, there are RC5, RC6 and other. Most of the non-learning universal TV remote controls that are available in the marketplace integrate one or more of the codes to be NEC-type, and more than three of the two remote controls I buy are NEC.
The NEC coded frame (usually the data sent by the remote control button) consists of a boot code, an address code, and a data code, as shown in the following illustration, to reverse the address code and the data code to enhance the correctness of the data.
The guide code and data are defined as shown in the figure below, and when holding down a button, the boot code (repeat) is sent around 110ms, without any data
The following is the waveform captured by the oscilloscope when holding down a button:
Click the waveform of the button:
One, remote control decoding instructions
1, the remote control coding format Common there are two kinds, one is NEC format, one is RC5 format. The signal from the remote controller is sent to an interrupt pin of the MCU after an IR receiving head. Through the MCU to identify different timing, to achieve the remote control key signal decoding.
2, remote control sequence diagram and data format (NEC format)
Data format:
The data code sent by the remote control consists of the following parts: Guide code, 8-bit client code, 8-digit customer code, 8-bit key value, and 8-digit key-value complement;
Specific timing:
Time Series for single button:
Note: A complete cycle is 108 ms
Continuous when pressing:
After the time series of a single keystroke, follow the following sequence: (cycle is also 108ms)
Second, the software design idea and the processing function
According to the characteristics of the remote control signal timing, in the design of software, we need to use time series, first find the boot area, and then read the customer code (can read 16 bits at a time), to identify whether the manufacturer of the value set; Read the 8-bit key value and save the read data.
The state value that needs to be defined to be used in the remote control decoding process:
#define ir_state_idle 0x00
#define ir_state_lead_on 0x01
#define Ir_state_lead_off 0x02
#define ir_state_custom 0x03
#define ir_state_data1 0x04
#define ir_state_data2 0x05
At the same time, define a constant that describes the duration of the high-low level.
#define Ir_r_max
#define ir_r_min
#define ir_h_max
#define IR _h_min
#define ir_l_max
#define ir_l_min 15
Define the following variables:
static unsigned char irstate;
static unsigned char irdata;
The decoding process is as follows: The decoding of the remote control is done in the interrupt processing function, when the MCU interrupt pin occurs the level change, will cause the interruption;
void interrupt nec_ir (void)
{
-------------------------------------
NEC Remote Control interrupt handling
------------------------------------
}
On the remote control decoding of RC5 format
RC5 format Remote Control In addition to the timing and NEC-format remote control is a little different, the software decoding process is basically similar, no longer described separately.
Third, the remote control signal decoding process
Iv. implementation code (based on PIC chip)
----------------------------------------------------------------------------//Function name:nec_ir// Description:ir Interrupt Manage//Params:none//Returns:none//Notes:sys INT service process//---------------------
-------------------------------------------------------void interrupt nec_ir (void) {unsigned char t0;
Here I things to disable the interupt!
gie=0;
IR intrupt input here.
Preamble=9ms "--|__|--" + 4.5ms "_|--|_", others Data high 2.25ms and low 1.25ms;
Data = "--|__|--" + "_|--|_" high 2.25ms and 1.25ms.
Repeat==9ms "--|__|--" + 2.25 ms "_|--|_".
if (intf) {t0 = TMR0;
TMR0 = 0;
Switch (irstate) {case IR_STATE_IDLE:INTEDG = 1;//rising Edge Trigger
Irstate = ir_state_lead_on;
Break Case IR_STATE_LEAD_ON:INTEDG = 0;//falling Edge Trigger if (T0 > Pream_l_min) &&am P;
(T0 < Pream_l_max))
{irstate = Ir_state_lead_off;
else {irstate = Ir_state_idle;
} break;
Case Ir_state_lead_off:if ((T0 > Pream_s_min) && (T0 < Pream_s_max)) {
Irstate = Ir_state_custom;
Ircustom = 0;
Bitcounter = 0;
Repeat = 0;
else {if ((T0 > Ir_r_min) && (T0 < Ir_r_max))
{if ((Repeat) && (systemstate = = power_on_state)) {
Repeat = 0;//ir Key Repeat}}
else {Repeat = 0;
}
INTEDG = 0;
Irstate = Ir_state_idle;
} break;
Case Ir_state_custom:if ((T0 > Ir_l_min) && (T0 < Ir_l_max)) {
Ircustom >>= 1;
else {if ((T0 > Ir_h_min) && (T0 < Ir_h_max))
{Ircustom = ((ircustom >> 1) | 0x8000);
else {intedg = 0;
Irstate = Ir_state_idle;
Repeat = 0;
Break
} if (++bitcounter = 16) {
if (Ircustom!= customcode) {intedg = 0; Irstate = Ir_state_idle;
Repeat = 0;
Break
} irstate = Ir_state_data1;
Bitcounter = 0;
Irkeycode = 0;
} break;
Case ir_state_data1:bitcounter++;
if ((T0 > Ir_l_min) && (T0 < Ir_l_max)) {Irkeycode >>= 1; else {if (T0 > Ir_h_min) && (T0 < Ir_h_ma
x)) {Irkeycode = ((irkeycode >> 1) | 0x80);
else {intedg = 0;
Irstate = Ir_state_idle;
Repeat = 0;
Break
} if (Bitcounter = 8) { Irstate = Ir_state_data2;
Bitcounter = 0;
Irdata = 0;
} break;
Case ir_state_data2:bitcounter++;
if ((T0 > Ir_l_min) && (T0 < Ir_l_max)) {irdata >>= 1;
else {if ((T0 > Ir_h_min) && (T0 < Ir_h_max))
{Irdata = ((irdata >> 1) | 0x80);
else {intedg = 0;
Irstate = Ir_state_idle;
Repeat = 0;
Break
} if (Bitcounter = 8) {intedg = 0;
Irstate = Ir_state_idle;
Irdata = ~irdata; if (Irkeycode = = Irdata) {//Check if
Data is valid} else {Repeat = 0;
}} break;
} intf=0;
} gie=1; }