计算 Basys2 上输入的频率
Counting the Frequency of the input on Basys2
我已经编写了这段代码来获取七段显示器上的输入频率。这只是在早期阶段,这就是为什么我只使用一个数字来显示的原因。我通过信号发生器获取输入并使用 Basys2 板进行输出。我面临的问题是,即使我通过信号发生器应用恒定频率输入,板上显示的频率也波动很大。下面是我的代码:
module frequencyCounter(clk, in, frequency, rst, C, AN, DP);
input clk, in, rst;
output reg [3:0] frequency;
output [6:0] C;
output [3:0] AN;
output DP;
reg [32:0] counter = 0;
reg [3:0] cur_dig_AN;
reg [3:0] current_digit;
reg [6:0] segments;
reg [3:0] frequency_reg;
assign AN = cur_dig_AN;
assign DP = 1;
assign C = ~segments;
always@(posedge clk) begin
if(rst) begin
frequency <= 0;
frequency_reg <= 0;
counter <=0;
cur_dig_AN <=0;
current_digit <=0;
end
else if (counter < 50000000) begin
counter <= counter +1;
if(in)
frequency_reg <= frequency_reg + 1;
end
else begin
counter <= 0;
frequency_reg <= 0;
frequency <= frequency_reg;
if (frequency < 10) begin
cur_dig_AN <= 4'b1110;
current_digit <= frequency;
end
end
end
// the hex-to-7-segment decoder
always @ (current_digit)
case (current_digit)
4'b0000: segments = 7'b111_1110; // 0
4'b0001: segments = 7'b011_0000; // 1
4'b0010: segments = 7'b110_1101; // 2
4'b0011: segments = 7'b111_1001; // 3
4'b0100: segments = 7'b011_0011; // 4
4'b0101: segments = 7'b101_1011; // 5
4'b0110: segments = 7'b101_1111; // 6
4'b0111: segments = 7'b111_0000; // 7
4'b1000: segments = 7'b111_1111; // 8
4'b1001: segments = 7'b111_0011; // 9
4'b1010: segments = 7'b111_0111; // A
4'b1011: segments = 7'b001_1111; // b
4'b1100: segments = 7'b000_1101; // c
4'b1101: segments = 7'b011_1101; // d
4'b1110: segments = 7'b100_1111; // E
4'b1111: segments = 7'b100_0111; // F
default: segments = 7'bxxx_xxxx;
endcase
endmodule
它的工作方式是在一秒钟内计算输入的数量。我使用的是 50Mhz 时钟(因此是 50000000)。一些像 cur_dig_AN 这样的寄存器可能看起来是多余的,但正如我所说,我只是在这个阶段进行测试。此外,如果我的情况有任何问题,是否有任何有效的消除噪音的方法?
我找到了问题的解决方案。我面临的问题是,一旦有一个输入,我就计算它的次数与有 clk 信号的次数一样多,而且那个输入就在那里,而不是只计算一次,因此我不得不引入另一个变量,这样我就不会计算相同的输入两次:
reg in_reg;
if(in && ~in_reg) begin
frequency_reg <= frequency_reg + 1; //increasing freq reg for each input with in one second
in_reg <= 1;
end
else if (~in) //makes sure it is not counting same input twice
in_reg <= 0;
这样我就得到了正确的频率!
我已经编写了这段代码来获取七段显示器上的输入频率。这只是在早期阶段,这就是为什么我只使用一个数字来显示的原因。我通过信号发生器获取输入并使用 Basys2 板进行输出。我面临的问题是,即使我通过信号发生器应用恒定频率输入,板上显示的频率也波动很大。下面是我的代码:
module frequencyCounter(clk, in, frequency, rst, C, AN, DP);
input clk, in, rst;
output reg [3:0] frequency;
output [6:0] C;
output [3:0] AN;
output DP;
reg [32:0] counter = 0;
reg [3:0] cur_dig_AN;
reg [3:0] current_digit;
reg [6:0] segments;
reg [3:0] frequency_reg;
assign AN = cur_dig_AN;
assign DP = 1;
assign C = ~segments;
always@(posedge clk) begin
if(rst) begin
frequency <= 0;
frequency_reg <= 0;
counter <=0;
cur_dig_AN <=0;
current_digit <=0;
end
else if (counter < 50000000) begin
counter <= counter +1;
if(in)
frequency_reg <= frequency_reg + 1;
end
else begin
counter <= 0;
frequency_reg <= 0;
frequency <= frequency_reg;
if (frequency < 10) begin
cur_dig_AN <= 4'b1110;
current_digit <= frequency;
end
end
end
// the hex-to-7-segment decoder
always @ (current_digit)
case (current_digit)
4'b0000: segments = 7'b111_1110; // 0
4'b0001: segments = 7'b011_0000; // 1
4'b0010: segments = 7'b110_1101; // 2
4'b0011: segments = 7'b111_1001; // 3
4'b0100: segments = 7'b011_0011; // 4
4'b0101: segments = 7'b101_1011; // 5
4'b0110: segments = 7'b101_1111; // 6
4'b0111: segments = 7'b111_0000; // 7
4'b1000: segments = 7'b111_1111; // 8
4'b1001: segments = 7'b111_0011; // 9
4'b1010: segments = 7'b111_0111; // A
4'b1011: segments = 7'b001_1111; // b
4'b1100: segments = 7'b000_1101; // c
4'b1101: segments = 7'b011_1101; // d
4'b1110: segments = 7'b100_1111; // E
4'b1111: segments = 7'b100_0111; // F
default: segments = 7'bxxx_xxxx;
endcase
endmodule
它的工作方式是在一秒钟内计算输入的数量。我使用的是 50Mhz 时钟(因此是 50000000)。一些像 cur_dig_AN 这样的寄存器可能看起来是多余的,但正如我所说,我只是在这个阶段进行测试。此外,如果我的情况有任何问题,是否有任何有效的消除噪音的方法?
我找到了问题的解决方案。我面临的问题是,一旦有一个输入,我就计算它的次数与有 clk 信号的次数一样多,而且那个输入就在那里,而不是只计算一次,因此我不得不引入另一个变量,这样我就不会计算相同的输入两次:
reg in_reg;
if(in && ~in_reg) begin
frequency_reg <= frequency_reg + 1; //increasing freq reg for each input with in one second
in_reg <= 1;
end
else if (~in) //makes sure it is not counting same input twice
in_reg <= 0;
这样我就得到了正确的频率!