学习笔记】红外遥控"/>
【学习笔记】红外遥控
红外遥控是一种无线、非接触控制技术,具有抗干扰能力强,信息传输可靠,功耗 低,成本低,易实现等显著优点。
这个工程太久之前写的,没对知识点印象有点模糊就不显丑了。当时也没上板子验证,凑合着看。废话不多说直接给出rtl图粘贴代码
总体框图RTL:
top:
module top_inf_rcv(input wire clk_sys ,input wire rst_n_sys ,input wire inf_in ,output wire led ,output wire ds ,output wire oe ,output wire sh_cp ,output wire st_cp );
parameter point =6'b0 ,sign =1'b0 ,en_seg=1'b0 ;//output inf_rcv
wire [19:0]data ;
wire repeat_en ;inf_rcv inf_rcv_inst(.clk_sys (clk_sys ),.rst_n_sys (rst_n_sys ),.inf_in (inf_in ),.repeat_en (repeat_en ),.data (data )
);led_ctrl led_ctrl_inst(.clk_sys (clk_sys ), .rst_n_sys (rst_n_sys ), .repeat_en (repeat_en ), .led (led )
);seg_595_dynamic(.clk_sys (clk_sys ),.rst_n_sys (rst_n_sys ),.data (data ),.point (point ),.sign (sign ),.en_seg (en_seg ),.ds (ds ),.sh_cp (sh_cp ),.st_cp (st_cp ),.oe (oe ),);endmodule
inf_rcv:
module inf_rcv(input wire clk_sys ,input wire rst_n_sys ,input wire inf_in ,output reg repeat_en ,output reg [19:0]data
);parameter IDLE =5'B00_001 ,TIME_9MS =5'B00_010 ,ARBIT =5'B00_100 ,DATA =5'B01_000 ,REPEAT =5'B10_000 ;parameter CNT_9A =19'D449_900 ,CNT_9B =19'D450_010 ,CNT_45A =19'D224_900 ,CNT_45B =19'D225_010 ,CNT_225A =19'D112_400 ,CNT_225B =19'D112_510 ,CNT_169A =19'D84_400 ,CNT_169B =19'D84_510 ,CNT_560A =19'D27_900 ,CNT_560B =19'D28_010 ;reg [4:0]state ;
reg [18:0]cnt ;
reg flag_9ms,flag_4_5ms,flag_560us,flag_1_69ms,flag_2_25ms;
reg [5:0]cnt_data ;
wire flag_fall,flag_rise ;
reg inf_in_reg1,inf_in_reg2,inf_in_reg3 ;
reg [31:0]data_reg ;always @(posedge clk_sys or negedge rst_n_sys)if (~rst_n_sys)begininf_in_reg1<= 1'b1 ;inf_in_reg2<= 1'b1 ;inf_in_reg3<= 1'b1 ;endelse begininf_in_reg1<= inf_in ;inf_in_reg2<= inf_in_reg1 ;inf_in_reg3<= inf_in_reg2 ;endassign flag_fall=(~inf_in_reg2)&&(inf_in_reg3);assign flag_rise=(~inf_in_reg3)&&(inf_in_reg2);always @(posedge clk_sys or negedge rst_n_sys)if (~rst_n_sys)state<= IDLE ;elsecase(state)IDLE:if(flag_fall==1'b1)state<= TIME_9MS ;elsestate<= IDLE ;TIME_9MS:if (flag_9ms==1'b1 && flag_rise==1'b1)state<= ARBIT ;else if(flag_rise==1'b1 )state<= IDLE ;else state<= state ;ARBIT:if(flag_fall==1'b1 && flag_4_5ms==1'b1)state<= DATA ;else if(flag_fall==1'b1 && flag_2_25ms==1'b1)state<= REPEAT;else if(flag_fall==1'b1)state<= IDLE ;elsestate<= state ;DATA: if(cnt_data==6'd32 && flag_rise==1'b1)state<= IDLE ;else if((flag_fall==1'b1 && ((flag_560us==1'b1)||(flag_1_69ms)))||(flag_rise==1'b1 && flag_560us))state<= DATA ;else if(flag_fall==1'b1 || flag_rise==1'b1)state<= IDLE ;else state<=state ;REPEAT:if(flag_rise==1'b1)state<=IDLE ;elsestate<=state ;default:state<=IDLE ;endcase always@(posedge clk_sys or negedge rst_n_sys)if(~rst_n_sys) cnt<=19'd0 ;else if (state==IDLE || flag_fall==1'b1 || flag_rise==1'b1) cnt<=19'd0 ;else cnt<=cnt+1'b1 ;
//9
always@(posedge clk_sys or negedge rst_n_sys)if(~rst_n_sys)flag_9ms<=1'b0 ;else if(state==TIME_9MS && cnt>=CNT_9A && cnt<CNT_9B)flag_9ms<=1'b1 ;elseflag_9ms<=1'b0 ;//4.5
always@(posedge clk_sys or negedge rst_n_sys)if(~rst_n_sys)flag_4_5ms<=1'b0 ;else if(state==ARBIT && cnt>=CNT_45A && cnt<CNT_45B)flag_4_5ms<=1'b1 ;elseflag_4_5ms<=1'b0 ;//2.25
always@(posedge clk_sys or negedge rst_n_sys)if(~rst_n_sys)flag_2_25ms<=1'b0 ;else if(state==ARBIT && cnt>=CNT_225A && cnt<CNT_225B)flag_2_25ms<=1'b1 ;elseflag_2_25ms<=1'b0 ;
//560
always@(posedge clk_sys or negedge rst_n_sys)if(~rst_n_sys)flag_560us<=1'b0 ;else if(state==DATA && cnt>=CNT_560A && cnt<CNT_560B)flag_560us<=1'b1 ;elseflag_560us<=1'b0 ; //169
always@(posedge clk_sys or negedge rst_n_sys)if(~rst_n_sys)flag_1_69ms<=1'b0 ;else if(state==DATA && cnt>=CNT_169A && cnt<CNT_169B)flag_1_69ms<=1'b1 ;elseflag_1_69ms<=1'b0 ; always@(posedge clk_sys or negedge rst_n_sys)if(~rst_n_sys)cnt_data<=6'd0 ;else if (state==DATA && flag_fall)cnt_data<=cnt_data+1'b1 ;else if (state==DATA )cnt_data<=cnt_data ;elsecnt_data<=6'd0 ;always@(posedge clk_sys or negedge rst_n_sys)if(~rst_n_sys)data_reg<=32'd0 ; else if (flag_fall==1'b1 && state==DATA && cnt_data <=6'd31)if (flag_1_69ms==1'b1)data_reg[cnt_data]<=1'b1 ; else if(flag_560us==1'b1)data_reg[cnt_data]<=1'b0 ;elsedata_reg<=data_reg ;else if(state==IDLE)data_reg<=32'D0 ;else data_reg<=data_reg ;always@(posedge clk_sys or negedge rst_n_sys)if(~rst_n_sys)data<=20'd0 ;else if (data_reg[7:0]==~data_reg[15:8] && data_reg[31:24]==~data_reg[23:16] && cnt_data==6'd32)data<={12'b0,data_reg[23:16]} ;else data<=20'd0 ;always@(posedge clk_sys or negedge rst_n_sys)if(~rst_n_sys)repeat_en<=1'b0 ;else if(state==REPEAT && flag_rise==1'b1)repeat_en<=1'b1 ;elserepeat_en<=1'b0 ;endmodule
seg :
module seg_595_dynamic(input wire clk_sys ,input wire rst_n_sys ,input wire [19:0]data ,input wire [5:0]point ,input wire sign ,input wire en_seg ,output wire ds ,output wire sh_cp ,output wire st_cp ,output wire oe);wire [7:0]seg ;
wire [5:0]sel ;seg_dynamic seg_dynamic1(.clk_sys (clk_sys),.rst_n_sys (rst_n_sys),.data (data),.point (point) ,.sign (sign) ,.en_seg (en_seg),.seg (seg),.sel (sel));hc595_ctrl hc595_ctrl1(.clk_sys (clk_sys),.rst_n_sys (rst_n_sys),.seg (seg),.sel (sel),.ds (ds),.sh_cp (sh_cp),.st_cp (st_cp),.oe (oe));endmodule
module seg_dynamic(input wire clk_sys ,input wire rst_n_sys ,input wire [19:0]data ,input wire [5:0]point ,input wire sign ,input wire en_seg ,output reg [7:0]seg ,output reg [5:0]sel);wire [3:0] uint,ten,hun,tbo,h_hun,t_tbo;
reg [23:0] data_reg ;
reg [18:0] cnt_ms ;
wire flat_ms ;
reg [2:0] cnt_sel ;
reg [3:0] data_disp ;
reg dot_disp ;
reg [5:0] sel_reg ; parameter fu_hao=4'd10 ;//符号
parameter empty =4'd11 ;//空
parameter CNT_MS_MAX=19'd49_999 ;
//parameter CNT_MS_MAX=19'd49 ;
parameter CNT_SEL_MAX=3'd5 ;
bcd_8421 bcd1(.clk_sys (clk_sys ),.rst_n_sys (rst_n_sys),.data (data),.uint (uint),.ten (ten),.hun (hun),.tbo (tbo),.t_tbo (t_tbo),.h_hun (h_hun) );always@(posedge clk_sys or negedge rst_n_sys)if(~rst_n_sys)data_reg<=24'd0 ;else if (h_hun || point[5])data_reg<={h_hun,t_tbo,tbo,hun,ten,uint} ;else if (t_tbo || point[4])beginif (sign==1'b1)data_reg<={fu_hao, t_tbo, tbo, hun, ten, uint} ;elsedata_reg<={empty, t_tbo, tbo, hun, ten, uint} ;endelse if (tbo || point[3])beginif (sign==1'b1)data_reg<={empty, fu_hao,tbo, hun, ten, uint} ;elsedata_reg<={empty, empty, tbo, hun, ten, uint} ;endelse if (hun || point[2])beginif (sign==1'b1)data_reg<={empty, empty, fu_hao, hun, ten,uint} ;elsedata_reg<={empty, empty, empty , hun, ten,uint} ;endelse if (ten || point[1])beginif (sign==1'b1)data_reg<={empty, empty, empty, fu_hao, ten,uint} ;elsedata_reg<={empty, empty, empty , empty, ten,uint} ;endelse if (uint)beginif (sign==1'b1)data_reg<={empty, empty, empty, empty, fu_hao, uint} ;elsedata_reg<={empty, empty, empty , empty, empty, uint} ;endelsedata_reg<= data_reg ;always@(posedge clk_sys or negedge rst_n_sys)if (~rst_n_sys) cnt_ms<=19'd0 ;else if(cnt_ms==CNT_MS_MAX)cnt_ms<=19'd0 ;elsecnt_ms<=cnt_ms+1'b1 ;assign flat_ms=(cnt_ms==CNT_MS_MAX)?1'b1:1'b0 ;always@(posedge clk_sys or negedge rst_n_sys)if (~rst_n_sys) cnt_sel<=3'd0 ;else if (flat_ms==1'b1 && cnt_sel==CNT_SEL_MAX)cnt_sel<=3'd0 ;else if (flat_ms==1'b1)cnt_sel<=cnt_sel+1'b1 ;elsecnt_sel<=cnt_sel ;always@(posedge clk_sys or negedge rst_n_sys)if (~rst_n_sys) sel_reg<=6'd000_000 ;else if(flat_ms==1'b1 && cnt_sel==3'b0)sel_reg<=6'd000_001 ;else if(flat_ms==1'b1)sel_reg<=sel_reg<<1 ;elsesel_reg<=sel_reg ;always@(posedge clk_sys or negedge rst_n_sys)if (~rst_n_sys) data_disp <=empty ;else if (flat_ms==1'b1 && en_seg)case(cnt_sel) 3'd0:data_disp<=data_reg[3:0] ;3'd1:data_disp<=data_reg[7:4] ;3'd2:data_disp<=data_reg[11:8] ;3'd3:data_disp<=data_reg[15:12] ;3'd4:data_disp<=data_reg[19:16] ;3'd5:data_disp<=data_reg[23:20] ;default:data_disp<=empty ;endcasealways@(posedge clk_sys or negedge rst_n_sys)if (~rst_n_sys)dot_disp<=1'b1 ;else if(flat_ms) dot_disp<=~point[cnt_sel] ;elsedot_disp<=dot_disp ;always@(posedge clk_sys or negedge rst_n_sys)if (~rst_n_sys) sel<=6'b0 ;elsesel<=sel_reg;always@(posedge clk_sys or negedge rst_n_sys)if (~rst_n_sys) seg<=8'd0 ;elsecase(data_disp)4'd0: seg <= {dot_disp,7'b100_0000} ;4'd1: seg <= {dot_disp,7'b111_1001} ;4'd2: seg <= {dot_disp,7'b010_0100} ;4'd3: seg <= {dot_disp,7'b011_0000} ;4'd4: seg <= {dot_disp,7'b001_1001} ;4'd5: seg <= {dot_disp,7'b001_0010} ;4'd6: seg <= {dot_disp,7'b000_0010} ;4'd7: seg <= {dot_disp,7'b111_1000} ;4'd8: seg <= {dot_disp,7'b000_0000} ;4'd9: seg <= {dot_disp,7'b001_0000} ;4'd10: seg <= 8'b1011_1111 ;4'd11: seg <= 8'b111_111 ;default: seg <= 8'b1100_0000 ;endcaseendmodule
module hc595_ctrl(input wire clk_sys ,input wire rst_n_sys ,input wire [7:0]seg ,input wire [5:0]sel ,output reg ds ,output reg sh_cp ,output reg st_cp ,output wire oe );wire [13:0]data ;
reg [1:0]cnt ;
reg [3:0]cnt_bit;parameter CNT_MAX=2'D3 ;
parameter CNT_BIT_MAX=4'D13 ;assign data={seg[0],seg[1],seg[2],seg[3],seg[4],seg[5],seg[6],seg[7],sel[5:0]} ;always@(posedge clk_sys or negedge rst_n_sys)if(!rst_n_sys)cnt<=2'd0 ;else if (cnt==CNT_MAX)cnt<=2'd0 ;elsecnt<=cnt+1'b1 ;always@(posedge clk_sys or negedge rst_n_sys)if(!rst_n_sys)cnt_bit<=4'd0 ;else if(cnt_bit==CNT_BIT_MAX && cnt==CNT_MAX)cnt_bit<=4'd0 ;else if(cnt==CNT_MAX)cnt_bit<=cnt_bit+1'b1 ;elsecnt_bit<=cnt_bit ; always@(posedge clk_sys or negedge rst_n_sys)if(!rst_n_sys)ds<=1'b0 ;else if (cnt==2'b0)ds<=data[cnt_bit] ;elseds<=ds ;always@(posedge clk_sys or negedge rst_n_sys)if(!rst_n_sys)sh_cp<=1'd0 ;else if(cnt==2'd2)sh_cp<=1'b1 ;else if(cnt==2'd0)sh_cp<=1'b0 ;elsesh_cp<=sh_cp;always@(posedge clk_sys or negedge rst_n_sys)if(!rst_n_sys)st_cp<=1'd0 ;else if(cnt_bit==4'd0)beginif (cnt==2'd0)st_cp<=1'b1 ;else if(cnt==2'd2)st_cp<=1'b0 ;endelsest_cp<=st_cp;assign oe=1'b0 ;endmodule
module bcd_8421(input wire clk_sys ,input wire rst_n_sys ,input wire [19:0]data ,output reg [3:0]uint ,output reg [3:0]ten ,output reg [3:0]hun ,output reg [3:0]tbo ,output reg [3:0]t_tbo ,output reg [3:0]h_hun );reg shift_flat ;
reg [4:0]cnt_shift ;
reg [43:0]data_shift ;parameter CNT_SHIFT_MAX =5'D21 ;always@(posedge clk_sys or negedge rst_n_sys)if(~rst_n_sys)shift_flat <=1'b0 ;else shift_flat <=~shift_flat ;always@(posedge clk_sys or negedge rst_n_sys)if(~rst_n_sys)cnt_shift <=5'b0 ;else if(shift_flat==1'b1 && cnt_shift==CNT_SHIFT_MAX)cnt_shift <=5'd0 ;else if(shift_flat==1'b1)cnt_shift <=cnt_shift+1'b1 ;else cnt_shift <=cnt_shift ;always@(posedge clk_sys or negedge rst_n_sys)if(~rst_n_sys)data_shift<=44'd0 ;else if(cnt_shift==5'd0)data_shift<={24'd0,data[19:0]} ;else if(cnt_shift>0)beginif (shift_flat==1'b1 && cnt_shift<=5'd20)data_shift<=data_shift<<1 ;else if (shift_flat==1'b0 && cnt_shift<=5'd20)begindata_shift[23:20]<=(data_shift[23:20]>4'd4)?4'd3+data_shift[23:20]:data_shift[23:20];data_shift[27:24]<=(data_shift[27:24]>4'd4)?4'd3+data_shift[27:24]:data_shift[27:24];data_shift[31:28]<=(data_shift[31:28]>4'd4)?4'd3+data_shift[31:28]:data_shift[31:28];data_shift[35:32]<=(data_shift[35:32]>4'd4)?4'd3+data_shift[35:32]:data_shift[35:32];data_shift[39:36]<=(data_shift[39:36]>4'd4)?4'd3+data_shift[39:36]:data_shift[39:36];data_shift[43:40]<=(data_shift[43:40]>4'd4)?4'd3+data_shift[43:40]:data_shift[43:40];endelse data_shift<=data_shift ;endelse data_shift<=data_shift ;
always@(posedge clk_sys or negedge rst_n_sys)if(~rst_n_sys)beginuint<=4'd0 ;ten<=4'd0 ;hun<=4'd0 ;tbo<=4'd0 ;h_hun<=4'd0 ;t_tbo<=4'd0 ;endelse if (shift_flat==1'b0 && cnt_shift==5'd21)beginuint <= data_shift[23:20] ;ten <= data_shift[27:24] ;hun <= data_shift[31:28] ;tbo <= data_shift[35:32] ;h_hun <= data_shift[39:36] ;t_tbo <= data_shift[43:40] ;end elsebeginuint <=uint ;ten <=ten ;hun <=hun ;tbo <=tbo ;h_hun <=h_hun ;t_tbo <=t_tbo ;end//过于复杂
//always@(posedge clk_sys or negedge rst_n_sys)
// if(~rst_n_sys)
// uint<=4'd0 ;
// else if (shift_flat==1'b0 && cnt_shift==5'd21)
// uint<=data_shift[23:20] ;
// else
// uint<=uint ;
//
//always@(posedge clk_sys or negedge rst_n_sys)
// if(~rst_n_sys)
// ten<=4'd0 ;
// else if (shift_flat==1'b0 && cnt_shift==5'd21)
// ten<=data_shift[27:24] ;
// else
// ten<=ten ;
//
//always@(posedge clk_sys or negedge rst_n_sys)
// if(~rst_n_sys)
// hun<=4'd0 ;
// else if (shift_flat==1'b0 && cnt_shift==5'd21)
// hun<=data_shift[31:28] ;
// else
// hun<=hun ;
//
//always@(posedge clk_sys or negedge rst_n_sys)
// if(~rst_n_sys)
// tbo<=4'd0 ;
// else if (shift_flat==1'b0 && cnt_shift==5'd21)
// tbo<=data_shift[35:32] ;
// else
// tbo<=tbo ;
//
//always@(posedge clk_sys or negedge rst_n_sys)
// if(~rst_n_sys)
// h_hun<=4'd0 ;
// else if (shift_flat==1'b0 && cnt_shift==5'd21)
// h_hun<=data_shift[39:36] ;
// else
// h_hun<=h_hun ;
//
//always@(posedge clk_sys or negedge rst_n_sys)
// if(~rst_n_sys)
// t_tbo<=4'd0 ;
// else if (shift_flat==1'b0 && cnt_shift==5'd21)
// t_tbo<=data_shift[43:40] ;
// else
// t_tbo<=t_tbo ;
endmodule
led:
module led_ctrl(input wire clk_sys , input wire rst_n_sys , input wire repeat_en , output reg led
);parameter CNT_MAX = 2500_000;wire repeat_en_rise ; reg repeat_en_d1 ; reg repeat_en_d2 ; reg cnt_en ; reg [21:0] cnt ; assign repeat_en_rise = repeat_en_d1 & ~repeat_en_d2;always@(posedge clk_sys or negedge rst_n_sys)if(rst_n_sys == 1'b0)beginrepeat_en_d1 <= 1'b0 ;repeat_en_d2 <= 1'b0 ;endelse beginrepeat_en_d1 <= repeat_en ;repeat_en_d2 <= repeat_en_d1 ;endalways@(posedge clk_sys or negedge rst_n_sys)if(rst_n_sys == 1'b0)cnt_en <= 1'b0 ;else if(cnt == CNT_MAX - 1)cnt_en <= 1'b0 ;else if(repeat_en_rise == 1'b1)cnt_en <= 1'b1 ;always@(posedge clk_sys or negedge rst_n_sys)if(rst_n_sys == 1'b0)cnt <= 22'b0;else if(cnt_en == 1'b1)cnt <= cnt + 1;elsecnt <= 22'b0;always@(posedge clk_sys or negedge rst_n_sys)if(rst_n_sys == 1'b0)led <= 1'b1;else if(cnt > 0)led <= 1'b0;elseled <= 1'b1;
endmodule
总共七段代码
更多推荐
【学习笔记】红外遥控
发布评论