这次交作业有些晚了。
以下是红外篇源代码,经过编译和下载到开发板调试:
`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大大说,用户码就是键值对应的编码。这样的话,那就只需要显示它们对应的编码就是了。是我理解错了么?
我要赚赏金
