测频的方法很多,有人提出低频用测周,高频用等精度测频,还有别的方法,反正对于在整个量程范围内保持一个精度有时候很困难,这方面的文章很多,数不胜数
高精度测频方案设计
频率测量方法的改进
还有一种通过相位的方法:基于FPGA的相检宽带测频系统的设计
昨天早上发现自己测频的问题之后,其实等精度得到的结果并不是很理想,但是自己发现自己不是很冷静,觉得自己很难认真去思考到底是为啥。因为想做占空比和相位的测量,所以自己就把那个问题放下,做一下的周期测量,其实道理很简单:用信号的电平作为gate,标准时钟在闸门打开的时候计数,然后就可以得到想要的结果。
昨天本来就头晕晕然,做的时候其实一个问题到晚上才解决。。。通信,因为你测量的是周期信号,所以不可能再gate关闭后就去采集数据,如果不对数据所存,时间可能不够用。
到晚上的时候才看清楚这个问题,所以就增加了2个start和end信号,这样单片机就可以识别测量的开始和结束,结束后对信号进行所存。。。问题没有解决完,晚上回去的时候结果还是不好,有几个范围是很好哦的,也有其他的地方结果不好。。。。进行中。。。
RTL图:
工程:https://static.assets-stash.eet-china.com/album/old-resources/2009/7/21/2a0045c6-5dbb-4a45-a9f5-e88128a8c525.rar
希望哪位大侠提提意见
7-22号补充
其实只是有一个注意的地方自己脑子里面有点感觉,却总是混混沌沌的,今天又花费了半天的时间才找出问题所在,唉。,就一个测频,测周,怎么搞了这么久啊,如果当初自己在动笔之前把所有的东西想好,怎么会有这么多的问题。。。最不改晕晕乎乎的开始,最不改有问题不去仔细的思考,时间啊。。。。。
下面是测周的代码:
//周期法测频
//7-20
/*
clk_std 标准时钟
clk_sig 输入信号
clr 异步清零计数器
sel 1 ---测量高脉宽 0---测低脉宽
start 测量开始信号
eend 结束信号
cnt 数据输出
//有个问题:
SEL改变的时候将会使gate信号改变,因此将会改变start 和 eend信号,sel改变之后必须清零
*/
module circle(clk_std,clk_sig,clr,sel,start,eend,cnt,en);
input clk_std;
input clk_sig;
input clr;
input sel;
input en;
output start;
output eend;
output [31:0]cnt;
reg eend;
reg start;
reg [31:0]cnt;
reg gate;
reg t1,t2;
//////////////////////////////////////////////
//高低电平选择
always @ (posedge clk_std)
begin
case(sel)
0:
t1 <= sel ^~ clk_sig;
1:
t1 <= sel & clk_sig;
endcase
end
//信号同步
always @ (posedge clk_std)
begin
t2 <= t1;
end
//信号同步,clr异步清零
always @ (posedge clk_std or negedge clr)
begin
if(!clr)
gate <= 1'b0;
else
gate <= t2;
end
////////////////////////////////////////////////
//计数器工作,异步清零,必须保证计数器在开始信号有效后进行计数always @ (posedge clk_std or negedge clr)begin if(!clr ) cnt<= 32'h00000000; else if(gate && start && en)// 问题就出在这里 begin cnt <= cnt + 32'h00000001; end end/////////////////////////测量开始信号(结束信号必须是无效状态)always @ (posedge gate or negedge clr)begin if(!clr) start <= 1'b0; else if(!eend && en) start <= 1'b1;end/////////////////////////测量结束信号(开始信号必须是有效状态)always @ (negedge gate or negedge clr)begin if(!clr) eend <= 1'b0; else if(start && en) eend <= 1'b1;end////////////////////////////
//eend下降沿锁存数据
endmodule
问题有三个:
1:数据锁存问题
因为你测量的数据是周期的信号,所以每次测的数据要锁存或者保持不变,有一点不能使用就是你用eend这个结束信号来对数据所存,综合后建立时间很难满足,这里面就存在很多的隐患。
你可以停止计数器,但是不清零计数器,只到下次采集之前再去清零计数器
2.闸门
被测信号就是闸门,闸门控制着开始和结束信号,在频率很低的情况下,如果用这个信号直接去控制计数器,闸门的边沿可能会很缓慢,经过系统时钟的同步之后边沿就会变的很陡,有利于测量,从另一方方面来说,对于避免的毛刺的干扰也有很大的作用。
还有一个很重要的问题:计数器的工作必须保证在计数器开始信号有效以后,避免在开始信号之前计数器的工作,但是又没有清零(清零是单片机控制的,你也不知道清零的时候信号处于什么状态,如果信号处于被测的电平,没有开始信号的限制,计数器就会开始工作,而且在非被测电平的时候不能够清零,就会积累到下一个被测周期)如下图:
3.开始和结束信号
开始和结束信号是被测信号进经过同步以后给出的,但是我在使用的开始并没有用start去限制eend的改变,也没有用eend去限制start,从示波器看,经常会有在清零后先出现eend高电平,在出现start信号高电平,而且这个问题和被测信号的频率有关,现在也不知道为啥会出现这个问题,后来就使用这种方法来对信号进行限制
//测量开始信号(结束信号必须是无效状态)always @ (posedge gate or negedge clr)begin if(!clr) start <= 1'b0; else if( en) start <= 1'b1;end/////////////////////////测量结束信号(开始信号必须是有效状态)always @ (negedge gate or negedge clr)begin if(!clr) eend <= 1'b0; else if(s en) eend <= 1'b1;end-------------------------------------------------------------------------------------
其实很简单的东西。。。最近脑子很混,还好心中还有个红太阳。。。。现在脑子里面还是迷迷糊糊。我觉得应该有更好的控制方法。。但是。。。
文章评论(0条评论)
登录后参与讨论