这次交作业有些晚了。
以下是红外篇源代码,经过编译和下载到开发板调试:
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: Charles Wang // // Create Date: 06/21/2014 // Design Name: hongwai // Module Name: hongwai // Project Name: hongwai // Target Devices: EP4CE6E22C8 // Tool versions: Quartus II 13.1 // Description: 数码管显示接收到的红外遥控器的数字按键值 // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // 以下代码以51FPGA的课程源代码改写 ////////////////////////////////////////////////////////////////////////////////// module hongwai(sys_clk,sys_rstn,ir,sm_seg,sm_bit); // input sys_clk ; input sys_rstn ; input ir ; output [7:0] sm_seg ; output [7:0] sm_bit ; //寄存器定义 reg [7:0] sm_seg ; reg [9:0] delay_cnt_hong ;//红外模块分频计数寄存器 reg [15:0] delay_cnt_sel ;//LED 数码管位选分频计数寄存器 reg div_clk ; reg ir_reg0 ; reg ir_reg1 ; reg [8:0] ir_cnt ; reg [4:0] rec_cnt ; reg [7:0] key_code ; reg [31:0] data ; reg [7:0] sm_bit ; reg [1:0] sm_bit_cnt ;//由于需要进行动态显示用户码和数据,把LED 数码管添加到3个 reg [7:0] user_code_seg_h;//用户码高8位寄存器 reg [7:0] user_code_seg_l;//用户码低8位寄存器 reg [7:0] key_code_seg ;//数据码LED显示寄存器 wire ir_posedge ; wire ir_negedge ; wire t_9ms ; wire t_4ms ; wire low ; wire high ; assign t_9ms=((9'd217 < ir_cnt)& (ir_cnt < 9'd297)) ;//257 assign t_4ms=((9'd88 < ir_cnt) & (ir_cnt < 9'd168)) ;//128 assign low=((9'd22 < ir_cnt) & (ir_cnt < 9'd42)) ;// 32 assign high=((9'd54 < ir_cnt) & (ir_cnt < 9'd74)) ;// 63 assign ir_posedge=(~ir_reg1)&ir_reg0; assign ir_negedge=ir_reg1&(~ir_reg0); //状态机定义 reg [7:0] ir_state ; parameter idle =8'h01 , waite_posedge =8'h02 , check_9ms =8'h04 , waite_negedge =8'h08 , check_4ms =8'h10 , rec_code =8'h20 ; //红外模块时钟分频 always@(posedge sys_clk or negedge sys_rstn) begin if(!sys_rstn) begin delay_cnt_hong<=10'd0; div_clk<=1'b0; end else if(delay_cnt_hong==11'd874) begin delay_cnt_hong<=10'd0 ; div_clk<=~div_clk; end else begin delay_cnt_hong<=delay_cnt_hong+1'b1 ; div_clk<=div_clk; end end //LED 数码管扫描模块时钟分频 always@(posedge sys_clk or negedge sys_rstn) begin if(!sys_rstn) delay_cnt_sel <= 16'h0; else if(delay_cnt_sel == 16'd49999) delay_cnt_sel <= 16'h0; else delay_cnt_sel <= delay_cnt_sel + 1'b1; end //捕捉红外信号的上下沿 always@(posedge div_clk or negedge sys_rstn) begin if(!sys_rstn) begin ir_reg0<=1'b0; ir_reg1<=1'b0; end else begin ir_reg0<=ir; ir_reg1<=ir_reg0; end end always@(posedge div_clk or negedge sys_rstn) begin if(!sys_rstn) begin ir_cnt<=9'd0; rec_cnt<=5'd0; key_code<=8'h0; data<=32'h0; ir_state<=idle; end else begin case(ir_state) idle: begin if(~ir_reg0) begin ir_state<=waite_posedge; ir_cnt<=9'd0; rec_cnt<=5'd0; end else ir_state<=idle; end waite_posedge: begin ir_cnt<=ir_cnt+1'b1; if(ir_posedge) ir_state<=check_9ms; else ir_state<=waite_posedge; end check_9ms: begin if(t_9ms) begin ir_state<=waite_negedge; ir_cnt<=9'd0; end else ir_state<=idle; end waite_negedge: begin ir_cnt<=ir_cnt+1'b1; if(ir_negedge) ir_state<=check_4ms; else ir_state<=waite_negedge; end check_4ms: begin if(t_4ms) begin ir_state<=rec_code; ir_cnt<=16'd0; end else ir_state<=idle; end rec_code: begin ir_cnt<=ir_cnt+1'b1; if(ir_negedge) begin rec_cnt<=rec_cnt+1'b1; ir_cnt<=9'd0; if(low) data[rec_cnt] <= 1'b0; else if(high) data[rec_cnt] <= 1'b1; else ir_state<=idle; if(rec_cnt==5'd31) begin ir_state <=idle; key_code <=data[23:16]; end end else ir_state<=rec_code; end default: ir_state<=idle; endcase end end //LED 数码管扫描模块 always@(posedge sys_clk or negedge sys_rstn) begin if(!sys_rstn) sm_bit_cnt <= 2'b00; else if(sm_bit_cnt == 2'b10 && delay_cnt_sel == 16'd49999) sm_bit_cnt <= 2'b00; else if(delay_cnt_sel == 16'd49999) sm_bit_cnt <= sm_bit_cnt + 1'b1; else sm_bit_cnt <= sm_bit_cnt; end always@(sm_bit_cnt) begin case(sm_bit_cnt) 2'b00 : sm_bit <= 8'b1111_1110; 2'b01 : sm_bit <= 8'b1111_1101; 2'b10 : sm_bit <= 8'b1111_1011; default: sm_bit <= 8'b1111_1111; endcase end always@(sm_bit) begin case(sm_bit) 8'b1111_1110: sm_seg = key_code_seg; 8'b1111_1101: sm_seg = user_code_seg_l; 8'b1111_1011: sm_seg = user_code_seg_h; default : sm_seg = 8'hff; endcase end //用户码显示模块 always@(key_code) begin case(key_code) 8'h16: begin user_code_seg_h <= 8'hf9;//"1" user_code_seg_l <= 8'h82;//"6" end 8'h0c: begin user_code_seg_h <= 8'hc0;//"0" user_code_seg_l <= 8'hc6;//"c" end 8'h18: begin user_code_seg_h <= 8'hf9;//"1" user_code_seg_l <= 8'h80;//"8" end 8'h5e: begin user_code_seg_h <= 8'h92;//"5" user_code_seg_l <= 8'h86;//"e" end 8'h08: begin user_code_seg_h <= 8'hc0;//"0" user_code_seg_l <= 8'h80;//"8" end 8'h1c: begin user_code_seg_h <= 8'hf9;//"1" user_code_seg_l <= 8'hc6;//"c" end 8'h5a: begin user_code_seg_h <= 8'h92;//"5" user_code_seg_l <= 8'h88;//"a" end 8'h42: begin user_code_seg_h <= 8'h99;//"4" user_code_seg_l <= 8'ha4;//"2" end 8'h52: begin user_code_seg_h <= 8'h92;//"5" user_code_seg_l <= 8'ha4;//"2" end 8'h4a: begin user_code_seg_h <= 8'h99;//"4" user_code_seg_l <= 8'h88;//"a" end default: begin user_code_seg_h <= 8'hff; user_code_seg_l <= 8'hff;//默认不显示用户码 end endcase end //键值显示模块 always @(key_code) begin case (key_code) 8'h16 : key_code_seg = 8'hc0; // "0" 8'h0c : key_code_seg = 8'hf9; // "1" 8'h18 : key_code_seg = 8'ha4; // "2" 8'h5e : key_code_seg = 8'hb0; // "3" 8'h08 : key_code_seg = 8'h99; // "4" 8'h1c : key_code_seg = 8'h92; // "5" 8'h5a : key_code_seg = 8'h82; // "6" 8'h42 : key_code_seg = 8'hf8; // "7" 8'h52 : key_code_seg = 8'h80; // "8" 8'h4a : key_code_seg = 8'h90; // "9" default: key_code_seg = 8'hc0; // "0" endcase end endmodule
另外,有个问题就是,看到superdian童鞋的用户码是data 的31到24位的数据,不懂为什么?
记得当时听课的时候,51FPGA大大说,用户码就是键值对应的编码。这样的话,那就只需要显示它们对应的编码就是了。是我理解错了么?