FPGA入门红外遥控解码

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 

在这里插入图片描述

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值