logo资料库

基于FPGA的红外线接收.doc

第1页 / 共6页
第2页 / 共6页
第3页 / 共6页
第4页 / 共6页
第5页 / 共6页
第6页 / 共6页
资料共6页,全文预览结束
module IR(clk,rst_n,IR,led_cs,led_db); clk; rst_n; IR; input input input output [3:0] led_cs; output [7:0] led_db; reg [3:0] led_cs; reg [7:0] led_db; reg [7:0] led1,led2,led3,led4; reg [15:0] irda_data; reg [31:0] get_data; reg [5:0] data_cnt; reg [2:0] reg error_flag; cs,ns; // save irda data,than send to 7 segment led // use for saving 32 bytes irda data // 32 bytes irda data counter // 32 bytes data 期间,数据错误标志 //---------------------------------------------------------------------------- reg irda_reg0; reg irda_reg1; reg irda_reg2; //为了避免亚稳态,避免驱动多个寄存器,这一个不使用。 //这个才可以使用,以下程序中代表 irda 的状态 //为了确定 irda 的边沿,再打一次寄存器,以下程序中代表 irda 的前 一状态 wire irda_neg_pulse; //确定 irda 的下降沿 wire irda_pos_pulse; //确定 irda 的上升沿 wire irda_chang; //确╥rda 的跳变沿 reg[15:0] cnt_scan;//扫描频率计数器 always @ (posedge clk) //在此采用跟随寄存器 if(!rst_n) begin irda_reg0 <= 1'b0; irda_reg1 <= 1'b0; irda_reg2 <= 1'b0; end else begin led_cs <= 4'b0000; //是数码管的位选择处于导通状态 irda_reg0 <= IR; irda_reg1 <= irda_reg0; irda_reg2 <= irda_reg1; end
assign irda_chang = irda_neg_pulse | irda_pos_pulse; assign irda_neg_pulse = irda_reg2 & (~irda_reg1); assign irda_pos_pulse = (~irda_reg2) & irda_reg1; //IR 接收信号的改变,上升或者下降 //IR 接收信号 irda 下降沿 //IR 接收信号 irda 上升沿 //分频 1750 次 reg [10:0] counter; reg [8:0] wire check_9ms; wire check_4ms; wire low; wire high; counter2; //计数分频后的点数 // check leader 9ms time // check leader 4.5ms time // check data="0" time data="1" time // check //---------------------------------------------------------------------------- //分频 1750 计数 always @ (posedge clk) if (!rst_n) counter <= 11'd0; else if (irda_chang) counter <= 11'd0; //irda 电平跳变了,就重新开始计数 else if (counter == 11'd1750) counter <= 11'd0; else counter <= counter + 1'b1; //---------------------------------------------------------------------------- always @ (posedge clk) if (!rst_n) counter2 <= 9'd0; else if (irda_chang) counter2 <= 9'd0; //irda 电平跳变了,就重新开始计点 else if (counter == 11'd1750) counter2 <= counter2 +1'b1; assign check_9ms = ((217 < counter2) & (counter2 < 297)); //257 为了增加稳定性,取一定范围 assign check_4ms = ((88 < counter2) & (counter2 < 168)); assign low = ((6 < counter2) & (counter2 < 26)); assign high = ((38 < counter2) & (counter2 < 58)); //128 // 16 // 48 //---------------------------------------------------------------------------- // generate statemachine 状态机 parameter IDLE = 3'b000, //初始状态 LEADER_9 = 3'b001, //9ms
LEADER_4 DATA_STATE = 3'b100; //传输数据 = 3'b010, //4ms always @ (posedge clk) if (!rst_n) cs <= IDLE; else cs <= ns; //状态位 always @ ( * ) case (cs) IDLE: if (~irda_reg1) ns = LEADER_9; else ns = IDLE; LEADER_9: if (irda_pos_pulse) //leader 9ms check begin if (check_9ms) ns = LEADER_4; else ns = IDLE; end else //完备的 if---else--- ;防止生成 latch ns =LEADER_9; LEADER_4: if (irda_neg_pulse) // leader 4.5ms check begin if (check_4ms) ns = DATA_STATE; else ns = IDLE; end else ns = LEADER_4; DATA_STATE: if ((data_cnt == 6'd32) & irda_reg2 & irda_reg1) ns = IDLE; else if (error_flag) ns = IDLE;
else ns = DATA_STATE; default: ns = IDLE; endcase //状态机中的输出,用时序电路来描述 always @ (posedge clk) if (!rst_n) begin data_cnt <= 6'd0; get_data <= 32'd0; error_flag <= 1'b0; end else if (cs == IDLE) begin data_cnt <= 6'd0; get_data <= 32'd0; error_flag <= 1'b0; end else if (cs == DATA_STATE) begin if (irda_pos_pulse) // low 0.56ms check begin if (!low) //error error_flag <= 1'b1; end else if (irda_neg_pulse) //check 0.56ms/1.68ms data 0/1 begin if (low) get_data[0] <= 1'b0; else if (high) get_data[0] <= 1'b1; else error_flag <= 1'b1; get_data[31:1] <= get_data[30:0]; data_cnt <= data_cnt + 1'b1; end end always @ (posedge clk)
if (!rst_n) irda_data <= 16'd0; else if ((data_cnt ==6'd32) & irda_reg1) //数据反码 begin led1 <= get_data[7:0]; led2 <= get_data[15:8]; //数据码 led3 <= get_data[23:16];//用户码 led4 <= get_data[31:24]; end //把遥控器的按下的键在数码管上面显示出来 always@(led2) begin case(led2) //在数码管上面显示 0 到 9 8'b01101000: //遥控板 0 的码值 led_db=8'b1100_0000; //显示 0 8'b00110000: //遥控板 1 的码值 led_db=8'b1111_1001; //显示 1 8'b00011000: //遥控板 2 的码值 led_db=8'b1010_0100; //显示 2 8'b01111010: //遥控板 3 的码值 led_db=8'b1011_0000; //显示 3 8'b00010000: //遥控板 4 的码值 led_db=8'b1001_1001; //显示 4 8'b00111000: //遥控板 5 的码值 led_db=8'b1001_0010; //显示 5 8'b01011010: //遥控板 6 的码值 led_db=8'b1000_0010; //显示 6 8'b01000010: //遥控板 7 的码值 led_db=8'b1111_1000; //显示 7 8'b01001010: //遥控板 8 的码值 led_db=8'b1000_0000; //显示 8 8'b01010010: //遥控板 9 的码值
led_db=8'b1001_0000; //显示 9 //在没有按下键时,显示 F default: led_db=8'b1000_1110; endcase end endmodule
分享到:
收藏