FPGA入门红外遥控解码

it2025-03-06  25

FPGA -HT6221红外遥控解码

编码协议中“1”和“0”的编码波形:(红外遥控发射头发出的波形) 接收头与发射头发出的波形反向。

对连按信号的处理

识别9ms的低电平之后,如果之后检测到的高电平的时间小于4.5ms,则为错误信号。 9ms的低电平与4.5ms的高电平引导为引导码。 首先发送地址低八位码,之后发送数据码。

解码状态:数据码中如果有560us的高电平必为0,如果有1960us的高电平必为1,数据码前16位为地址位,后16位为数据位。后16位中前8位是数据码,后8位是数据反码。
信号接收解码模块
module IR_IR( Clk, Rst_n, IR, //接收数据端口 Data_flag,//解码成功标志信号 Data_out,//解码完成的16位数据位 Data_address //解码完成后的16位地址位 ); input Clk; input Rst_n; input IR; output Data_flag; output [15:0] Data_out; output [15:0] Data_address; reg [18:0]count; //计数器 reg con_count; //计数使能信号 reg T9_ms; //识别9ms标志信号 reg T4_5ms; //识别4.5ms标志信号 reg T0_56ms;//识别0.56ms标志信号 reg T1_69ms;//识别1.69ms标志信号 reg IR0,IR1; //异步信号寄存器 reg IR_0,IR_1;//上升下降沿寄存器 wire rise,low; reg [3:0]state; reg [31:0]data_between;//中间数据寄存器 reg timeout;//超出10ms标志信号 reg Get_done; reg [5:0]ir_count; //计数33个ir信号低电平 assign Data_address = data_between[15:0]; assign Data_out = data_between[31:16]; localparam free_condition = 4'b0001, //空闲状态 distinguish_9ms = 4'b0010, //识别9ms低电平状态 distinguish_4_5ms = 4'b0100, //识别4.5ms高电平状态 decode = 4'b1000; //解码状态 always @(posedge Clk or negedge Rst_n) //异步信号的处理 if(!Rst_n) begin IR0 <= 1'b0; IR1 <= 1'b0; end else begin IR0 <= IR; IR1 <= IR0; end always @(posedge Clk or negedge Rst_n) //上升沿下降沿检测 if(!Rst_n) begin IR_0 <= 1'b0; IR_1 <= 1'b0; end else begin IR_0 <= IR1; IR_1 <= IR_0; end assign rise = IR_0 && !IR_1; assign low = !IR_0 && IR_1; always @(posedge Clk or negedge Rst_n) //使能计数 if(!Rst_n) count <= 19'b0; else if(con_count == 1'b1) count <= count + 19'b1; else count <= 19'b0; always @(posedge Clk or negedge Rst_n) //识别9ms时间脉冲 if(!Rst_n) T9_ms <= 1'b0; else if(19'd325000< count && count < 19'd495000) T9_ms <= 1'b1; else T9_ms <= 1'b0; always @(posedge Clk or negedge Rst_n) //识别4.5ms时间脉冲 if(!Rst_n) T4_5ms <= 1'b0; else if(19'd152500 < count && count < 19'd277500) T4_5ms <= 1'b1; else T4_5ms <= 1'b0; always @(posedge Clk or negedge Rst_n) //识别0.56ms时间脉冲 if(!Rst_n) T0_56ms <= 1'b0; else if(19'd20000 < count && count < 19'd35000) T0_56ms <= 1'b1; else T0_56ms <= 1'b0; always @(posedge Clk or negedge Rst_n) //识别1.69ms时间脉冲 if(!Rst_n) T1_69ms <= 1'b0; else if(19'd75000 < count && count < 19'd90000) T1_69ms <= 1'b1; else T1_69ms <= 1'b0; always @(posedge Clk or negedge Rst_n) if(!Rst_n) timeout <= 1'b0; else if(count >= 19'd500000) timeout <= 1'b1; else timeout <= 1'b0; //一段式状态机 always @(posedge Clk or negedge Rst_n) if(!Rst_n) begin state <= free_condition; con_count <= 1'b0; end else if(!timeout) begin case(state) free_condition : //空闲状态 if(low) begin con_count <= 1'b1; state <= distinguish_9ms; end else begin state <= free_condition; con_count <= 1'b0; end distinguish_9ms: //识别9ms脉冲低电平 if(rise) begin if(T9_ms) begin state <= distinguish_4_5ms; con_count <= 1'b0; end else state <= free_condition; end else begin state <= distinguish_9ms; con_count <= 1'b1; end distinguish_4_5ms: //识别4.5ms时间脉冲 if(low) begin if(T4_5ms) begin state <= decode; con_count <= 1'b0; end else state <= free_condition; end else begin state <= distinguish_4_5ms; con_count <= 1'b1; end decode: //识别0和脉冲数据 有1.69ms的高脉冲就是1,有0.56ms的高脉冲就是0 if(rise && !T0_56ms) state <= free_condition; else if(low && (!T1_69ms && !T0_56ms)) state <= free_condition; else if(Get_done) state <= free_condition; else if(rise && T0_56ms) con_count <= 1'b0; else if(low && (T1_69ms || T0_56ms)) con_count <= 1'b0; else con_count <= 1'b1; default : ; endcase end else begin con_count <= 1'b0; state <= free_condition; end always @(posedge Clk or negedge Rst_n) if(!Rst_n) begin Get_done <= 1'b0; ir_count <= 6'b0; data_between <= 32'b0; end else if(state == decode) begin if(rise && (ir_count == 6'd32)) begin Get_done <= 1'b1; ir_count <= 6'b0; end else begin if(low) ir_count <= ir_count + 1'b1; if(low && T0_56ms) data_between[ir_count] <= 1'b0; else if(low && T1_69ms) data_between[ir_count] <= 1'b1; Get_done <= 1'b0; end end assign Data_flag = Get_done; endmodule
仿真模块
`timescale 1ns/1ns `define Clk_period 20 module IR_IR_tb; reg Clk; reg Rst_n; reg IR; wire Data_flag; wire [15:0] Data_out; wire [15:0] Data_address; integer i; IR_IR IR_IR0( .Clk(Clk), .Rst_n(Rst_n), .IR(IR), //接收数据端口 .Data_flag(Data_flag), //解码成功标志信号 .Data_out(Data_out), //解码完成的16位数据位 .Data_address(Data_address) //解码完成后的16位地址位 ); initial Clk =1; always #(`Clk_period/2) Clk =~Clk; initial begin i=0; Rst_n = 0; IR = 0; #(`Clk_period*2); Rst_n = 1; #3000; IR = 1; #(`Clk_period*5); send_data(1,8'hae); #60000000; send_data(1,8'h1f); #60000000; $stop; end task send_data; input [15:0]address; input [7:0] data; begin IR = 0; #9000000; //引导码 IR = 1; #4500000; for(i=0;i<=15;i=i+1) send_byte(address[i]); for(i=0;i<=7;i=i+1) send_byte(data[i]); for(i=0;i<=7;i=i+1) send_byte(~data[i]); IR = 0;#560000; IR = 1; end endtask task send_byte; input one_bite; begin IR = 0; #560000; IR = 1; if(one_bite) #1690000; else #560000; end endtask endmodule

顶层设计

使用tools生成IP核,In-System Sources and Probes。探针为32位(将模块输出数据放入到IP核中,查看数据)。source(来源)为0位。

module IR_look( Clk, Rst_n, IR, //接收数据端口 Data_flag,//解码成功标志信号 Data_out,//解码完成的16位数据位 Data_address //解码完成后的16位地址位 ); input Clk; input Rst_n; input IR; output Data_flag; output [15:0] Data_out; output [15:0] Data_address; IR_IR IR_IR0( .Clk(Clk), .Rst_n(Rst_n), .IR(IR), //接收数据端口 .Data_flag(Data_flag), //解码成功标志信号 .Data_out(Data_out), //解码完成的16位数据位 .Data_address(Data_address) //解码完成后的16位地址位 ); IR_see IR_see0( .probe({Data_out,Data_address}), //探针 .source() ); endmodule

最新回复(0)