本次主要实现红外遥控解码模块的实现,红外模块发送端采用的是HT6221的编码芯片,而在接收端由于红外对管,生成的正好是与发送端电平相反的信号。要实现解码模块程序编写,需先知道协议的过程以及编码的格式,还有模块的输入输出。
1. HT6221介绍
是一款基于红外遥控协议(NEC协议)的遥控编码芯片。一共24个引脚,其PIN定义如下:
When one of the keys (32 or 64 keys) is triggered for over 36ms, the oscillator is enabled and the chip is activated. If the key is pressed and held for 108ms or less, the 108ms transmission codes are enabled and comprised of a header code (9ms), an off code (4.5ms), low byte address codes (9ms~18ms), high byte address codes (9ms~18ms), 8-bit data codes (9ms~18ms), and the inverse codes of the 8-bit data codes (18ms~9ms). After the pressed key is held for 108ms, if the key is still held down, the transmission codes turn out to be a composition of header (9ms) and off codes (2.5ms) only.
To avoid mistakes made by keyboard scanning or simultaneous two-key inputs (except for the three double-key active functions (K21+K22, K21+K23, and K21+K24), the HT6221/HT6222 are facilitated with 36ms starting time. The HT6221/HT6222 also provide three double-key active functions (K21+K22, K21+K23, and K21+K24) for tape deck recording operations.
The double-key operation rules are shown in timing 4 and timing 6. Transmission Codes The transmission codes of the HT6221/HT6222 consist of a 9ms header code, a 4.5ms off code, 16-bit address codes (18ms~36ms), 9ms~18ms 8-bit data codes, and the inverse code of the 8-bit data codes. The following is an illustration of the transmission codes


如上,NEC协议主要时发送9ms的高电平,然后4.5ms的低电平,然后是地址和数据。其中地址和数据的1,0采用PPM编码,即用不同时长的高低电平表示二进制1,0。
2. 红外解码模块设计
模块接口如下,因为实际接收时,接收头接收到的信号后输出的波形刚好与编码产生的波形相反。因此需要decode模块将这个相反的时序识别出来。

1)计数模块
这里需要产生9ms,4.5ms,0.56ms,1.69ms这四个时间点判断,但由于不同硬件电路,晶振,不同实际场景下这个时间可能不会这么精确,因此需要以包含这个时间前后一段范围的时间段进行判断。
2)代码
整个NEC协议,在识别过程中主要是根据上面的时间点判断协议目前在那个状态,如果在数据传输状态则根据高低电平时间判断传输的是1还是0,然后将数据转换后输出。NEC协议只有4个状态,但是在数据传输这个状态下输出和判断信息比较复杂,所以用三段式的状态机实现。
module decoder_top( input clk,rst_n, input iIR, output wire [15:0]irData, output wire [15:0]irAddr, output reg end_flag); reg [19:0]tim_cnt; reg tim_clear; reg [3:0]main_state; parameter IDLE =4'b0000, ST_high=4'b0001, ST_low =4'b0010, ST_data=4'b0100; reg data_done; reg [6:0] data_cnt; reg [31:0]data_r; assign irAddr=data_r[15:0]; assign irData=data_r[23:16]; /* parameter time_9ms=20'd; parameter time_4_5ms=20'd; parameter time_0_56ms=20'd56000; parameter time_1_68ms=20'd; */ reg [1:0]iIR_r; wire iIR_pos_flag,iIR_neg_flag; assign iIR_pos_flag = (~iIR_r[1] & iIR_r[0])?1'b1:1'b0; assign iIR_neg_flag = (iIR_r[1] & (~iIR_r[0]))?1'b1:1'b0; always@(posedge clk or negedge rst_n)begin if(~rst_n) iIR_r<=0; else begin iIR_r[0]<=iIR; iIR_r[1]<=iIR_r[0]; end end always@(posedge clk or negedge rst_n)begin if(~rst_n) tim_cnt<=0; else if(tim_clear) tim_cnt<=0; else tim_cnt<=tim_cnt+1'b1; end always @(posedge clk or negedge rst_n) begin if(~rst_n)begin main_state<=IDLE; tim_clear<=1; end else if(tim_cnt<20'd) begin case (main_state) IDLE:begin if(iIR_neg_flag) begin main_state<=ST_high; tim_clear<=1; end else begin main_state<=IDLE; tim_clear<=0; end end ST_high:begin if (iIR_pos_flag)begin if (tim_cnt>20'd && tim_cnt<20'd) begin main_state<=ST_low; tim_clear<=1; end else begin main_state<=IDLE; tim_clear<=0; end end else begin main_state<=ST_high; tim_clear<=0; end end ST_low:begin if(iIR_neg_flag)begin if(tim_cnt>20'd &&tim_cnt<20'd)begin main_state<=ST_data; tim_clear<=1; end else begin main_state<=IDLE; tim_clear<=0; end end else begin main_state<=ST_low; tim_clear<=0; end end ST_data:begin if(data_done) begin main_state<=IDLE; tim_clear<=0; end else if(iIR_pos_flag)begin if(tim_cnt>20'd20000 && tim_cnt<20'd35000)begin tim_clear<=1; end else begin main_state<=IDLE; tim_clear<=0; end end else if(iIR_neg_flag)begin if((tim_cnt>20'd20000 && tim_cnt<20'd35000) || (tim_cnt>20'd75000 && tim_cnt<20'd90000))begin tim_clear<=1; end else begin main_state<=IDLE; tim_clear<=0; end end else begin main_state<=ST_data; tim_clear<=0; end end endcase end end always @(posedge clk or negedge rst_n)begin if(~rst_n)begin data_done<=0; data_cnt<=0; data_r<=0; end_flag<=0; end else if (main_state==IDLE)begin data_done<=0; end_flag<=0; data_r<=0; end else if (main_state==ST_data) begin if(data_cnt==7'd32) begin data_cnt<=0; data_done<=1; end_flag<=1; end else if(iIR_neg_flag )begin if(tim_cnt>20'd20000 && tim_cnt<20'd35000) data_r[data_cnt]<=0; if(tim_cnt>20'd75000 && tim_cnt<20'd90000) data_r[data_cnt]<=1; data_cnt<=data_cnt+1'b1; end end end endmodule
讯享网


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/116877.html