FPGA|CPLD|ASIC论坛
登录
直播中
Harvestlamb
8年用户
20经验值
擅长:76517
私信
关注
[资料]
【AC620 FPGA试用体验】数字频率计
频率计
本帖最后由 Harvestlamb 于 2017-8-24 00:37 编辑
项目名称:基于
FPGA
的数字频率计
试用计划:基于fpga的数字频率计,能达到2015年全国大学生
电子
设计大赛频
率测量测技术指标(100M),并且达到精准测频,误差符合题目要求。
今天正式起笔,感谢朋友的支持让我得到了试用机会,其次感谢小梅哥能提供FPGA学习平台,首先进入硬件展示篇:
正面
背面
附送模块
整体合影
硬件上的优点外围芯片相比较其他类型产品很用心,比如dac芯片,比我的锆石好很多。同时引脚分配图在背面也能加分。
至于缺点,就是layout没那么精致(因人而异,500元级别还可以)
教学上,我觉得实体教学最好,网络始终不能有那么好的效果,听说小梅哥最近开了实体课。但是现在网络课程中不得不说小梅哥的课程可以说通俗易懂,老少皆宜.
数字频率计的代码部分
.首先我想使用小梅哥板子上的数码管,数码管等视频讲解在购买后都会有的(设计与验证vip版群里有,这个PDF十分适合入门),弄了一下午代码,觉得位数不够,最终索性就不用数码管了,使用了uart发送给
STM32
.
我想说说测频的方法,
直接测频,周期测频,等精度测频。
直接测频
便是在自己定的1s闸门时间内,计数待测信号的上升沿个数。(这一测
开发板
上便是用这一方法。但是把
fre_in写入敏感事件列不是特别好。
)
module fre(reset,clk,fre_in,zhiout);
input clk,reset;
input fre_in;
output [26:0]zhiout;
reg [26:0]i,j,l;
reg k;
always @(posedge clk or negedge reset)
if(!reset)
begin
i<=0;
l<=0;
k<=0;
end
else if(i==49999999)
begin
i<=0;
l<=j;
k<=1;
end
else
begin
i=i+1;
k<=0;
end
always @(posedge fre_in or negedge reset or posedge k)
if(!reset)
j<=0;
else if(k==1)
j<=0;
else
j<=j+1;
assign zhiout=l;
endmodule
周期测频
是在一个被测信号的周期内测系统时钟clk的个数。(这里我把主频clk使用了pll 倍频到了500m,并且最后如果大家采用这种方法,自行处理数据读出的时间,否则数据通过uart发送时会比较乱。)
module fre (
input clk,
input inpluse,
output reg [26:0] cntout,
output reg cntok,
output [26:0] fre
);
reg [31:0] cnt;
reg plusebuf;
always @ (posedge clk)
begin
plusebuf <= inpluse;
end
always @ (posedge clk)
begin
if ((plusebuf == 1'b0)&&(inpluse == 1'b1))
begin
cntout <= cnt;
cnt <= 32'd1;
cntok <= 1'b1;
end
else
begin
cnt <= cnt + 32'd1;
cntok <= 1'b0;
end
end
assign fre = 500000000/cntout;
endmodule
等精度测频
这两张PPT便是等精度测频的核心精髓(此PPT源于武汉大学电赛培训)
至于
uart
发送部分的,先看看RTL视图
module tx_module_start
(
// input port
CLK_50M , RST_N , data_tx ,
// output port
tx_start_flag , data_tx_div
);
//--------------------------------------------------------------------
// 外部端口定义
//--------------------------------------------------------------------
input CLK_50M ; // 时钟输入
input RST_N; //复位的端口,低电平复位
input [26:0] data_tx ;
output reg tx_start_flag ;
output reg [7:0 ] data_tx_div ;
//--------------------------------------------------------------------
// 内部端口定义
//--------------------------------------------------------------------
reg [20:0]
ti
me_seconds; //秒钟低位计数器
reg [20:0] time_seconds_n; //time_seconds的下一个状态
parameter SEC_TIME_1mS = 20'd50_000;
reg [9:0] num_cnt ; //定义10位的加法计数器
reg [9:0] num_cnt_n; //num_cnt的下一个状态
parameter SET_NUM_1000 = 8'd10;
//---------------------------------------------------------------------------
//时序
电路
,用来给time_seconds寄存器赋值
always @ (posedge CLK_50M or negedge RST_N)
begin
if(!RST_N) //判断复位
time_seconds <= 1'b0; //初始化time_seconds值
else
time_seconds <= time_seconds_n; //用来给time_seconds赋值
end
//组合电路,实现1s的定时计数器
always @ (*)
begin
if(time_seconds == SEC_TIME_1mS) //判断1s时间
time_seconds_n = 1'b0; //如果到达1s,定时计数器将会被清零
else
time_seconds_n = time_seconds + 1'b1;
end
//---------------------------------------------------------------------------
//时序电路,用来给num_cnt寄存器赋值
//时序电路,用来给num_cnt寄存器赋值
always @ (posedge CLK_50M or negedge RST_N)
begin
if(!RST_N) //判断复位
num_cnt <= 1'b0; //初始化time_seconds值
else
num_cnt <= num_cnt_n; //用来给time_seconds赋值
end
//组合电路
always @ (*)
begin
if(time_seconds == SEC_TIME_1mS)
num_cnt_n = num_cnt + 1'b1;
else if(num_cnt == SET_NUM_1000)
num_cnt_n = 1'b0;
else
num_cnt_n = num_cnt; //否则,定时计数器将会保持不变
end
//---------------------------------------------------------------------------
//组合电路,用来判断当前数据
always @ (*)
begin
if(num_cnt <= 4'd3)
tx_start_flag = 1'b1 ;
else
tx_start_flag = 1'b0 ;
end
//---------------------------------------------------------------------------
//设置定时器用来设定当前发送数据
reg [2:0] count_send ;
reg [2:0] count_send_n ;
always @ (posedge CLK_50M or negedge RST_N)
begin
if(!RST_N) //判断复位
count_send <= 1'b0;
else
count_send <= count_send_n;
end
//组合电路
always @ (*)
begin
if(num_cnt == SET_NUM_1000)
count_send_n = count_send + 1'b1;
else if (count_send == 3'd7)
count_send_n = 1'b0;
else
count_send_n = count_send; //否则,定时计数器将会保持不变
end
always @ (*)
begin
case (count_send)
3'd0 : data_tx_div = 8'b11001100;//0xcc(stm32校验码,自行设置)
3'd1 : data_tx_div = {1'b0,1'b0,1'b0,1'b0,1'b0,data_tx[26],data_tx[25],data_tx[24]};
3'd2 : data_tx_div = {data_tx[23:16]};
3'd3 : data_tx_div = {data_tx[15:8]};
3'd4 : data_tx_div = {data_tx[7:0]};
3'd5 : data_tx_div = 8'b00001101;
3'd6 : data_tx_div = 8'b00001010;
endcase
end
endmodule
这个代码可以自行修改,发送10位数据都是可以的。由于篇幅限制,完整的代码我会开源的,压缩包的形式自行下载(stm32部分代码后续有需求的话会上传)。
整体效果展示
fre.zip
(2017-8-24 00:36 上传)
5.02 MB, 阅读权限:
10
, 下载次数: 1642
回帖
(3)
那些年儿ing
2017-8-30 14:34:29
感谢分享哦
感谢分享哦
举报
yrzc
2017-10-31 22:58:13
感谢分享
感谢分享
举报
黄裕歌
2018-1-12 17:02:40
感谢主楼慷慨分享
感谢主楼慷慨分享
举报
更多回帖
rotate(-90deg);
回复
相关帖子
频率计
基于vhdl
数字频率计
2020-03-30
1833
基于
FPGA
的
数字频率计
2017-07-26
3145
【
AC620
FPGA
试用
体验】 利用UART传输数据
2017-07-12
3361
【
AC620
FPGA
试用
申请】基于
fpga
的
数字频率计
2017-06-19
4553
基于
fpga
的
数字频率计
msp430单片机显示
2015-09-30
6092
求助基于
FPGA
的
数字频率计
各种资料
2015-08-13
3421
数字频率计
2012-05-20
27536
数字频率计
2012-05-10
4743
数字频率计
的设计与制作
2011-11-19
4050
[求助]
数字频率计
设计
2008-12-12
4414
发帖
登录/注册
20万+
工程师都在用,
免费
PCB检查工具
无需安装、支持浏览器和手机在线查看、实时共享
查看
点击登录
登录更多精彩功能!
首页
论坛版块
小组
免费开发板试用
ebook
直播
搜索
登录
×
20
完善资料,
赚取积分