FPGA-红外

发射器为普通的红外遥控器,接收器为1838T(VCC/GND/OUT);

软件协议:NEC(还有一种常用协议,SONY);

协议介绍:

    引导码:9ms低电平+4.5ms高电平;

    客户代码:C0-C7,C0-C7(反码);

    用户码:D0-D7,D0-D7(反码);

    停止位:低脉冲(560us);

    重复码:若按键时间过长,会在发送完一帧正常数据之后,每隔110ms,发送重复码(9ms电平+2.25ms高电平+停止位);

逻辑电平介绍:

协议中,客户代码和用户代码涉及到逻辑0和逻辑1的问题,其中,逻辑0用560us低电平和560us高电平标识,高电平用560us低电平和1.69ms高电平标识(实际脉宽会存在一些误差)。

码值对应关系

客户代码:每一个遥控器不一样,需要测试;

用户码:数字0到数字9,依次为:

0x16,0x0c,0x18,0x5e,0x08,0x1c,0x5a,0x42,0x52,0x4a

Verilog编程注意事项

逻辑0和逻辑1的持续时间不相同,因此,不可以用等间隔采样的方法实现;

实际信号的上升沿和下降沿都需要一定的时间,设计时需要特别注意,通过检测电平的方式实现时,一定要控制好时钟频率,太快会导致逻辑混乱!!!这一点,及时前仿真、后仿真全都通过,也没有办法验证;

实际测试时发现,很容易引起按键重复的情况,状态机可能会进入意想不到的状态,因此,若不需要处理重复码,需要屏蔽;

具体代码如下:

module IR(clk,rst,ir,led_seg,led_dig,led);
	
	parameter HL  = 100;//高低电平
	parameter CTN = 400;//重发码
	
	input clk;//系统时钟
	input rst;//系统复位
	input ir;//红外输入
	
	output reg [7:0] led_seg;//数码管断码
	output reg [3:0] led_dig;//数码管位码
	output reg led;
	
	reg clk_r;//10us时钟
	reg [7:0] clk_r_cnt;//10us时钟计数器
	reg [7:0] ir_state;//IR状态机
	reg [8:0] delay_cnt;//IR延时计数器
	reg [7:0] dat;//IR用户码
		
	always @ (posedge clk or negedge rst) begin//生成10us时钟
		if(!rst) begin
			clk_r <= 1'b0;
			clk_r_cnt <= 8'd0;
		end
		else begin
			if(clk_r_cnt == 250) begin//10us
				clk_r_cnt <= 8'd0;
				clk_r <= ~clk_r;
			end
			else begin
				clk_r_cnt <= clk_r_cnt + 1;
			end
		end
	end
		
	always @ (posedge clk_r or negedge rst) begin//接收并显示
		if(!rst) begin
			ir_state <= 8'd0;
			led_seg <= 8'd0;
			delay_cnt <= 9'd0;
			dat <= 8'd0;
			led <= 1'b1;
		end
		else begin
			case(ir_state)
				//引导
				8'd0 :	if(ir == 0) ir_state <= ir_state + 1;//9msd
				8'd1 :	if(ir == 1) ir_state <= ir_state + 1;//4.5ms
				//客户代码(前8bit)
				8'd2 :	if(ir == 0) ir_state <= ir_state + 1;//560us
						else delay_cnt <= delay_cnt + 1;
				8'd3 :	if(ir == 1)	begin//剔除重发
										if(delay_cnt < CTN) ir_state <= 8'd0;
										else ir_state <= ir_state + 1;
										delay_cnt <= 9'd0;
									end
						else delay_cnt <= delay_cnt + 1;
				8'd4 :	if(ir == 0) ir_state <= ir_state + 1;//560us
				8'd5 :	if(ir == 1) ir_state <= ir_state + 1;
				8'd6 :	if(ir == 0) ir_state <= ir_state + 1;//560us
				8'd7 :	if(ir == 1) ir_state <= ir_state + 1;
				8'd8 :	if(ir == 0) ir_state <= ir_state + 1;//560us
				8'd9 :	if(ir == 1) ir_state <= ir_state + 1;
				8'd10 :	if(ir == 0) ir_state <= ir_state + 1;//560us
				8'd11 :	if(ir == 1) ir_state <= ir_state + 1;
				8'd12 :	if(ir == 0) ir_state <= ir_state + 1;//560us
				8'd13 :	if(ir == 1) ir_state <= ir_state + 1;
				8'd14 :	if(ir == 0) ir_state <= ir_state + 1;//560us
				8'd15 :	if(ir == 1) ir_state <= ir_state + 1;
				8'd16 :	if(ir == 0) ir_state <= ir_state + 1;//560us
				8'd17 :	if(ir == 1) ir_state <= ir_state + 1;
				//客户代码(后8bit)
				8'd18 :	if(ir == 0) ir_state <= ir_state + 1;//560us
				8'd19 :	if(ir == 1) ir_state <= ir_state + 1;
				8'd20 :	if(ir == 0) ir_state <= ir_state + 1;//560us
				8'd21 :	if(ir == 1) ir_state <= ir_state + 1;
				8'd22 :	if(ir == 0) ir_state <= ir_state + 1;//560us
				8'd23 :	if(ir == 1) ir_state <= ir_state + 1;
				8'd24 :	if(ir == 0) ir_state <= ir_state + 1;//560us
				8'd25 :	if(ir == 1) ir_state <= ir_state + 1;
				8'd26 :	if(ir == 0) ir_state <= ir_state + 1;//560us
				8'd27 :	if(ir == 1) ir_state <= ir_state + 1;
				8'd28 :	if(ir == 0) ir_state <= ir_state + 1;//560us
				8'd29 :	if(ir == 1) ir_state <= ir_state + 1;
				8'd30 :	if(ir == 0) ir_state <= ir_state + 1;//560us
				8'd31 :	if(ir == 1) ir_state <= ir_state + 1;
				8'd32 :	if(ir == 0) ir_state <= ir_state + 1;//560us
				8'd33 :	if(ir == 1) ir_state <= ir_state + 1;
				//用户码(前8bit)
				8'd34 :	if(ir == 0) ir_state <= ir_state + 1;//560us
				8'd35 :	if(ir == 1) ir_state <= ir_state + 1;
				8'd36 :	if(ir == 0) begin
										ir_state <= ir_state + 1;//560us
										dat[0] <= (delay_cnt > HL) ? 1'b1 : 1'b0;
										delay_cnt <= 16'd0;
									end
						else delay_cnt <= delay_cnt + 1;
				8'd37 : if(ir == 1) ir_state <= ir_state + 1;
				8'd38 : if(ir == 0) begin
										ir_state <= ir_state + 1;//560us
										dat[1] <= (delay_cnt > HL) ? 1'b1 : 1'b0;
										delay_cnt <= 16'd0;
									end
						else delay_cnt <= delay_cnt + 1;
				8'd39 : if(ir == 1) ir_state <= ir_state + 1;
				8'd40 : if(ir == 0) begin
										ir_state <= ir_state + 1;//560us
										dat[2] <= (delay_cnt > HL) ? 1'b1 : 1'b0;
										delay_cnt <= 16'd0;
									end
						else delay_cnt <= delay_cnt + 1;
				8'd41 : if(ir == 1) ir_state <= ir_state + 1;
				8'd42 : if(ir == 0) begin
										ir_state <= ir_state + 1;//560us
										dat[3] <= (delay_cnt > HL) ? 1'b1 : 1'b0;
										delay_cnt <= 16'd0;
									end
						else delay_cnt <= delay_cnt + 1;
				8'd43 : if(ir == 1) ir_state <= ir_state + 1;
				8'd44 : if(ir == 0) begin
										ir_state <= ir_state + 1;//560us
										dat[4] <= (delay_cnt > HL) ? 1'b1 : 1'b0;
										delay_cnt <= 16'd0;
									end
						else delay_cnt <= delay_cnt + 1;
				8'd45 : if(ir == 1) ir_state <= ir_state + 1;
				8'd46 : if(ir == 0) begin
										ir_state <= ir_state + 1;//560us
										dat[5] <= (delay_cnt > HL) ? 1'b1 : 1'b0;
										delay_cnt <= 16'd0;
									end
						else delay_cnt <= delay_cnt + 1;
				8'd47 : if(ir == 1) ir_state <= ir_state + 1;
				8'd48 : if(ir == 0) begin
										ir_state <= ir_state + 1;//560us
										dat[6] <= (delay_cnt > HL) ? 1'b1 : 1'b0;
										delay_cnt <= 16'd0;
									end
						else delay_cnt <= delay_cnt + 1;
				8'd49 : if(ir == 1) ir_state <= ir_state + 1;
				//用户码(后8bit)
				8'd50 : if(ir == 0) begin
										ir_state <= ir_state + 1;//560us
										dat[7] <= (delay_cnt > HL) ? 1'b1 : 1'b0;
										delay_cnt <= 16'd0;
									end
						else delay_cnt <= delay_cnt + 1;
				8'd51 : if(ir == 1) ir_state <= ir_state + 1;
				8'd52 : if(ir == 0) ir_state <= ir_state + 1;//560us
				8'd53 : if(ir == 1) ir_state <= ir_state + 1;
				8'd54 : if(ir == 0) ir_state <= ir_state + 1;//560us
				8'd55 : if(ir == 1) ir_state <= ir_state + 1;
				8'd56 : if(ir == 0) ir_state <= ir_state + 1;//560us
				8'd57 : if(ir == 1) ir_state <= ir_state + 1;
				8'd58 : if(ir == 0) ir_state <= ir_state + 1;//560us
				8'd59 : if(ir == 1) ir_state <= ir_state + 1;
				8'd60 : if(ir == 0) ir_state <= ir_state + 1;//560us
				8'd61 : if(ir == 1) ir_state <= ir_state + 1;
				8'd62 : if(ir == 0) ir_state <= ir_state + 1;//560us
				8'd63 : if(ir == 1) ir_state <= ir_state + 1;
				8'd64 : if(ir == 0) ir_state <= ir_state + 1;//560us
				8'd65 : if(ir == 1) ir_state <= ir_state + 1;
				//结束位
				8'd66 : if(ir == 0) ir_state <= ir_state + 1;
				8'd67 : if(ir == 1) begin
										ir_state <= 8'd0;
										delay_cnt <= 9'd0;
										dat <= 8'd0;
										case(dat)
											8'h16 : led_seg <= 8'hc0;
											8'h0c : led_seg <= 8'hf9;
											8'h18 : led_seg <= 8'ha4;
											8'h5e : led_seg <= 8'hb0;
											8'h08 : led_seg <= 8'h99;
											8'h1c : led_seg <= 8'h92;
											8'h5a : led_seg <= 8'h82;
											8'h42 : led_seg <= 8'hf8;
											8'h52 : led_seg <= 8'h80;
											8'h4a : led_seg <= 8'h90;
											default : led_seg <= 8'h8e;
										endcase
									end
				default :	;
			endcase
		end
	end
endmodule

 

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
UDP FPGA接收模块是一个用于接收UDP协议数据的模块。该模块通过解析数据包中的协议类型,识别出UDP协议,并提取出UDP数据。 在FPGA中,接收模块名为eth_receive,它能够识别并处理UDP协议的数据。当接收到UDP数据时,eth_receive模块会产生cmd_flag和cmd_data信号,其中cmd_flag与UDP包中的数据对齐,cmd_data则是UDP的数据总线。 为了测试UDP FPGA接收模块的功能,可以使用网络调试助手向FPGA发送UDP数据包。比如发送1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9这样的18个数据。 FPGA接收到这些UDP数据后,eth_receive模块会提取出这些数据,并将其传递给后续的处理模块进行进一步处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [FPGA实现千兆网口UDP协议收发实例](https://download.csdn.net/download/weixin_40615338/86511024)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [FPGA千兆网系列2-----UDP发送与接收](https://blog.csdn.net/chengfengwenalan/article/details/84501584)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值