this experiment "NEC IR receiver with VerilogHDL" utilize my WireFrame FPGA board which was published earlier Click here to go previous article.
NEC Protocol
NEC Protocol has been already well documented and explained in the previous post click here to got to previous post
The Decoder Module
decoder module implement the good old state machine to step through the various stages of the NEC protocol.
the module logic define same as the C code in Previous Project .
the State machine get into next state at every edge of the IR input signal , as you can see in the timing diagram blow there are total 67 edges ,so total 67 states.
please read the previous post for detailed description about the NEC IR protocol.
major point in the NEC protocol
T1 leading pulse at 84.115ms
T2 space on 93.28ms
T3 Address starts at 97.580ms
T4 Address ends , address inverse starts 107.670ms
T5 address inverse ends , command starts at 124.486ms
T6 Command ends, command inverse starts 135.696ms
T7 Command inverse ends and last 562.5µs pulse to show end of transmission

state == 1 we just detected the first edge of the input singal it may also mean(if interrupt is not false) that the 9ms leading pulse started | |||
after the first edge THE next pulse is expected to arrive around 9ms so the TIMEOUT is set to 11ms and PREPULSE is set to 8ms | |||
state == 2 we just detected the second edge of the input signal and we finished the 9ms leding pulse and now 4.5ms space started | |||
after the second edge the next pulse is expected to arrive around 4.5ms so TIMEOUT is set to 5.5ms and PREPULSE is 3ms | |||
state == 3 we just detected the third edge of the input singal and we finished 4.5ms space and addres lsb is now started | |||
after the third edge the next pulse is expected to arrive around 562.5us so TIMEOUT is set to 2.3ms and PREPULSE is 0.2ms (timeout can be much less at this state but to do this i have to add one more if else statemetnt) | |||
(state 4 is not T4 from the diagram ) | |||
state == 4 we just decected the forth edge and the 562.5 us burt of LSB of address has ended now a little space for '0'562.5us or for '1' 1.6875ms | |||
after the forth edge the next pulse is expected to arrive for '0' around 562.5us and for '1' 1.675ms so TIMEOUT is set to 2.3ms and PREPULSE is 0.2ms | |||
state ==5 to 66 data pulse keep comming | |||
TIMOUT and PREPLUSE remain same as above. | |||
state ==67 we just fined the command inverse MSB space not the final 562.5us burst has stated so we fined the receiveing | |||
now we will check the address and command for being correct |
as the system gets into next state on every signal edge , the question is how to detect IR signal edge.
Detecting edge of the Input signal,
the always block runs on ever positive clock edge , clock is derived from on board 25Mhz crystal oscillator ,
on ever positive edge of the clock the always block samples the IR signal , and then compare it with captured IR signal's value on the last positive edge of the clock , store it temporary register to be compared with next positive edge of the clock.
hens if the current value and the previous value does not match we got the edge in the signal,
Measuring time between edges
in micro controller implementation we utilized a hardware time to measure time between the signal edge , so that we can always sure of the edge being at the correct time according to the state machine.
to measure time in the FPGA , we also implemented an timer module, which run on the system clock , and ever time we detect a IR signal edge we take out the reading out of the time module and compare with a predefined constant to see if the edge is at the right time and of right length.
we also clear the timer on every read, so that it will be a fresh value on next read.
timer module has over flow flag to detect very long idle time on the IR signal input.
The decode module
module source is little big ~ 200 lines to be published here you can take a look at the code in the git hub repo click here to go to soure.
Validation
![]() |
IR Code Input(Ch2) an module data_ready output (Ch1) |
![]() | |
|
![]() | |
|
Source Code and Design file
all the source code is available in the github repo
https://github.com/circuitvalley/WireFrame-FPGA/tree/master/VerilogHDL-Modules/Nec_Decoder
https://github.com/circuitvalley/WireFrame-FPGA
Comments
Post a Comment