TA的每日心情 | 开心 2017-1-11 04:03 |
---|
签到天数: 3 天 连续签到: 1 天 [LV.2]偶尔看看I
|
手头有红外发射器和接收器,就做红外的测试
主要的原理图如下:
通信接口就是UART
然后进行仿真测试,由于之前的UART模块是测试好,就不赘述.
tb的思路就是发送00 - ff 的数据到irDA.
uart的波特率是115.2Kbps
下面放出irDA的代码.
`timescale 1ns / 100psmodule sirendec ( clk16x, // Input: 16x (chip rate) clock irrxd, // Input: IR RxD input from IR transciever module nrcven, // Input: Active low reset for decode state machine rxd, // Output: Recovered RxD output -> UART's SIN signal txd, // Input: TxD input <- UART's SOUT signal irtxd // Output: TxD LED signal output for IR transciever ) ; input clk16x , irrxd , nrcven , txd ; output rxd , irtxd ;/******** Decoder **********/reg q0, q1, q2, q3;reg trigctl, count8reset, one_more; reg clear_ff;wire rxd = ~clear_ff;wire restrigff = nrcven & count8reset;always @ ( negedge irrxd or negedge restrigff ) begin if ( ~restrigff ) trigctl <= 0; else trigctl <= 1;end wire reset_count = ~( (~one_more) | (~trigctl) ) ; always @ ( negedge clk16x or negedge clear_ff ) begin if (~clear_ff) q0 <= 0; else q0 <= ( reset_count | (~q0) );end wire din_q1 = ~(reset_count | (~( q0 ^ q1 )) ); always @ ( negedge clk16x or negedge clear_ff ) begin if ( ~clear_ff ) q1 <= 0; else q1 <= din_q1;endwire din_q2 = ~(reset_count | (~( q2 ^ (q0 & q1) )) ); always @ ( negedge clk16x or negedge clear_ff ) begin if (~clear_ff) q2 <= 0; else q2 <= din_q2;end wire din_q3 = ~(reset_count | (~( ( q0 & q1 & q2 ) ^ q3 )) ); always @ ( negedge clk16x or negedge clear_ff ) begin if ( ~clear_ff ) q3 <= 0; else q3 <= din_q3;endwire judge_1 = ~( q0 | q1 | q2 | q3 );wire judge_2 = ~( (~q0) & (~q1) & (~q2) & q3 );always @ ( posedge clk16x or negedge nrcven ) begin if ( ~nrcven ) count8reset <= 0; else count8reset <= judge_2;endalways @ ( posedge clk16x or negedge nrcven ) begin if ( ~nrcven ) clear_ff <= 0; else clear_ff <= ~(judge_1 & (~trigctl) );endalways @ ( negedge clk16x or negedge nrcven ) begin if ( ~nrcven ) one_more <= 0; else one_more <= q3;end/********** Encoder **********/reg [3:0] count4bit ;always @ ( negedge clk16x or posedge txd ) begin if ( txd ) count4bit <= 4'b0000; else count4bit <= count4bit + 1;endwire dec8clkcount = (~count4bit[0]) | (~count4bit[1] ) | (~count4bit[2]) | count4bit[3]; // == 8wire dec10cycclk = count4bit[0] | (~count4bit[1]) | count4bit[2] | (~count4bit[3]); // == 5wire irtxd;jk_ff jk_ff ( .clk ( ~clk16x ), .J (~dec8clkcount), .K (dec10cycclk), .CLR (~txd), .jkout (irtxd) );endmodule // JK flip flop with async. clear model: 74xx109module jk_ff ( clk , J , K , CLR , jkout ); input clk , J , K , CLR;output jkout ;reg jkout ;always @ ( posedge clk or negedge CLR ) begin if ( ~CLR ) jkout <= 0 ; else case ({ J , K }) 2'b00 : jkout <= 0 ; 2'b01 : jkout <= jkout ; 2'b10 : jkout <= ~jkout ; 2'b11 : jkout <= 1 ; endcaseendendmoduleirDA的传感器原理如图
就是个led.
uart编码是NRZ编码方式.irDA使用的是RZI编码方式.如图.
这两种编码是反转的.
其中irDA是半双工,uart是全双工.在每次传输过程中有10ms的延迟.
这些差别在仿真过程中能很好的发现.
仿真脚本:
`timescale 1ns / 100psmodule irda_uart_tb;reg mclkx16, read, write, irrxd, reset;wire [7:0] data;wire irtxd, rxrdy, txrdy, parity_error, framing_error, overrun;parameter baudrate = 500; // Baudrate specified in ns integer testdata;reg [7:0] data_received, data_written;// Instantiate IrDA/UART top level moduleirda_uart irda_uart_test (.data(data), .mclkx16(mclkx16), .write(write), .read(read), .reset(reset), .parity_error(parity_error), .framing_error(framing_error), .overrun(overrun), .rxrdy(rxrdy), .txrdy(txrdy), .irtxd(irtxd), .irrxd(irrxd)); // Generate 16 times baudrate clock frequency, i.e. Baudrate = mclkx16/16initial begin mclkx16 = 1; forever begin #(baudrate/(16*2)); // Divide baudrate periode by 32 to get half mclkx16 period mclkx16 = ~mclkx16; endend// Reset UART. initial begin #500; reset = 1; #2000; reset = 0;end// Feeding back transmit output to receive inputalways @(irtxd) begin #1; irrxd = ~irtxd;end // Main test programinitial begin write = 1; // de-assert write initially read = 1; // de-assert read initially #100; force irda_uart_tb.rxrdy = 0; #50; // Necessary for proper initialization release irda_uart_tb.rxrdy; #3000; // Wait for reset to go low // Write every possible combinations to the transmitter. for (testdata = 8'h0; testdata <= 8'hff; testdata = testdata + 1) begin write = 0; #100; force data = testdata; #50; write = 1; data_written = testdata; // Latch contents of data bus #20; release data; wait(rxrdy); // Wait for rxrdy/read signal read = 0; #25; data_received = data; // Latch contents of data bus #75; read = 1; end endendmodule进一步
进一步的拓展是获取空调遥控的编码信息.随后继续跟进. |
|