- module hs0038_irq(clk_100k, rstn, irq, data, rd_suc)/*synthesis noprune*/;
- input clk_100k; //T=0.01ms
- input rstn;
- input irq;
- output [31:0] data; //16位地址码,16位操作码
- output rd_suc; //成功标志,维持0.01ms的高电平
- parameter T9ms=10'd899;
- parameter T4ms5=10'd449;
- parameter Tms84=7'd83; //0.84ms
- parameter error=8'd19; //0.2ms
- reg [1:0] irq_tmp;
- wire irq_up;
- wire irq_down;
- //捕捉红外信号的上下沿
- always @(negedge clk_100k or negedge rstn)
- begin
- if (!rstn)
- begin
- irq_tmp <= 2'd0;
- end
- else
- begin
- irq_tmp[0] <= irq;
- irq_tmp[1] <= irq_tmp[0];
- end
- end
- assign irq_up = ~irq_tmp[1] & irq_tmp[0]; //上升沿为1
- assign irq_down = irq_tmp[1] & ~irq_tmp[0]; //下降沿为1
- /**********************************************************/
- reg irq_suc;
- reg [31:0] irq_buf;//提取出的32位数据,地址码,其反码,操作码,其反码
- reg [9:0] irq_cnt;
- reg [3:0] step; //状态机,解析红外的处理状态
- reg [7:0] i; //引导码后的数据位计数
- //上下沿的计数
- always @(negedge clk_100k or negedge rstn)
- begin
- if (!rstn)
- begin
- irq_cnt <= 10'd0;
- step <= 4'd0;
- irq_buf <= 32'd0;
- i <= 8'd0;
- irq_suc <= 1'b0;
- end
- else
- begin
- case (step)
- 4'd0 : //开始等待捕捉引导码的上升沿
- begin
- if (irq_up) //第一次上升沿,过滤掉第一个上升沿
- begin
- step <= step + 1'd1;
- irq_cnt <= 10'd0;
- end
- end
- 4'd1 : //引导码上升沿后开始计数
- begin
- irq_cnt <= irq_cnt + 1'd1;
- if (irq_down) //下降沿截止计数
- step <= step + 4'd1;
- end
- 4'd2 : //判断引导码的高电平合法性
- begin
- if (irq_cnt <= (T9ms+error) && irq_cnt >= (T9ms-error))//引导码的9ms高电平
- begin
- step <= step + 4'd1;
- irq_cnt <= 10'd0;
- end
- else
- step <= 4'd0;
- end
- 4'd3 : //引导码的下降沿开始计数至上升沿
- begin
- irq_cnt <= irq_cnt + 1'd1;
- if (irq_up)
- step <= step + 4'd1;
- end
- 4'd4 : //判断引导码的低电平4.5ms
- begin
- if (irq_cnt <= (T4ms5+error) && irq_cnt >= (T4ms5-error))//引导码确认完成
- begin
- step <= step + 4'd1;
- i <= 8'd0;
- end
- else
- step <= 4'd0;
- end
- 4'd5 : //引导码正确后开始提取数据
- begin
- if (irq_down)
- begin
- step <= step + 4'd1;
- irq_cnt <= 10'd0;
- end
- end
- 4'd6 : //提取每个下降沿后0.84ms时的IRQ状态,为高是表示数据0,为低时表示数据1
- begin
- irq_cnt <= irq_cnt + 1'd1;
- if (irq_cnt == Tms84) //捕捉数据部分每个下降沿后0.84ms的值
- begin
- irq_buf[i] <= ~irq;
- i <= i + 8'd1;
- if (i==8'd31) //所有数据提取完
- step <= step + 4'd1;
- else //捕捉下个位的下降沿
- step <= 4'd5;
- end
- end
- 4'd7 : //提取完数据发送成功标志
- begin
- step <= step + 4'd1;
- irq_suc <= 1'b1;
- end
- 4'd8 :
- begin
- irq_suc <= 1'b0;
- step <= 4'd0;
- end
- default : ;
- endcase
- end
- end
- assign rd_suc = irq_suc;
- assign data = irq_buf;
- endmodule
- 有必要说明一下,module后面的注释语句/*synthesis noprune*/是避免综合时候系统优化掉一些变量,导致在仿真里面看不到现象。
- 我自己调试的时候因为红外信号进来的没有取反,所以引导码是9ms低电平,4.5ms高电平,自己没注意导致调试费了一些时间.....需要在上层把红外信号取反之后送进来,这样就能正常工作了,注释很详细,不多解释了...
- 以后我会抽时间把自己调试的小功能程序分享出来,留作备用以及纪念。